log4j记录两次

log4j记录两次

问题描述:

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

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

然而,当程序启动或登录失败两次的信息,任何人可以帮我找一下可能是其原因。

+0

可能是配置问题或初始化问题。 你在哪里初始化记录器? 不是你调用Logger.getLogger(SomeClass.class)两次吗? 一些额外的代码可以给我们更多的信息来帮助你。 – MaSEL 2011-04-18 06:38:25

看起来正在由根记录器记录的邮件一次,再由特定的记录,你可以有两种配置的追加程序(可能在不同的地方-in属性文件,然后在代码中)。

这可以通过在记录器上将可加性设置为false来解决。 Log4j的manual在附加目的地和布局section.Check说出来

+2

这是你应该如何解决这个问题,或者是一个可以掩盖更大配置问题的创可贴吗? – 2015-01-13 21:27:55

+1

没有记录器,没有记录。当我添加记录器时,它记录了两次。当我将可加性设置为false时,它会记录一次。这里发生了什么? – 2016-03-11 19:30:39

+0

@DanielKaplan如果你的记录器有一些分层结构,是的。从手动链接中解释说,你只需要除了Foo之外的所有类的ERROR消息,你希望看到所有的消息。您将Foo logger additive设置为false,因此任何ERROR消息都不会继续到root并重新打印。没有可加性,配置会变得更复杂,维护性更低,所以我会说这是正确的。 – whrrgarbl 2016-12-08 16:54:39

提到加同意亚特兰蒂斯。

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

+6

不应该是'假',而不是'真'? – 2011-09-23 14:13:00

+0

Google图书似乎随机隐藏了某些页面。 [Here's](http://veerasundar.com/blog/2009/08/log4j-tutorial-additivity-what-and-why/)一篇博文,我发现它很有帮助。它包括一个更广泛的例子,包括一些** log4j.category ... **条目 – 2015-03-19 22:05:19

对于那些使用XML格式:

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

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

如果你可以运行一个Java调试程序,把一个断点在程序中,这些双记录调用之一发生。

检查调试器中的记录器对象。如果它是一个org.apache.log4j.Logger(v 1.2.x),那么它可能有一个AppenderAttachableImpl。您可以查询appender列表的AppenderAttachableImpl。

如果发现超过1个附加器,这可能是问题 - 和线索修复它。

只需简单地添加

logger.setadditivity(false); 

到您的代码(Reference)。

我们正在控制台中的双重效果,这是因为追加程序不是单身,他们是添加剂。意思是,一个类别从它的祖先继承所有的appender(默认情况下)。如果我们将一个appender添加到一个类别中,并将其写入与其他appender相同的基础流(控制台,相同文件等),则相同的日志消息将在日志中出现两次(或更多次)。此外,如果层次结构中的两个类别配置为使用相同的appender名称,Log4j将向该appender写入两次。配置为该类别

来调整additivity财产造成另一种方法是检查你的记录仪从最具体到最普通的。在以下示例中,我们希望在控制台中看到foo.bar.LoggingExampleClass中发生的任何日志事件的双重记录。从foo.bar中删除额外的控制台appender是安全的。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> 

有折衷到可加性调整方法和附加器调整方法两者。关闭叠加性可能会无意中阻止了使用期望的通用级记录器的appender。在上面的例子中,在foo.bar.LoggingExampleClass记录器上设置additivity="false"属性意味着记录事件不会被追加到Root记录器中引用的MainLogFile中。

另一方面,如果在不检查对更细粒度记录器的影响的情况下更改父appender,则依赖父appender可能会产生问题。例如,假设需要将foo.bar.LoggingExampleClass记录事件写入控制台。即使foo.bar.LoggingExampleClass记录器的控制台appender被删除,它们当前也在上面的示例配置中。但是,如果控制台appender在没有任何其他调整的情况下也从Root Logger中移除,则不再满足此要求。