Friday, October 30, 2009

Configure Log4j for a web application on Apache Tomcat

Today I stumbled upon a problem of configuring log4j for a web application on Apache Tomcat. The problem is where to keep the log4j.xml and how initialize the logging system. One way is to keep the log4j.xml anywhere and change the Tomcat startup script to add -Dlog4j.configuration=<log4j.xml file path> but I do not want to depend on a change in Tomcat startup script.

I tried all the possible places but it did not work. I realized unless I define the log4j.configuration system parameter it will not work. I then looked at log4j api and found DOMConfigurator class which initializes the log4j system from log4j.xml.

Here is what I done to keep all configurations inside my application.

Create a listener class as shown below to initialize the log4j using the log4j.xml deployed with your application.


import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

public class Log4jInitializationListener implements ServletContextListener {
public Log4jInitializationListener() {
}
public void contextInitialized(ServletContextEvent servletContextEvent) {
DOMConfigurator.configureAndWatch(servletContextEvent.getServletContext().getInitParameter("log4jXMLFilePath"));
Logger logger = Logger.getLogger(Log4jInitializationListener.class);
logger.debug("Log4j working");
}

public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}


Add these entries to your web.xml. Here we are defining a parameter to configure the log4j.xml file path and registering the above created listener.

<pre>
<context-param>
<param-name>log4jXMLFilePath</param-name>
<param-value>WEB-INF/classes/log4j.xml</param-value>
</context-param>
<listener>
<listener-class>Log4jInitializationListener</listener-class>
</listener>
</pre>

Start the application to confirm log4j is working. I have used the following log4j configuration so here it creates a server.log file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="RollingFileAppender" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="server.log"/>
<param name="MaxFileSize" value="100MB"/>
<param name="MaxBackupIndex" value="10"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %l - %m%n" />
</layout>
</appender>
<root>
<priority value="debug"/>
<appender-ref ref="RollingFileAppender"/>
</root>
</log4j:configuration>