log4j logging twice

LoggingLog4j

Logging Problem Overview


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 started");
    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.

Logging Solutions


Solution 1 - Logging

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

Solution 2 - Logging

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

Solution 3 - Logging

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.

Solution 4 - Logging

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

Solution 5 - Logging

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.

Solution 6 - Logging

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.

Solution 7 - Logging

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.

Solution 8 - Logging

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>

Solution 9 - Logging

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTalha Bin ShakirView Question on Stackoverflow
Solution 1 - LoggingatlantisView Answer on Stackoverflow
Solution 2 - LoggingGervaseView Answer on Stackoverflow
Solution 3 - LoggingLee Chee KiamView Answer on Stackoverflow
Solution 4 - LoggingAugustRushView Answer on Stackoverflow
Solution 5 - LoggingTim TView Answer on Stackoverflow
Solution 6 - LoggingFernando RezkView Answer on Stackoverflow
Solution 7 - LoggingGoldDragonTSUView Answer on Stackoverflow
Solution 8 - LoggingAccountant مView Answer on Stackoverflow
Solution 9 - LoggingGeneView Answer on Stackoverflow