log4j logging twice

前端 未结 9 1624
眼角桃花
眼角桃花 2021-02-04 23:02

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         


        
相关标签:
9条回答
  • 2021-02-04 23:32

    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.

    0 讨论(0)
  • 2021-02-04 23:34

    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

    0 讨论(0)
  • 2021-02-04 23:38

    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.

    0 讨论(0)
  • 2021-02-04 23:40

    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.

    0 讨论(0)
  • 2021-02-04 23:40

    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 讨论(0)
  • 2021-02-04 23:41

    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>
    
    0 讨论(0)
提交回复
热议问题