Log4j Behaviour in Tomcat and WebSphere

Logging is the interface between developers and system admin. Developers need to know how their logging code behave in a server envrionment. Admins need to know how to configure and turn on/off logging. This series inspects how two most common logging methods, Java Util Logging and Log4j, behave in Tomcat and WebSphere.

Contrary to Java Util Logging, log4j is not part of the JDK. You need to include log4j.jar in your classpath in order to use log4j logging. However, also because it is not part of the JDK, WebSphere and Tomcat don't use it for its own internal logging and it enables log4j's behaviour to be consistent across different platforms. This article inspects how log4j works.

1. Components of Log4j

  • The log4j jar file

For web applications, you need to include a version of log4j jar, for example, log4j-1.2.12.jar, under WEB-INF\lib.
  • Java Code 

    • Create Loggers
In the following log4j sample code, two loggers are created: the mainLogger com.appinf and a perfSubLogger com.appinf.perf.  This is to help us understand how log4j organizes loggers in a tree structure. 

It is almost identical to java util logging. The only difference is the type of Logger is
org.apache.log4j.Logger instead of java.util.logging.Logger;
    static Logger mainLogger = null;
    static Logger perfSubLogger = null;
    static {
        mainLogger = Logger.getLogger("com.appinf4j");
        perfSubLogger = Logger.getLogger("com.appinf4j.perf");
    }
    • Logging
Again, the code is almost identical to java util logging.
        final long startTime = System.currentTimeMillis();
        perfSubLogger.info("JavaUtilLoggingSETest main Enter");
        
        mainLogger.info("JavaUtilLoggingSETest main Processing ... ");

        final long endTime = System.currentTimeMillis();
        perfSubLogger.info("JavaUtilLoggingSETest main Exit Total time : " + (endTime - startTime) + " ms.");
  • log4j.properties

A log4j.properties file has to be put in the classpath, usually directly under WEB-INF/classes. If not, you will see an error that states "No appenders could be found for logger (com.appinf4j.perf)" and "Please initialize the log4j system properly".
.

You can define a default logger (rootLogger) for the web application.

log4j.rootLogger=DEBUG,console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy.MM.dd-HH.mm.ss} [console] %-5p %c : %m%n

You can also configure a named logger (log4j.logger.com.appinf4j) to log to its own log file.

log4j.logger.com.appinf4j=DEBUG,appinfLog
log4j.appender.appinfLog=org.apache.log4j.FileAppender
log4j.appender.appinfLog.layout=org.apache.log4j.PatternLayout
log4j.appender.appinfLog.Threshold=DEBUG
log4j.appender.appinfLog.layout.ConversionPattern=%d{yyyy.MM.dd-HH.mm.ss} [appinfLog] %-5p %c  : %m%n
log4j.appender.appinfLog.File=logs/appinf.log


There are several things to note here.
  • If you are NOT using absolute path, it will use the profile home directory profiles\was70profile1 in WebSphere, or the directory where you run startup scripts for Tomcat. 
  • A named logger (log4j.logger.com.appinf4j) will still log to its parent logger (the root logger in the above case, which in turn logs to the console). To disable it, you have to call  setAdditivity to false.

    mainLogger.setAdditivity(false);

2. Log4j in Tomcat

Usually, log4j jar and log4j.properties are packaged within the web app and log4j's behaviour is consistent across Tomcat and WebSphere. However, there are two scenarios that Tomcat will modify default log4j behaviour.

  • Use Default Java Util Logging for Tomcat, but defined -Dlog4j.configuration 
if you follow recommendations by some popular log4j documentation on how to configure log4j with Tomcat, you may be in trouble.

 export TOMCAT_OPTS="-Dlog4j.configuration=log4j-dev.properties"

If this system level setting specificies a file name different than log4j.properties, as the case in the above example, it will interrup log4j's default behaviour. Even if you have log4j.properties under WEB-INF\classes, you may encounter errors like "No appenders could be found for logger (com.appinf4j.perf)" and "Please initialize the log4j system properly".

My recommendation is to leave log4j alone and DO NOT use -Dlog4j.configuration in Tomcat unless it is well-communicated to developers.

  • Customized Tomcat to use Log4j for System logging
Tomcat provides documentation on how to use log4j, instead of the default Java Util logging, for Tomcat internal logging. This puts log4j jar in the system directory and introduces an extra layer tomcat-juli-adapters.jar. This will definitely affect log4j behaviour. I am not familiar with the setup and personally don't see any benefit by going through all these extra configurations. 

No comments:

Post a Comment