2012-10-16 25 views
1

讓我和我使用的系統的簡要說明開始:Log4J的 - 與動態線程創建的環境中每個線程都有一個日誌文件

我們有作爲後臺進程運行,運行的工作單位作爲一個系統他們進來。這個守護進程在給定一個新的工作單元時動態地創建一個新的線程。對於這些工作單元中的每一個,我需要Log4J創建一個新的日誌文件以追加到 - 文件名將在運行時提供,當時必須創建新的日誌文件。這個守護進程必須能夠無限期地保持活躍狀態​​,我相信這會引起一些內存問題,正如我將解釋的那樣。

我的第一個想法是爲每個工作單元創建一個新的記錄器,當然在線程之後命名它。工作單元的線程保留對該記錄器的引用。當單元完成後,它將被垃圾收集,但問題在於Log4J本身保留了對Logger的引用,該引用永遠不會再被使用。所有這些記錄器似乎都可能導致虛擬機內存不足。

另一種解決方案:子類Filter,通過線程名稱篩選Appenders,並將它們放在同一個Logger上。然後,刪除Appenders作爲工作單元完成。當然,這需要添加代碼來刪除appender。這將是很多代碼更改。

我已經看過NDC和MDC,它似乎是用來管理交錯輸出到同一個文件。我曾考慮過提出這個解決方案,但我不認爲它會被接受。

我想說Log4J似乎是而不是以這種方式運行,即在運行時動態創建新的日誌文件,因爲它們是必需的(或期望的)。所以我不確定接下來要看哪個方向 - log4j不是這裏的解決方案,還是我錯過了什麼?我在NDC方面看得不夠緊密嗎?或者,我擔心Log4J會因爲我看不到的原因而陷入記錄器中?

+0

而不是每次都使用間接創建一個新文件的記錄器,您可以用FileWriter寫入一個新文件,並在完成後關閉它。 –

回答

0

您可以創建一個新的日誌方法來包裝正常的日誌方法,並附加線程ID。 類似於以下內容(過於簡化,但你明白了)。我相信Log4j已經是線程保存了,所以只要你不記錄一噸,你應該沒問題。然後,你可以很容易地在線程ID上grep。

public log(long id, String message) 
{ 
    logger.log("ThreadId: id + "message: " + message); 
} 
+0

謝謝你的回覆。 這會記錄所有線程的輸出到同一個文件,是否正確?這不是我正在尋找的解決方案。我不希望確保線程安全;我知道Log4J那樣做。 –

+0

檢查此問題中提供的鏈接。看起來他們正在試圖做同樣的事情,但是有了請求而不是線程。 http://stackoverflow.com/questions/2331128/log4j-one-log-file-per-request?rq=1 – aglassman

相關問題