开发者

log4j logging twice

I am using log4j to log error and other system information. but come of the info logged twice at INFO level.

public static void main(final String... args) throws Exception {

    LOGGER.info("program start开发者_如何学JAVAed");
    try {
        // try body codes
    } catch (Exception ex) {
        LOGGER.info("program start-up failed.",ex);
    }
}

however when the program starts or failed the information logged twice, any one can help me to find what could be the reason of that.


Looks like your messages are being logged once by the root logger and again by the specific logger as you may have both the appenders configured (may be at different places -in a properties file and then in code).

This can be solved by setting additivity to false on your logger. Log4j manual mentions additivity in the Appenders and Layout section.Check that out


Agree with atlantis.

log4j.rootCategory=INFO, console
log4j.logger.org.hibernate=INFO

The above property settings will cause double logging.

However adding

log4j.additivity.org.hibernate=false

fixed the issue.

Check out page 62 of this book. http://books.google.com/books?id=hZBimlxiyAcC&printsec=frontcover#v=onepage&q&f=false


For those use XML format:

<logger name="package.class" additivity="false">
    <level value="info" />
    <appender-ref ref="file" />
    <appender-ref ref="console" />
</logger>

Note: By default, Loggers have their additivity flag set to true.


Just simply add

logger.setadditivity(false);

to your code (Reference).

We are having double results in the console, it's because appenders are not singletons, they are additive. Meaning, a category inherits all the appenders from its ancestors (by default). If we add an appender to a category and it writes to the same underlying stream (console, same file etc.) as some other appender, the same log message will appear twice (or more) in the log. In addition, if two categories in a hierarchy are configured to use the same appender name, Log4j will write twice to that appender. Configured for that category


If you can run the program with a Java debugger, put a breakpoint in the program where one of these double logging calls happen.

Examine the logger object in the debugger. If it is an org.apache.log4j.Logger (v 1.2.x) then it may have an AppenderAttachableImpl. You can query the AppenderAttachableImpl for the appender list.

If you find more than 1 appender, this could be the problem - and a clue to fixing it.


I had the same problem, and fixed by removing all appenders from the root logger. I don't know why, but solve my problem and I'm sharing:

        // Root
    rootLogger = Logger.getRootLogger();
    rootLogger.removeAllAppenders(); // Solve my problem
        // CSV
    csvLogger = rootLogger.getLogger("csvLogger");
        // Txt
    txtLogger = rootLogger.getLogger("txtLogger");

Without this extra line, even setting additivity to false, whenever I log with my csvLogger or txtLogger it logs twice.


A potential alternative to adjusting the additivity property is to examine your loggers from most specific to most generic. In the following example, we would expect to see double logging in the Console for any log events occurring in foo.bar.LoggingExampleClass. It would be safe to remove the extra Console appender from the foo.bar.LoggingExampleClass Logger as it is already covered by the Root logger.

<Logger name="foo.bar.LoggingExampleClass" level="DEBUG">
  <AppenderRef ref="Console" />   <!-- THIS APPENDER COULD BE REMOVED -->
  <AppenderRef ref="FooBarPackageLogging" />
</Logger>

<Root level="WARN">
  <AppenderRef ref="Console" />
  <AppenderRef ref="MainLogFile" />
</Root>

There are tradeoffs to both the additivity adjustment approach and the appender adjustment approach. Turning off additivity might inadvertently stop a desirable generic level logger's appender from being used. In the above example, setting the additivity="false" property on the foo.bar.LoggingExampleClass Logger would mean the logging event would not be appended to the MainLogFile referenced in the Root logger.

On the other hand, relying on parent appenders might be problematic if the parent appenders are changed without examining the effects on more granular loggers. For example, suppose there is a requirement that foo.bar.LoggingExampleClass logging events should be written to the Console. They currently are in the example configuration above due to additivity, even if the foo.bar.LoggingExampleClass Logger's Console appender is removed. However, if the Console appender was also removed from the Root logger without any additional adjustments, the requirement would no longer be met.


This is another option if you don't like to use the "additivity" feature.

In my case (and mostly your case too) the root logger is behind this additional log and you have another higher logger in your configurations, something like this

  <Loggers>
    <Logger name="com.foo.Bar" level="trace">
      <AppenderRef ref="Console"/>
    </Logger>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>

This will result in duplicated logs, and if you removed the root logger at all from this configuration file, log4j will force it's default root logger, check this note

Log4j will provide a default configuration if it cannot locate a configuration file. The default configuration, provided in the DefaultConfiguration class, will set up:

A ConsoleAppender attached to the root logger.

A PatternLayout set to the pattern "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" attached to the ConsoleAppender

Note that by default Log4j assigns the root logger to Level.ERROR.

If you want to override the default root logger and force it to not log you can remove it's Appender from your configuration file, like this

<Root level="error">
</Root>

This is just another option, however, I like to use the recommended method and set the "additivity" attribute to the child logger

<Logger name="com.foo.Bar" level="trace" additivity="false">
  <AppenderRef ref="Console"/>
</Logger>


In your resources/log4.properties file.

In that configuration file, if you have "log4j.rootLogger= DEBUG, file", then don't include "log4j.logger.org.springframework=DEBUG, file". Just keep the log4j.rootLogger part.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜