Multiple Log4J instances in a WebApp
Many times I've come across the classic problem of different logging instances in an web app server. Most of them involve classloader conflicts:
I've finally come across a solution for log4j. It involves using a repository selector based on a context, this is fully described here - Supporting the log4j RepositorySelector in Servlet Containers.
So the solution to stop conflicts and independently configure each application is this.
First put ALL logging jars in the shared library directory including (
Next is a little extension for log4j: log4j-contrib. Put its jar into the shared library as well.
Next you have to configure each individual app. Add the following to the web.xml (at the top so it is the first called).
If you want to have Tomcat use log4j (not just the apps), then add the following configuration:
For catalina.bat add somewhere in the file (line 119):
Or under linux, catalina.sh add somewhere appropriate (line 163):
Additionally if you put the log4j.properties in somewhere other than CATALINA_HOME/lib then you'll need to add that directory to the classpath. e.g.
Now alter conf/logging.properties and replace the entire contents with:
And that's it for the command line.
Note: the argument -Dlog4j.configuration, sets the file name to search for on the Tomcat start up classpath. You CANNOT specify the exact file to load, instead you have to add the folder as a class folder (add external folder in eclipse), in order for it to be located.
Under the launch configuration classpath, add the following jars/folders:
- The webapp has log4j.jar but the webapp has bundled log4j.jar as well and you get errors.
- OR you have the log4j.jar in the application server's shared library directory and you have 2 webapps but the configuration conflict - or even just a configuration for the application server itself and one for the webapp.
I've finally come across a solution for log4j. It involves using a repository selector based on a context, this is fully described here - Supporting the log4j RepositorySelector in Servlet Containers.
So the solution to stop conflicts and independently configure each application is this.
First put ALL logging jars in the shared library directory including (
log4j.jar, slf4j-api.jar, slf4j-log4j.jar, commons-logging.jar,
etc). This ensures that if they one of the libraries is loaded in the main classloader it can access the other jars.Next is a little extension for log4j: log4j-contrib. Put its jar into the shared library as well.
Next you have to configure each individual app. Add the following to the web.xml (at the top so it is the first called).
<!-- Use log4j.properties from the classpath -->
<context-param>
<param-name>log4jConfigLocations</param-name>
<param-value>logj.properties</param-value>
</context-param>
<listener>
<listener-class>com.mathieucarbou.log4j.web.ContextLoggingListener</listener-class>
</listener>
If you want to have Tomcat use log4j (not just the apps), then add the following configuration:
For catalina.bat add somewhere in the file (line 119):
rem JavaUtilLogging to SLF4J required to be on classpath.
set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\lib\jul-to-slf4j-1.5.6.jar;%CATALINA_HOME%\lib\slf4j-api-1.5.6.jar;%CATALINA_HOME%\lib\slf4j-log4j12-1.5.6.jar;%CATALINA_HOME%\lib\log4j-1.2.15.jar
Or under linux, catalina.sh add somewhere appropriate (line 163):
# JavaUtilLogging to SLF4J required to be on classpath.
CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/lib/jul-to-slf4j-1.5.6.jar:"$CATALINA_HOME"/lib/slf4j-api-1.5.6.jar:"$CATALINA_HOME"/lib/slf4j-log4j12-1.5.6.jar:"$CATALINA_HOME"/lib/log4j-1.2.15.jar
Additionally if you put the log4j.properties in somewhere other than CATALINA_HOME/lib then you'll need to add that directory to the classpath. e.g.
rem if you put it in /conf
set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\conf
Now alter conf/logging.properties and replace the entire contents with:
handlers = org.slf4j.bridge.SLF4JBridgeHandler
.handlers = org.slf4j.bridge.SLF4JBridgeHandler
And that's it for the command line.
Running it from Eclipse
Eclipse has a guide how to set it up at Enable JULI logging in Eclipse. To set it up, with the configuration files stored in the workspace under Servers for a server named "Tomcat6-Localhost" add the following to the end of the Server's launch configuration arguments:-Dlog4j.configuration="log4j.properties"Copy in logging.properties and log4.properties into the workspace configuration directory as per the command line version.
-Djava.util.logging.config.file="${workspace_loc:Servers/Tomcat6-Localhost-config/logging.properties}"
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
Note: the argument -Dlog4j.configuration, sets the file name to search for on the Tomcat start up classpath. You CANNOT specify the exact file to load, instead you have to add the folder as a class folder (add external folder in eclipse), in order for it to be located.
Under the launch configuration classpath, add the following jars/folders:
- jdk:lib/tools.jar
- bin/bootstrap.ja
- lib/jul-to-slf4j-1.5.6.jar
- lib/slf4j-api-1.5.6.jar
- lib/slf4j-log4j12-1.5.6.jar
- lib/log4j-1.2.15.jar
- workspace:Servers/Tomcat6-Localhost-config
Comments
Post a Comment