System.Diagnostics.Debug 命名空間與其他日誌記錄解決方案(log4net、MS Enterprise Library 等)
我目前正在調查 .net 項目的各種日誌記錄可能性,但我無法在 System.Diagnostics.Debug/Trace 功能和第三方庫(如 log4net、MS Enterprise Library、NLog 等)之間做出決定。
目前我發現了這一點:
- System.Diagnostics 相當難以配置和使用,因為您需要顯式配置所有偵聽器、過濾器、源等。它似乎也缺乏對數據庫的批量插入(考慮分別寫入 100'000 個日誌條目它自己的插入,可怕,不是嗎?)。但是有些人認為不使用額外的庫來做像 Logging 這樣的“基本”事情是“很酷的”(當然,在某些時候,減少項目所依賴的 3rd 方庫的數量是有意義的,但這次不是,我想)
- 3rd 方更強大,通常更快,更容易使用,但配置有時也很痛苦,而且這些庫通常不太可靠(比如 EntLib 神秘地突然停止記錄等)
- Common.Logging 呢?是否值得嘗試(因為,正如我所聽說的,它提供了各種日誌框架的外掛,並且充當應用程序和所需庫之間的介面)?
如果有人能指出我上面給出的比較的正確方向或糾正(或添加一些東西),我將不勝感激!也許如果你鼓勵我使用第三方,你可以建議一些特定的(考慮到我們的應用程序很可能不需要任何花哨的東西,如 UDP、滾動文件等 - 只是普通文件、電子郵件、數據庫和事件日誌)?
提前致謝!
您可以通過更一般的Google搜尋在 StackOverflow 上找到有關 log4net 和 NLog 的大量資訊。
您還可以找到很多關於 System.Diagnostics 的資訊。關於 System.Diagnostics 需要注意的一件事,我認為您會在 StackOverflow 上找到很多關於使用 Debug.Write/WriteLine 和 Trace.Write/WriteLine 的參考資料。一個可以說是“更好”的方法是使用 TraceSources。TraceSources 類似於 log4net 和 NLog 中的記錄器。TraceSources 允許您對日誌消息具有更高的粒度,從而更容易打開和關閉一些日誌(除按級別外,按類或類別)。TraceSources 確實有一個缺點,與 log4net 和 NLog 相比,您在程式碼中創建的每個 TraceSource 都必須在 app.config 中顯式配置(如果您希望它實際記錄)。
log4net 和 NLog 有一個分層概念,如果您要求的確切記錄器未明確配置,則檢查其“祖先”以查看是否配置了任何“祖先”,如果是,則請求的記錄器“繼承”這些設置。祖先只是記錄器名稱中由“.”分隔的部分。(因此,如果您請求一個名為 的記錄器
"ABC.DEF.GHI",則祖先將是"ABC.DEF",並且"ABC")。也有可能(需要?)在 app.config 中有一個“根”記錄器配置,如果沒有顯式配置並且沒有配置祖先,所有記錄器請求都將退回到該配置。因此,您可以僅配置一個“根”記錄器以在某個級別進行記錄,並且您程式碼中的所有記錄器都將在該級別記錄。或者,您可以將“根”記錄器配置為“關閉”,然後顯式打開一個或多個記錄器(或通過配置祖先)。這樣,除了那些配置的記錄器之外,沒有記錄器會記錄。如果你看這裡,你會發現一個有趣的 System.Diagnostics TraceSources 包裝器,它提供了與 log4net 和 NLog 非常相似的繼承能力。
為了顯示:
log4net 和 NLog 中記錄器的常見使用模式是獲取這樣的記錄器:
//log4net static ILog logger = LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); //NLog static Logger logger = LogManager.GetCurrentClassLogger();在這兩種情況下,記錄器的名稱都是完全限定的類型名稱。
在 app.config 文件中,如果需要,您可以只配置“根”記錄器,兩個記錄器都將繼承根記錄器的設置(級別、附加程序/目標等)。或者,您可以為某些命名空間配置記錄器。在該命名空間中定義其類型的任何記錄器都將繼承這些記錄器設置。
夠了 log4net 和 NLog,你可能已經知道它們是如何工作的。
上面的連結說明了一個基於 TraceSource 的包裝器,它允許類似的配置。所以,如果你願意,你可以在你的課堂上做這樣的事情:
static TraceSource ts = new TraceSource( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);使用上面連結的包裝器,您可以在更高級別(類/命名空間層次結構,而不是級別)配置 TraceSource 並在較低級別的記錄器中繼承這些設置。
因此,如果您的完全限定類型名稱是這樣的:ABC.DEF.GHI,那麼您可以為 ABC 或 ABC.DEF(命名空間級別)配置 TraceSource,並且類“GHI”將繼承這些設置。這確實可以減少您必須執行的配置量。
請注意,您不限於(使用任何這些日誌記錄平台)使用類的類型或類型名稱來獲取記錄器。您可以定義自己的記錄器命名方案,可能基於功能區域(“Communication”、“Communication.Send”、“Communication.Receive”等)。同樣,您可以請求最高粒度(或不)的 logger/TraceSource,然後以任何有意義的粒度級別進行配置。
因此,您可以像這樣在程式碼中請求記錄器:
ILog logger = LogManager.GetLogger("Communication.Receive"); ILog logger = LogManager.GetLogger("Communication.Send"); Logger logger = LogManager.GetLogger("Communication.Receive"); Logger logger = LogManager.GetLogger("Communication.Send"); TraceSource ts = new TraceSource("Communication.Receive"); TraceSource ts = new TraceSource("Communication.Send");如果您在 app.config 文件中僅配置“通信”,那麼所有記錄器都將繼承這些設置(因為它們是“通信”的後代)。如果您只配置“Communication.Receive”,那麼只有“Communication.Receive”記錄器會記錄。“Communication.Send”記錄器將被禁用。如果同時配置“Communication”和“Commuincation.Receive”,則“Communication.Receive”記錄器將記錄在“Communication.Receive”設置中,而“Communication.Sender”記錄器將記錄在“Communication”設置中。在 log4net 和 NLog 中,繼承可能不止這些,但我對它的了解還不夠。
使用 System.Diagnostics 時您會錯過的一件事是非常輕鬆地格式化日誌輸出格式的靈活性。有一個第三方庫為基於 TraceSource 的日誌記錄提供了非常好的可配置格式。你可以在這裡找到它。
我用過Common.Logging一些。主要用於原型設計,但我可能會在我們的下一個項目中使用它。它工作得很好,編寫自己的日誌抽象來插入它相對容易(例如,如果你想編寫一個類似於我上面連結的 TraceSource 抽象)。Common.Logging 現在缺少兩個重要的東西(儘管他們的網站說他們計劃在“下一個”版本中發布)是日誌記錄上下文(如 log4net 和 NLog NDC/MDC/GDC 對象和 System.Diagnostics.CorrelationManger.LogicalOperationStack ) 和 Silverlight 兼容性。在使用 Common.Logging 時,您仍然可以與程式碼中的 log4net 或 NLog 上下文對象進行互動,但這違背了它的目的,不是嗎。
我不知道我有沒有幫助!
以下是關於 log4net、NLog 和 TraceSource 的一些要點:
log4net - 非常流行,可能需要一些更新 - 至少建立在 .NET 4.0 上,幾年前的最後一個版本,非常靈活。
NLog - 在許多方面與 log4net 非常相似,現在是新版本(NLog 2.0 的測試版剛剛發布)
TraceSource - 沒有第三方依賴,無需您(或某人)的一些努力,不如 log4net 或 NLog 強大(關鍵缺陷 - 記錄器層次結構,輸出格式 - 兩者都可以通過上面的連結輕鬆解決),微軟檢測了他們的許多組件使用 System.Diagnostics,這樣您就可以獲得 Microsoft 的日誌輸出和交錯的日誌輸出。(通常,在其他日誌系統中擷取 System.Diagnostics 很容易,因此可能不是大問題)。
雖然我沒有經常使用 log4net 或 NLog,但在兩者之間我會傾向於 NLog,主要是因為剛剛發布的新版本(測試版)。我認為 TraceSource 也是一個合理的選擇,如果更基本的話,特別是如果您實現記錄器層次結構並使用上面連結的 Ukadc.Diagnostics 庫。
或者,使用 Common.Logging,您可以避免或延遲為您的底層日誌平台做出決定,直到您準備好。無論如何,Common.Logging 的一個非常有用的方面是,您可以在開發產品時“試駕”日誌平台,而無需更改任何應用程式碼。您不必等到決定使用特定的日誌記錄平台才能將日誌記錄添加到您的程式碼中。現在通過 Common.Logging api 添加它。當您接近傳遞時,您應該縮小您的日誌平台選擇範圍。使用該平台傳遞(如果您重新分發日誌平台),您就完成了。如果您願意,您仍然可以稍後更改。