Application Logging in a Container Environment

Log4j, by default, uses a single logger repository. So, unless you log within the context of your own custom logger repository, the last entity to configure Log4j will have configured Log4j for every app using the default logger repository. This is not usually a concern in a standalone app, but in a containers such as Tomcat, JBoss, and Websphere, you will have to take precautions in order to keep your app's logging configuration separate from others in the container. Here are a some ways to do this...

1. In Servlet applications, put log4j.jar in WEB-INF/lib and your Log4j configuration file (log4j.properties or log4j.xml) in WEB-INF/classes of each webapp. Since each webapp should have its own classloader that other apps can't see (nor should the container be able to see it based on Java2 classloader heirarchy rules) and the WebappClassLoader loads classes and resources in a manner inverse to that of normal Java2 classloaders (looks to itself before looking at parent classloaders to load classes and resources), the default logger repository is, essentially, reserved for use by your webapp alone. This is known to work in Tomcat Standalone. Some appservers must be specifically configured to achieve child-first, or parent-last, classloading behavior.

2. Use a custom logger repository selector to create a distinct logger repository for your application. This allows for log4j to be in a global classloader that can be seen by all apps (and/or the container as well), but still provide a distinct logging environment for each application. To do this, you will need to utilize an implementation of a logger repository selector; two of which exist in the logging-log4j-sandbox project, though only the one based on JNDI is really recommended. The classloader-based one can suffer from memory leaks and other mysterious classloading issues.

See:

Because the Log4j sandbox is voliatile, these classes won't necessarily exist in the trunk at any given time. Two tags were cut and a while back providing permanent snapshots of compilable, Log4j 1.2.xx compatible, working code. These tags are "LOG4J_SANDBOX_ALPHA3" and "LOG4J_SANDBOX_ALPHA2". Below are the links to the alpha3 code...

Implementations of custom repository selectors and servlet utilities:

Take a look at the InitContextListener and InitShutdownController to utilize the repository selectors in a webapp...

InitShutdownController does most of the work, but the Javadoc for InitContextListener is the place to go to learn how to use this stuff. It is pretty extensive and should be instructive.

The code for the above in the trunk was modified to work with Log4j 1.3 alpha. However, given that all development on 1.3 has ceased and 1.2 development has continued in earnest, the alpha3 tag is probably recommended. Here's a link to the trunk anyway....

To check out the source, see instructions at http://logging.apache.org/site/repositories.html

AppContainerLogging (last edited 2012-02-04 20:05:37 by PidSter)