2012-10-10 37 views
3

我使用Log4J的AsyncAppender在我的應用程序,我不知道,有什麼用AsyncAppender的線程時,我的應用程序完成後會發生什麼?我應該手動終止線程,還是可以忘記它並退出應用程序而不必擔心某些日誌消息會丟失?停止log4j的AsyncAppender線程

回答

0

如果AsyncAppender爲您的應用程序中運行的線程,它會在您關閉應用程序關閉(和應用程序,我的意思是JVM的當前實例)。我不知道這是否是你的問題,但是

+0

這不是很準確 - 非守護線程將繼續運行,並會從關停保持JVM。 –

+0

好吧,我編輯的答案,試圖使之更加清晰和準確的 – Roger

1

看着AsyncAppender的來源,it creates a daemon thread(112-117行)來處理事件的寫入,作者希望你明確地在appender上調用close()以確保任何排隊的消息被寫入了JVM關閉之前:

dispatcher = new Thread(new Dispatcher(this, buffer, discardMap, appenders)); 

// It is the user's responsibility to close appenders before 
// exiting. 
dispatcher.setDaemon(true); 

通過設置線程作爲守護程序,這意味着JVM會跟不上,一旦你退出應用程序的核心運行。但是,這也意味着如果您的應用程序關閉而沒有通知appender,則隊列中的任何消息都將丟失。

+0

我怎樣才能訪問的appender對象,如果我使用XML配置Log4j和我使用SLF4J和春天嗎?有什麼方法可以在xml中配置log4J,以便在應用程序關閉時自動調用appender的close方法? – mike27

+0

這是一個很好的問題,因爲它看起來像是它們API的一個非常令人困惑的部分(並且使設計決定需要調用close()混淆)。我不知道什麼是最好的方式來訪問附加器會是這樣,但你可以嘗試像'Logger.getLogger(名稱).getAllAppenders()'或'Logger.getLogger(名稱).getAppender(名稱)'或'Logger.getRootLogger()。getAllAppenders()'。我會在JVM關機掛鉤中添加這個。它不會很漂亮,因爲它需要你的應用程序代碼來知道日誌配置 –

0

如果調用LogManager.shutdown() JVM關閉之前,它將繼續運行,直到追加程序已經刷新。請注意,這隻對log4j 1.x是必需的。我從文檔中瞭解到,Log4j 2會自動註冊一個關閉掛鉤來處理這個問題。