Search code examples
javaloggingtomcat8java.util.logging

How to add a unique tag to each log in logging.properties


My standard configuration of Tomcat 8.5 splits the logs into

  • Catalina,
  • manager,
  • localhost ,
  • host-manager

My task is to add to each file unique tags: CatalinaTag, mngTag, localTag, hostMngTag

I tried to find a solution on the internet but without any success.

My propse of logging.properties look like this:

handlers = 1catalina.mypackage.CatalinaConsoleHandler, 2localhost.mypackage.LocalhostConsoleHandler, 3manager.mypackage.ManagerConsoleHandler, 4host-manager.mypackage.LocalhostConsoleHandler, java.util.logging.ConsoleHandler
.handlers = 1catalina.mypackage.CatalinaConsoleHandler, java.util.logging.ConsoleHandler

1catalina.mypackage.CatalinaConsoleHandler.directory = /.../logs
1catalina.mypackage.CatalinaConsoleHandler.prefix = catalina.
1catalina.mypackage.CatalinaConsoleHandler.formatter = mypackage.CatalinaFormatter
mypackage.CatalinaFormatter.format = [CatalinaTag %1$tF %1$tT] [%4$-7s] %5$s %n

2localhost.mypackage.LocalhostConsoleHandler.directory = /.../logs
2localhost.mypackage.LocalhostConsoleHandler.prefix = localhost.
2localhost.mypackage.LocalhostConsoleHandler.formatter =mypackage.LocalhostFormatter
mypackage.LocalhostFormatter.format = [localhostTag %1$tF %1$tT] [%4$-7s] %5$s %n

3manager.mypackage.ManagerConsoleHandler.directory = /.../logs
3manager.mypackage.ManagerConsoleHandler.prefix = manager.
3manager.mypackage.ManagerConsoleHandler.formatter =mypackage.ManagerFormatter
mypackage.ManagerFormatter.format = [manager %1$tF %1$tT] [%4$-7s] %5$s %n

4host-manager.mypackage.LocalhostConsoleHandler.directory = /.../logs
4host-manager.mypackage.LocalhostConsoleHandler.prefix = host-manager.
4host-manager.mypackage.LocalhostConsoleHandler.formatter =mypackage.HostManagerFormatter
mypackage.HostManagerFormatter.format = [manager %1$tF %1$tT] [%4$-7s] %5$s %n

############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.mypackage.LocalhostConsoleHandler

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.mypackage.ManagerConsoleHandler

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.mypackage.LocalhostConsoleHandler

Here is an example of *ConsoleHandler

package mypackage;

import java.util.logging.ConsoleHandler;

public class CatalinaConsoleHandler extends ConsoleHandler {
}

Here an example of *Formatter

package mypackage;

import java.util.logging.SimpleFormatter;

public class CatalinaFormatter extends SimpleFormatter {
}

But so far I am not able to do it. Do you have any idea why?

Thank you for any help!


Solution

  • If you were using the original java.util.logging, your approach of subclassing ConsoleHandler (or rather FileHandler) and SimpleFormatter multiple times would be the correct one: JUL allows only one instance of every Handler and Formatter class. This approach will work, but you need to add mypackage.CatalinaConsoleHandler and company to the system classloader (cf. Tomcat classloaders).

    However there is a much easier approach: Tomcat has its own extensions to JUL (cf. documentation), which allow you to:

    • add a prefix to each handler name and create multiple handlers of the same class. The prefix must start with a digit (e.g. 1catalina.). Prefixed properties apply only to the specific handler, while non-prefixed properties apply to all handlers.
    • use property placeholders ${...} which will be replaced with the appropriate Java system property. There are also three special properties (classloader.serverName, classloader.hostName and classloader.webappName) that resolve the name of the engine, host and context respectively.

    Therefore you can use:

    # List of all handler names:
    handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler
    # Handlers attached to the root logger:
    .handlers = 1catalina.org.apache.juli.AsyncFileHandler
    
    # These properties apply to all handlers
    org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
    org.apache.juli.AsyncFileHandler.formatter = java.util.logging.SimpleFormatter
    
    # These properties apply only to `1catalina.org.apache.juli.AsyncFileHandler`
    1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina.
    1catalina.java.util.logging.SimpleFormatter.format = [CatalinaTag %1$tF %1$tT] [%4$-7s] %5$s %n
    
    # These properties apply only to `2localhost.org.apache.juli.AsyncFileHandler`
    2localhost.org.apache.juli.AsyncFileHandler.prefix = localhost.
    2localhost.java.util.logging.SimpleFormatter.format = [LocalhostTag %1$tF %1$tT] [%4$-7s] %5$s %n