.NET 有幾種不同的日志記錄和跟蹤工具,還有許多不同的第三方日志記錄程序。嘗試將一個應用程序從一種日志記錄技術更改為另一種日志記錄技術不是一件容易的事情,因為日志記錄 API 的使用分布在整個源代碼中。要使日志記錄獨立于任何日志記錄技術,可以使用接口。
.NET Core 在NuGet 包 Microsoft.Extensions.Logging 中嵌入了泛型 ILogger接口。這個接口定義了 Log 方法。Log 方法定義了參數,來指定 LogLevel(枚舉值)、事件ID(使用結構 EventId)、泛型狀態信息、記錄異常信息的 Exception類型,以及用字符串確定輸出格式的格式化程序:
void?Log<TState>(LogLevel?logLevel,?EventId?eventide,?TState?state,?Exception exception, Func<TState, Exception, string> formatter)
除了 Log 方法之外,ILogger 接口還定義了 IsEnabled 方法,以基于 LogLevel檢查日志記錄是否啟用,該接口也定義了方法 BeginScope,為日志記錄返回可釋放的作用域。ILogger 接口中的成員實際上是日志記錄所需的全部。Log 方法有許多需要填充的參數。為了簡化日志記錄,在 LoggerExtensions 類中定義了 ILogger 接口的擴展方法。擴展方法,例如LogDebug、LogTrace、LogInformation、LogWarning、LogError、LogCritical 和 BeginScope 都有幾個重載版本和易于使用的參數。
下面利用依賴注入,并使用包含的類 SampleController 作為一個泛型參數,注入ILogger 接口。泛型參數定義了日志記錄器的類別。在泛型參數中,類別是由類名組成的,包括名稱空間:
class SampleController
{private?readonly?ILogger<SampleController>?_logger;public?SampleController(ILogger<SampleController>?logger)?{_logger = logger;}//...
}
日志示例是使用了以下依賴項和名稱空間:
依賴項
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Logging
Microsoft.Extensions.Logging.Configuration
Microsoft.Extensions.Logging.Console
Microsoft.Extensions.Logging.Debug
Microsoft.Extensions.Logging.EventSource
Microsoft.Extensions.Logging.Filter
名稱空間
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Logging
Microsoft.Extensions.Logging.Console
System
System.Net.Http
System.Threading.Tasks
ILogger 接口可以簡單地用于調用擴展方法,如 LogInformation:
_logger.LogInformation("NetworkRequestSample started");
擴展方法提供重載版本,來傳遞額外的參數、異常信息和事件ID。為了使用事件ID,應用程序定義了一個常量值列表:
class?LoggingEvents
{public const int Injection = 2000; public const int Networking = 2002;
}
接下來,使用LogInformation和LogError擴展方法顯示NetworkRequestSampleAsync 方法的開頭、結束時間以及拋出異常時的錯誤信息:
public async Task NetworkRequestSampleAsync(string url)
{try{_logger.LogInformation(LoggingEvents.Networking,"NetworkRequestSampleAsync started with url {0}", url); var?client?=?new?HttpClient();string result = await client.GetStringAsync(url); _logger.LogInformation(LoggingEvents.Networking,"NetworkRequestSampleAsync completed, received {0} characters", result.Length);}catch?(Exception?ex){logger.LogError(LoggingEvents.Networking,?ex,"Error?in?NetworkRequestSampleAsync,?error?message:?{0},HResult:?{1}",ex.Message,?ex.HResult);}
}
注意:
ILogger 擴展方法的一個重載版本需要給第一個參數使用 EventId。在示例代碼中,傳遞一個 int。這是可能的,因為 EventId 結構實現了一個隱式運算符,來將 int 轉換為 EventId。
將消息傳遞給 LogXX 方法時,可以提供任何數量的的對象,并將其放入格式消息字符串中。此格式字符串使用位置參數傳入以下對象。不能使用可格式化的字符串 名因為格式字符串通常來自允許這些消息本地化的資源。
?微信公眾號?
DotNet講堂