3

In our application, we decided to name the log4j configuration file as a custom name to avoid inadvertent loading of the default file from another jar. To configure this, we use org.springframework.util.Log4jConfigurer to specify the log4j location.

<bean
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass">
        <value>org.springframework.util.Log4jConfigurer</value>
    </property>
    <property name="targetMethod">
        <value>initLogging</value>
    </property>
    <property name="arguments">
        <list>
            <value>classpath:com/kilo/custom-log4j.xml</value>
        </list>
    </property>
</bean>

This also helps to keep all of the configuration in the code and let's a new developer hit the ground running (rather than keeping it in some setenv.sh for the container and separately for the test cases). So far we were sufficiently happy till we discovered that some valuable logging from the Spring container itself was missed out due to this.

[ 2012-09-05 00:16:43,188 [main] support.DefaultListableBeanFactory.registerBeanDefinition():618  INFO ]: Overriding bean definition for bean 'beanA': replacing [Generic bean: class [com.kilo.spring.context.log.ClassA]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [com/kilo/spring/context/log/spring-application-context-2.xml]] with [Generic bean: class [com.kilo.spring.context.log.ClassA]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [com/kilo/spring/context/log/spring-application-context-1.xml]]
[ 2012-09-05 00:16:43,235 [main] support.DefaultListableBeanFactory.preInstantiateSingletons():555  INFO ]: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@8453227: defining beans [org.springframework.beans.factory.config.MethodInvokingFactoryBean#0,beanB,beanA]; root of factory hierarchy

If I configured the name via the system property log4j.configuration I am able to see the logs. I guess this can go away if we put the configuration as a static block in one of the classes - but in a web application, this seemed strange to do. Any other tricks that I could use? Feel free to point out any/all incorrect paradigms that I am following here.

Thanks in advance!

Kilokahn
  • 2,281
  • 1
  • 25
  • 50

1 Answers1

2

In Tomcat you can configure such a string in the tomcats context.xml

<Parameter name="log4j.configuration" value="whereEver"/>

An other way would be configuration via JNDI.

BTW read this question Initializing Log4J with Spring?, it contains a link (in the comment of the accepted answer) to an implementation that configures log4j via jndi in a servlet listener.

Community
  • 1
  • 1
Ralph
  • 118,862
  • 56
  • 287
  • 383
  • I had forgotten to mention that we need to ensure that our test cases also can use the correct log4j file. – Kilokahn Sep 06 '12 at 05:08
  • @Kilokahn: I do not understand what this mean in context of this answer? – Ralph Sep 06 '12 at 06:43
  • while this works very nicely in a web-environment, I also wanted that the test cases that exist in my sub-modules also use the correct custom log4 file. More generally, how do you configure seamless logging from your unit test cases that are run via JUnit. I don't wish to go to the debug configurations each time and add a -D log4j.configuration=bar.xml (yeah I am lazy that way :)) – Kilokahn Sep 13 '12 at 03:26
  • @Kilokahn: then configure log4j in you tests – Ralph Sep 13 '12 at 07:02