开发者

Working log4j config ignored by Spring classes

I use log4j and he work just fine. A log4j.xml file is in my classpath, i use appender and category... again, it's work just fine for my code or code of other librairy.

But the spring classes continue to flood stdout with message i want to log elsewhere. It's beggin to be anoying.

Offending message : org.springframework.jms : some error.... More generally, all classes of the org.springframework package send message to stdout.

So i put this in my log4j.xml :

<appender name="JMS-ERROR" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="tms.logs.folder/tms.logs.files.prefix-jms-error.log"/>
    <param name="Append" value="true"/>
    <param name="MaxFileSize" value="1000KB"/>
    <param name="MaxBackupIndex" value="2"/>
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="**DVIDEA** %d{dd.MM.yyyy HH:mm:ss} %c  %m%n"/>
    </layout>
    <filter class="org.apache.log4j.varia.LevelRangeFilter">
        <param name="LevelMin" value="DEBUG" />
        <param name="LevelMax" value="FATAL" />
    </filter>
</appender>


<category name="org.springframework.jms" additivity="false">
    <appender-ref ref="JMS-ERROR"/>
</category>

It's work with other librairie. Why not spring ?

I do some research, and it's appeart that Spring use common-logging, and not log4j. It's that a possible cause ? Any workaround ?

I have try to add a log4jConfigurationListener to my web.xml. he's working but i stil dont have any control over the spring error message.

<context-param>
   <param-name>log4jConfigLocation</param-name>
   <param-value>classpath:log4j.xml</param-value>
</context-param>
<context-param>
   <param-name>log4jRefreshInterval</param-name>
   <param-v开发者_运维知识库alue>10000</param-value>
</context-param>
<listener>
   <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

Edit :

Some more info :

  • i use Tomcat 5.5
  • a log4j.property ( old log4j config ) is still present for historical reason. I'v try to remove it => no change.

EDIT 2 : I use the following workaround, but i'm not happy with it : it's not configurable

java.util.logging.Logger springLogger = Logger.getLogger("org.springframework.jms");
springLogger.setLevel(Level.OFF);


Note that in the Spring samples they are using slf4j to route log messages from Commons Logging to log4j. In Maven's pom.xml it looks this way:

<!-- Exclude Commons Logging -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>org.springframework.context</artifactId>
    <version>${spring.version}</version>
    <exclusions>
        <!-- Exclude Commons Logging in favor of SLF4j -->
        <exclusion>
            <groupId>org.apache.commons</groupId>
            <artifactId>com.springsource.org.apache.commons.logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- Add slf4j API -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>com.springsource.slf4j.api</artifactId>
    <version>${slf4j.version}</version>
</dependency>

<!-- Add Commons Logging -> slf4j bridge -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
    <version>${slf4j.version}</version>
    <scope>runtime</scope>
</dependency>

<!-- Add slf4j -> log4j bridge -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>com.springsource.slf4j.log4j</artifactId>
    <version>${slf4j.version}</version>
    <scope>runtime</scope>
</dependency>


You might need:

<bean id="log4jInitialization"
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetClass"
            value="org.springframework.util.Log4jConfigurer" />
        <property name="targetMethod" value="initLogging" />
        <property name="arguments">
            <list>
                <value>conf/log4j.xml</value>
            </list>
        </property>
    </bean>


Spring uses Apache Commons Logging, which in turn decides whether to use STDOUT (via java.util.logging) or Log4j. If you're getting Spring output on STDOUT, then commons-logging hasn't located log4j for some reason.

If you set the system property org.apache.commons.logging.diagnostics.dest, commons-logging can be configured to log its diagnostics, telling you what steps it is taking to determine in log4j is present.

So in your tomcat startup script, set the system property, e.g.

-Dorg.apache.commons.logging.diagnostics.dest=STDOUT


You must use SLF4J, and include the bridge to the logging platform you want (log4j) but you must also exclude commons-logging from all the other places it might be pulled in. It helps to have an IDE to do this, or you can put a dummy entry in for commons-logging. For details on that, see the SLF4J FAQ entry

A previous answer mentioned using the com.springsource artifacts, however if you are using Maven Central the right way to do it is:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.10</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.10</version>
</dependency>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜