2009-10-05 108 views
8

我們有一個在多線程中運行並使用Log4Net作爲日誌框架的應用程序。我們遇到了一些未記錄日誌事件的場景。正如文檔中提到的,FileAppender和其他Appender是「而不是多線程操作的安全」。 我搜索了網絡上的解決方案或Appenders,但找不到任何。
您是否知道使用環形緩衝區或隊列提供多線程支持的多線程安全Log4Net Appender?或者我們是否應該使用不同的多線程安全日誌框架?
在此先感謝!多線程安全日誌

+4

重複http://stackoverflow.com/questions/1294668 - 基本上,log4net將適當地爲您使用appender。 – 2009-10-05 10:16:19

+0

感謝您的回答。我編寫了一些確認Log4Net多線程安全的單元測試(請參閱下面的答案)。 – 2009-10-05 14:58:19

回答

13

我寫了一些單元測試來重現問題:測試創建50個線程和每個線程記錄500條消息。之後,對筆跡進行了統計,結果我按不同的順序得到了25,000(50×500)行。我在雙核心和八核心機器上測試過它。
我測試了靜態記錄儀:

private static ILog StaticLog = log4net.LogManager.GetLogger(RepositoryName, "Static logger"); 

,並與測試類/線程的每個實例記錄器:

ILog instanceLog = LogManager.GetLogger(RepositoryName, "Instance logger: " + ThreadId.ToString()); 


和所有測試都是綠色的。

因此,Log4Net正常工作,並很好地處理多線程情況。如果以正確的方式使用Logger API,則應該更新Appender文檔並聲明支持多線程操作。

我想我們在客戶機器上遇到的缺少日誌條目的問題是由其他問題引起的。也許底層的虛擬機或硬件壞了。

感謝您的幫助!

8

我從來沒有使用FileAppender,不能說它是線程安全的,但我從來沒有任何問題RollingFileAppender。文檔聲明該類型的成員不是線程安全的,但是除非您嘗試直接寫入appender,否則這應該是確定的。你並不需要添加自己的鎖定周圍的代碼調用,如:

log.Info("message"); 
+1

是的,log4net自動鎖定日誌通話,因此這裏沒有線程問題。 – 2009-10-05 10:17:49

+0

所以你說Log4Net是多線程安全的,如果它通過Logger API使用的話?所以我想我們的代碼中有使用它的問題?
在每個班級中,我們正在創建一個這樣的記錄程序:

  private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);  

但是,只有一個此類的實例在線程中使用。 – 2009-10-05 10:28:47

0

測試是綠色的並不意味着這些行實際上是寫入文件,但沒有例外。或者你是否包含了在你的測試中讀取文件的檢查?在IIS中打開Web花園後,我遇到了同樣的問題。那時,只有一個線程正在向文件寫入行。

更多關於多線程和log4net的位置:herehere

+3

Web-garden場景意味着IIS正在使用多個*進程*,這與多個*線程*不同。寫入FileAppender的多個線程很好;由於文件系統的工作原理,寫入FileAppender的多個進程會導致錯誤。 – Bleaourgh 2011-10-31 20:17:26

0

log4net的是線程安全的,但附加目的地使用的可能是一個問題。文件appender在被調用時會「阻止」。這意味着在您的應用程序中,發送到Log4Net的每個日誌都必須在返回到您的應用程序之前完成每個appender。

它是線程安全的,許多線程可以使用Log4Net來記錄消息,但在調用Log4Net的應用程序等待appender完成。日誌記錄的執行時間將添加到您的應用程序時間。

這很容易證明。請參閱:https://www.codeproject.com/Tips/1219696/Log-Net-Singleton-Wrapper-for-Concurrent-Logging

我所做的是將Log4Net函數「包裝」到線程安全的靜態單例中,然後將每個日誌消息放入併發線程中運行的隊列中。這將使所有日誌記錄與應用程序併發,但應用程序執行不會等待appender完成。