IsolatedLog4JLogger routes all commons-logging logging using Log4J to an ContextClassLoader
specific Hierarchy.
For web or application servers providing (and enforcing) commons-logging and
Log4J from a shared context (like JBoss), configuring Log4J loggers and appenders
from within a (web) application overrides and resets the global
Log4J LoggerRepository.
Capturing root logging for logging events from within the web application
for example isn't possible using a Log4J propery or xml configuration without
routing ALL root logging through the new (web application specific)
configuration.
It is possible using the Log4J API directly instead of configuration files,
but that requires hardcoded knowledge about how the logging is to be done.
Furthermore, if another application later on reconfigures the root logging again, the
current root logging configuration is closed, detached and rerouted to the new configuration.
The same applies of course to common named loggers like capturing springframework logging.
The only way to prevent this stealing of logging configuration is allowing only
one log4J configuration for the whole web or application server.
As this has to be done in a web or application server specific manner, setting up Jetspeed
for different servers will become rather complex and difficult to automate.
The IsolatedLog4JLogger solves these problems by routing all logging through a statically
configured ContextClassLoader isolated LoggerRepository.
Using this class requires a commons-logging.properties file in the WEB-INF/classes
folder containing:
org.apache.commons.logging.Log=org.apache.jetspeed.util.IsolatedLog4JLogger
During web application initialization, preferably from a ServletContextListener or
a Servlet init method loaded with a load-on-startup value of 0 (zero), a new
ContextClassLoader (e.g. web application) specific LoggerRepository as well as
the initialization of Log4J should be configured as follows:
Properties p = new Properties();
p.load(new FileInputStream(log4jFile));
// Create a new LoggerRepository
Hierarchy h = new Hierarchy(new RootCategory(Level.INFO));
// Configure the LoggerRepository with our own Log4J configuration
new PropertyConfigurator().doConfigure(p,h);
// set the LoggerRepository to be used for the current ContextClassLoader
IsolatedLog4JLogger.setHierarchy(h);
Instead of using a PropertyConfigurator a DomConfigurator could be used likewise.
TODO: It might be useful to have this utility class available for usage by Portlet
Applications too. Because this class must be included within a web application
classpath, a separate jetspeed-tools or jetspeed-utils library will have to be created
for it (and possibly other utility classes as well) which then can be put in the web
application lib folder.
author: Ate Douma version: $Id: IsolatedLog4JLogger.java 531463 2007-04-23 13:35:58Z taylor $ |