Home > Programming / tutorials > How do you dynamically change the log4j level

How do you dynamically change the log4j level

One of the common feature requested in most production application is to reload of log4j properties or lo4j xml file at runtime without retstarting of tomcat. Very helpful when you are debugging production level issues and would only like to turn on logging for a short period of time but also do not want any downtime.

I will show you a brief example on how to dynamically change the log4j level on a Tomcat server. This is a programmatic change

Set up includes

1. Jdk 1.7 and above2.

2. Apache-tomcat-7.0.57

3. Assumption your application is running on spring framework (I am on 3.2.2)

This is my java file. This configurer file  is required to reload the updated settings.


public class OptionalLog4jConfigurer extends Log4jConfigurer implements
 InitializingBean {

public static final Long DEFAULT_REFRESH = 30000L;
 private static final Log LOG = LogFactory
 .getLog(OptionalLog4jConfigurer.class);

private String configLocation;
 private Long refreshInterval;

public OptionalLog4jConfigurer(final String configLocation,
 final Long refreshInterval) {
 this.configLocation = configLocation;

if (refreshInterval == null) {
 this.refreshInterval = DEFAULT_REFRESH;
 }
 else {
 this.refreshInterval = refreshInterval;
 }
 }

/**
 * Will only customize if a configLocation has been specified.
 *
 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
 */
 public void afterPropertiesSet() throws Exception {
 if (!StringUtils.isEmpty(this.configLocation)) {
 LOG.info("Log4J configuration is being customized.");

this.initLoggingInternal();
 }
 else {
 LOG
 .info("Using default Log4J configuration. No customization requested");
 }
 }

public String getConfigLocation() {
 return this.configLocation;
 }

public Long getRefreshInterval() {
 return this.refreshInterval;
 }

}

Changes to application-Context.xml


 <bean id="optionalLog4jInitialization"  class="com.skg.jetm.OptionalLog4jConfigurer">
<constructor-arg index="0" type="java.lang.String"  value="${log4j.configuration}" />
<constructor-arg index="1" type="java.lang.Long" value="100" />
 </bean>

${log4j.configuration} is the path to your log4j file.

For local testing on my eclipse, I passed this value in jdk environment variables


-Dlog4j.configuration=file:\C:\Myfolder\log4j.properties -Dlog4j.debug

log4 in tomcat at runtime

When running with tomcat, you need to set up this in tomcat configuration


APPLICATION_OPTS="-Dlog4j.configuration=file:/C:/Myfolder/log4j.properties \
-Dlog4j.debug=true"

When I start tomcat,  the messages will be displayed as below


INFO: Deploying web application archive C:\devsoftware\apache-tomcat-7.0.57\webapps\myweb-0.0.1-SNAPSHOT.war
log4j: Using URL [file:/C:/apps44/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/C:/apps44/log4j.properties
log4j: Parsing for [root] with value=[error, stdout].
log4j: Level token is [error].
log4j: Category root set to ERROR
log4j: Parsing appender named "stdout".
log4j: Parsing layout options for "stdout".
log4j: End of parsing for "stdout".
log4j: Setting property [target] to [System.out].
log4j: Parsed "stdout" options.
log4j: Parsing for [com.skg] with value=[info].
log4j: Level token is [info].
log4j: Category com.skg set to INFO
log4j: Handling log4j.additivity.com.skg=[null]
log4j: Parsing for [com.crunchtime.util] with value=[error].
log4j: Level token is [error].
log4j: Category com.crunchtime.util set to ERROR
log4j: Handling log4j.additivity.com.crunchtime.util=[null]
log4j: Parsing for [org.springframework.web.context.ContextLoader] with value=[error].
log4j: Level token is [error].
log4j: Category org.springframework.web.context.ContextLoader set to ERROR
log4j: Handling log4j.additivity.org.springframework.web.context.ContextLoader=[null]
log4j: Finished configuring.
Feb 23, 2015 10:18:25 AM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deployment of web application archive C:\devsoftware\apache-tomcat-7.0.57\webapps\myweb-0.0.1-SNAPSHOT.war has finished in 2,434 ms

Change any settings in log4j file and you should see the context reload in tomcat server console


log4j: Parsing for [root] with value=[info, stdout].
log4j: Level token is [info].
log4j: Category root set to INFO
log4j: Parsing appender named "stdout".
log4j: Parsing layout options for "stdout".
log4j: End of parsing for "stdout".
log4j: Setting property [target] to [System.out].
log4j: Parsed "stdout" options.
log4j: Parsing for [com.skg] with value=[error].
log4j: Level token is [error].
log4j: Category com.skg set to ERROR
log4j: Handling log4j.additivity.com.skg=[null]
log4j: Parsing for [com.crunchtime.util] with value=[error].
log4j: Level token is [error].
log4j: Category com.crunchtime.util set to ERROR
log4j: Handling log4j.additivity.com.crunchtime.util=[null]
log4j: Parsing for [org.springframework.web.context.ContextLoader] with value=[error].
log4j: Level token is [error].
log4j: Category org.springframework.web.context.ContextLoader set to ERROR
log4j: Handling log4j.additivity.org.springframework.web.context.ContextLoader=[null]
log4j: Finished configuring.

Project at Github : Coming soon

Categories: Programming / tutorials Tags:
  1. Vijay
    March 25th, 2015 at 19:37 | #1

    Thx for the nice example.
    Where is the implmentation of initLoggingInternal()?
    What do you do in there?

  1. No trackbacks yet.