November 29

Configuring log4j through Spring

As I mentioned in a previous post, in order to have different log4j settings in different environments without an environment-specific build, you need to allow Spring to manage the log4j configuration. Now there is currently no way to specify that in the Application Context itself, but a post in the Spring Support Forums suggests an alternate approach.

If you define the following custom bean:

package com.molecular.util.logging;
 
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Log4jConfigurer;
 
/**
 * A simple Spring Bean that allows log configuration to be managed in the Application Context
 *
 * Originally by Daniel Rijkhof (daniel.rijkhof@gmail.com)
 */
public class Log4jDirectConfigurer implements InitializingBean {
    private String location;
    private long refreshInterval;
 
    public void afterPropertiesSet() throws Exception {
        if (location == null) {
            return;
        }
 
        if (refreshInterval == 0) {
            Log4jConfigurer.initLogging(location);
        }
        else {
            Log4jConfigurer.initLogging( location, refreshInterval);
        }
    }
 
    // Attribute injectors
    public void setLocation(String location) {
        this.location = location;
    }
 
    public void setRefreshInterval(long refreshInterval){
        this.refreshInterval = refreshInterval;
    }
}

You can then define the location of the log4j configuration in the Spring Context. Remembering that in the earlier discussion we were using the system property env to denote the environment we’re running:

<bean id="log4jDirectConfigurer" class="com.molecular.util.logging.Log4jDirectConfigurer">
  <property name="location" value="classpath:log4j-${env}.properties"/>
  <property name="refreshInterval" value="0"/>
</bean>

Alternately, you can store the name of the log file in the system properties file. This is useful when the file name will vary wildly between installations:

<bean id="log4jDirectConfigurer" class="com.molecular.util.logging.Log4jDirectConfigurer">
  <property name="location" value="${logging.location}"/>
  <property name="refreshInterval" value="0"/>
</bean>

In either case, there’s no need to call the code directly, since Spring will execute afterPropertiesSet automatically during the setup phase.Now as with everything, this has limitations. This only handles information that is logged following bean initialization. Anything that happens during initialization (either in Spring or in your own code) will not be logged to these files. If your application does very little at initialization (which is fairly common) this may still work for you.

Edit: As Ken pointed out below, I’d removed a log directory from the underlying code, but forgotten to remove it from the configs. That’s fixed now.

Comments

  1. Ken said on January 2nd, 2008

    I’m unclear on the purpose of ${webapp.logDir}. Is it the directory where the logfiles will be located? Why is this not in the log4j properties file indicated in the location property?

  2. Don Brinker said on January 23rd, 2008

    You’re absolutely right. This is what I get for not vetting the solution VERY closely before pulling it from the Spring Forums. Edit coming soon…

  3. Okada said on May 28th, 2008

    Could it be possible configuring it to redirect the logs into the console instead to a file?

    The location value can be a absolute path instead of
    classpath:log4j-${env}.properties??

    Please answer me

    thanks

Add a comment

Browse posts by month

Browse by author

We're hiring!

Come take a look at careers with Molecular