[英]Logging in a C# library
關於在圖書館內登錄的最佳做法是什么?
我正在創建一個供用戶使用的 C# 庫,有時我想記錄錯誤或警告。 使用 log4net 並登錄文件是一個好習慣嗎?
我在我自己的庫中使用 log4net,但如果我的庫應該被其他人使用(即我的組織之外),我不會這樣做。 在這種情況下,我將使用一個接口進行日志記錄,在單獨的程序集中提供基於 log4net 的默認實現,並使用一種或另一種方式允許庫的用戶注入他們自己的實現。
話雖如此:我真的很喜歡 log4net,不會使用其他任何東西,但我認為強迫他人必須使用您選擇的日志記錄框架是錯誤的。
編輯:
這里的所有答案似乎都過時了。 我會做一個新的:
我的庫要求使用可選的Microsoft.Extensions.Logging.ILogger
對象來寫入日志消息。 如果沒有ILogger
對象,它就不會記錄任何內容。
消費者應用程序可以使用 NLog、Log4Net 或 SeriLog 創建這個ILogger
對象。我的庫可以在沒有日志框架鎖定的 ASP.NET 核心應用程序中使用。
使用其他 lggging 框架創建 Microsoft ILogger 的示例
private static readonly ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddNLog(); //=>install NLog.Extensions.Logging nuget
//or builder.AddSerilog(); => install Serilog.Extensions.Logging nuget
//or builder.AddLog4Net() //=> Microsoft.Extensions.Logging.Log4Net.AspNetCore
});
private static readonly ILogger<Program> log = loggerFactory.CreateLogger<Program>();
//configure nlog/serilog/log4net normally then
log.LogInformation("Hello");
在 Log4Net 的情況下,您還可以
ILoggerFactory loggerFactory = new LoggerFactory();
loggerFactory.AddLog4Net(); //load log4net.config by default
我會警惕在通用類庫中引入對 3rd 方庫(例如 log4net)的依賴:我更願意將其留給調用者來決定如何進行日志記錄。 如果庫的用戶已經在使用不同的日志框架怎么辦?
一些替代方案是:
對於錯誤,拋出一個Exception
或允許一個Exception
傳播,讓調用者處理它並做任何日志記錄。
對於警告(例如,您在庫中處理的異常),您可以考慮引發一個事件,如果他想記錄它,調用者可以處理該事件。 例如,您可以引發一個Error
事件,該事件采用帶有錯誤詳細信息的System.IO.ErrorEventArgs
(或類似的自定義EventArgs
)。
如果您覺得庫需要更多檢測,您可以在庫中的戰略點引發更多事件,調用者可以處理這些事件來進行日志記錄。
或者,您可以在您的類庫( ILogging
或類似的)中定義一個接口,如果他們想要記錄,調用者必須實現該接口。 讓調用者將此接口的實例傳遞給類構造函數以啟用日志記錄。
您可以執行類似於登錄AWS SDK for .NET 的操作,即支持多個日志記錄框架,但使用反射加載第 3 方框架以避免創建依賴項。 我個人不喜歡這個,但這是一種有效的方法,特別是如果您的庫足夠大以證明詳細的檢測是合理的。
log4net 只是一個 3rd 方庫,在使用 C# 時必須將其用作日志庫並不是最佳實踐。 我的建議是始終將日志保存到某個地方(最常見的是文本文件)。 但是,還有事件日志(需要一些額外的設置)。
我傾向於使用NLog ,我發現它非常易於使用且易於設置。 至於在您的類庫中登錄,您認為哪種方法最適合您的應用程序。 有些人會創造1個日志和它向下傳遞到類,其他人會創造每一個單獨的記錄loggable
類。 我傾向於為每個類創建一個靜態記錄器,它工作正常。
練習虎鉗的一個好方法是引入一個 Logging 門面,這樣你就不用關心你使用的記錄器,你有一個一致的記錄器通用接口。
例如,你可以試試這個,或者干脆自己寫。
在我看來,將日志記錄在您自己的小適配器中永遠不會有什么壞處,例如,以后可以輕松地從生產中剝離日志記錄。 我為此創建了一個小的日志包裝器,它的 API 如下所示:
Log.d("I'm a log message");
Log.w("I'm a warning with parmas", "param 1", 2, "..");
Log.e("I'm an error");
Log.e(new Exception("I'm an exception"));
AssertV2.IsTrue(1 + 1 == 3, "This assertion will fail");
有關更多示例,請參閱https://github.com/cs-util-com/cscore#logging
您可以登錄到控制台、文件、Unity,並且可以輕松添加更復雜的日志記錄目標,例如 Serilog
如果您有任何建議或其他反饋,請告訴我,我想讓它盡可能小,但想了解它尚未涵蓋的用例💚
這取決於你想做什么。
您是否想為純技術內容提供一個日志記錄機制,您可以使用不同的詳細程度(用於支持活動)打開/關閉? 或者您想記錄更多旨在供圖書館用戶閱讀的業務相關內容?
您應該先回答這些問題,然后才能決定要記錄的內容、存儲位置以及如何格式化...
無論如何,log4net 是用於所有這些目的的良好、成熟和穩定的日志記錄框架。 並且記錄到滾動文件是常見的做法(但到目前為止不是唯一的選擇......)。
問候托馬斯
您的用戶使用什么進行日志記錄?
這是您需要回答以確定正確框架的問題。
從我的觀點來看,Log4net 功能強大且相對容易。 如果沒有指定其他內容,您也可以使用它來登錄流編寫器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.