2011-04-18 136 views
54

我正在使用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

回答

75

看起來正在由根記錄器記錄的郵件一次,再由特定的記錄,你可以有兩種配置的追加程序(可能在不同的地方-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

29

提到加同意亞特蘭蒂斯。

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

28

對於那些使用XML格式:

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

注意:默認情況下,記錄器有其相加標誌設置爲true。

2

如果你可以運行一個Java調試程序,把一個斷點在程序中,這些雙記錄調用之一發生。

檢查調試器中的記錄器對象。如果它是一個org.apache.log4j.Logger(v 1.2.x),那麼它可能有一個AppenderAttachableImpl。您可以查詢appender列表的AppenderAttachableImpl。

如果發現超過1個附加器,這可能是問題 - 和線索修復它。

2

只需簡單地添加

logger.setadditivity(false); 

到您的代碼(Reference)。

我們正在控制檯中的雙重效果,這是因爲追加程序不是單身,他們是添加劑。意思是,一個類別從它的祖先繼承所有的appender(默認情況下)。如果我們將一個appender添加到一個類別中,並將其寫入與其他appender相同的基礎流(控制檯,相同文件等),則相同的日誌消息將在日誌中出現兩次(或更多次)。此外,如果層次結構中的兩個類別配置爲使用相同的appender名稱,Log4j將向該appender寫入兩次。配置爲該類別

0

來調整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中移除,則不再滿足此要求。