Problems with duplicate or multiple log messages using log4j xml

Are you seeing duplicate or multiple log messages using log4j xml configuration?
The configuration below produces three log messages.

log4j.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
  <appender name="console" class="org.apache.log4j.ConsoleAppender">
    <param name="Target" value="System.out" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%-5p %c{1} – %m%n" />
    </layout>
  </appender>
  <logger name="com.acme.LoggingTest">
    <level value="debug" />
    <appender-ref ref="console" />
  </logger>
  <logger name="com.acme">
    <level value="debug" />
    <appender-ref ref="console" />
  </logger>
  <root>
    <priority value="debug" />
    <appender-ref ref="console" />
  </root>
</log4j:configuration>

LoggingTest.java:

package com.acme;
public class LoggingTest {
  
  private Logger log = Logger.getLogger(this.getClass());

  public static void main(String[] args) {
    // initialize log4j
    URL propsUrl = Loader.getResource("log4j.xml");
    DOMConfigurator.configure(propsUrl);
    new LoggingTest();
  }
  
  public LoggingTest(){
    log.debug("Hello World");
  }
}

The reason for the multiple log messages is that the three loggers (”com.acme.LoggingTest”, “com.acme” and “root”) are configured to use the same “console” appender. The “com.acme.LoggingTest” logger logs the first message to its appender and then traverses through its ancestors and logs to their appenders as well. This behavior is called appender additivity and it is set to “true” by default on all loggers including the “root” logger.

Logger Hiearchy:
- root
- com.acme
- com.acme.LoggingTest

The appender additivity can be turned off by specifying additivity=”false” on a logger. This causes the logger to only log to its appender but not to the appenders of its ancestors. Setting the additivity=”false” on all the loggers solves the multiple logging problem. The modified configuration below only outputs a single log message.

Fixed log4j.xml with additivity="false":

<?xml version=”1.0? encoding=”UTF-8? ?>
<!DOCTYPE log4j:configuration SYSTEM “log4j.dtd”>

<log4j:configuration xmlns:log4j=”http://jakarta.apache.org/log4j/”>
  <appender name=”console” class=”org.apache.log4j.ConsoleAppender”>
    <param name=”Target” value=”System.out” />
    <layout class=”org.apache.log4j.PatternLayout”>
      <param name=”ConversionPattern” value=”%-5p %c{1} – %m%n” />
    </layout>
  </appender>
  <logger name=”com.acme.LoggingTest” additivity=”false”>
    <level value=”debug” />
    <appender-ref ref=”console” />
  </logger>
  <logger name=”com.acme” additivity=”false”>
    <level value=”debug” />
    <appender-ref ref=”console” />
  </logger>
  <root>
    <priority value=”debug” />
    <appender-ref ref=”console” />
  </root>
</log4j:configuration>

More information on this topic can be found on the log4j wiki.

  • Share/Bookmark

Leave a Reply

You must be logged in to post a comment.