log4j记录两次

tcomlyy6  于 2022-11-06  发布在  其他
关注(0)|答案(9)|浏览(251)

我正在使用log4j来记录错误和其他系统信息。但是在INFO级别记录了两次信息。

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);
    }
}

然而,当程序启动或失败的信息记录两次,任何人都可以帮助我找到什么可能的原因。

rsaldnfx

rsaldnfx1#

同意亚特兰蒂斯的意见。

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

上述属性设置将导致重复记录。
然而添加

log4j.additivity.org.hibernate=false

已修复此问题。
请查看本书的第62页。http://books.google.com/books?id=hZBimlxiyAcC&printsec=frontcover#v=onepage&q&f=false

jmp7cifd

jmp7cifd2#

对于那些使用XML格式的:

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

注意:默认情况下,记录器的相加性标志设置为true。

wr98u20j

wr98u20j3#

只需添加

logger.setadditivity(false);

添加到代码(Reference)中。
我们在控制台中得到了双重结果,这是因为附加器不是单例,它们是可加的。(默认情况下)。如果我们将一个追加器添加到一个类别,并且它写入同一个底层流(控制台、相同文件等),则相同的日志消息将出现两次此外,如果层次结构中的两个类别被配置为使用相同的附加器名称,Log4j将向该附加器写入两次。

umuewwlo

umuewwlo4#

如果您可以使用Java调试器运行程序,请在程序中发生这些双重日志记录调用之一的位置放置一个断点。
检查调试器中的记录器对象。如果它是org.apache.log4j.Logger(v 1.2.x),则它可能具有AppenderAttachableImpl。您可以查询AppenderAttachableImpl以获得附加器列表。
如果您找到多个附加器,这可能就是问题所在-也是修复问题的线索。

nkoocmlb

nkoocmlb5#

我有同样的问题,并通过删除所有的附加器从根日志记录器修复.我不知道为什么,但解决我的问题,我分享:

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

如果没有这一行,即使将additivity设置为false,每当我用csvLogger或txtLogger进行日志记录时,它都会记录两次。

2cmtqfgy

2cmtqfgy6#

调整additivity属性的一个可能的替代方法是从最特定到最一般地检查您的记录器。在下面的示例中,我们希望在控制台中看到foo.bar.LoggingExampleClass中发生的任何日志事件的双重日志记录。从foo.bar.LoggingExampleClass记录器中删除额外的控制台附加器是安全的,因为它已经被根记录器覆盖了。

<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>

可加性调整方法和追加器调整方法都有折衷。关闭可加性可能会无意中停止使用所需的通用级别记录器的追加器。在上面的示例中,设置foo.bar.LoggingExampleClass Logger上的additivity="false"属性意味着日志记录事件不会追加到根记录器中引用的MainLogFile。
另一方面,如果父级附加器被更改而没有检查对更细粒度的日志记录器的影响,则依赖父级附加器可能会有问题。例如,假设要求foo.bar.LoggingExampleClass日志记录事件应被写入控制台。由于可添加性,它们当前在上面的示例配置中,即使foo.bar.LoggingExampleClass Logger的控制台附加器被删除。但是,如果控制台附加器也从根记录器中删除,而没有进行任何其他调整,则不再满足要求。

2ul0zpep

2ul0zpep7#

如果您不喜欢使用“加法”功能,这是另一个选项。
在我的情况下(大多数情况下也是你的情况),根日志记录器是在这个额外的日志后面,你在你的配置中有另一个更高的日志记录器,类似于这样

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

这将导致重复的日志,如果您从该配置文件中删除了根日志程序,log4j将强制使用其默认根日志程序,请检查this note
如果Log4j找不到配置文件,它将提供一个默认配置。DefaultConfiguration类中提供的默认配置将设置:
ConsoleAppender已附加到根记录器
模式布局设置为模式“%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n”,已附加到控制台添加器
请注意,默认情况下,Log4j将根记录器分配给Level. ERROR。
如果你想覆盖默认的根记录器并强制它不记录**,你可以从你的配置文件中删除它的Appender**,如下所示

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

这只是另一个选项,但是,我喜欢使用推荐的方法,并将“additivity”属性设置为子记录器

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

6bc51xsx8#

resources/log4.properties文件中。
在该配置文件中,如果有“log4j.rootLogger= DEBUG, file“,则不要包含“log4j.logger.org.springframework=DEBUG, file“,只保留log4j.rootLogger部分。

oogrdqng

oogrdqng9#

看起来您的消息由根记录器记录一次,然后由特定记录器再次记录,因为您可能配置了两个附加器(可能在不同的位置-在属性文件中,然后在代码中)。
这个问题可以通过在你的记录器上设置additivity为false来解决。Log4j手册在Appenders and Layout部分提到了additivity。

相关问题