Wednesday, June 26, 2013

Dynamically changing a log4j configuration

For most of my career, I've used log4j as my logging back end. Whether during development, testing or production, I've encountered situations where I need to change the log level of a running web app on Tomcat. Restarting the application is often not feasible: either the situation I'm trying to diagnose would be wiped out, or other users would be impacted.  Here's an easy tweak, if you're using Spring, to dynamically change a log4j configuration. With this addition to your web.xml, log4j will pick up any changes you make to your log4j.properties file within 5 seconds:
<listener> 
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
</listener>
<context-param> 
    <param-name>log4jConfigLocation</param-name> 
    <param-value>WEB-INF/classes/log4j.properties</param-value>
</context-param> 
<context-param> 
    <param-name>log4jRefreshInterval</param-name> 
    <param-value>5000</param-value> 
</context-param>
The log4jRefreshInterval parameter is the key. Without that, the log4j configuration won't reload. While this solution is documented separately elsewhere, I wanted to call attention to this tweak because it really deserves wider knowledge.
There are, of course, other possible approaches such as writing your own custom JMX MBean, a custom servlet or using JRebel. These have their own advantages and disadvantages, but I feel the Spring Log4jConfigListener approach is the easiest and most straighforward for a developer.