0

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-value>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);
Antoine Claval
  • 4,923
  • 7
  • 40
  • 68

4 Answers4

1

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>
axtavt
  • 239,438
  • 41
  • 511
  • 482
  • Indeed, slf4j seems the way to go. But changing of logging framework for some ( annoying ) un-controled error message seems overkill to me. Or maybe the switch from log4j to slf4j is pain-less ? ( i'm sure that theoricly yes, but i doubt ) – Antoine Claval Jan 27 '10 at 16:47
  • You shouldn't change your logging framework, because slf4j is only a facade. The config I posted works fine with log4j logging in your code. – axtavt Jan 27 '10 at 18:03
  • This is only partly correct; you must exclude commons logging from every other place it might possibly appear as well (and there can be quite a few). I would not recommend using the com.springsource artifacts either unless you have a specific reason. See more details at my answer. – Erica Kane Mar 13 '15 at 16:54
0

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>
bmargulies
  • 97,814
  • 39
  • 186
  • 310
0

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
skaffman
  • 398,947
  • 96
  • 818
  • 769
0

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>
Erica Kane
  • 3,137
  • 26
  • 36