.NET 中 Logger 常被忽视的方法 BeginScope
BeginScope 方法是 .NET 中 ILogger 接口的一部分,用于创建日志记录的作用域(Scope)。这种作用域可以将特定的上下文信息包含在日志中,从而提高日志的可读性和调试效率。配置日志包含作用域信息
首先,需要在日志配置中启用包含作用域信息。以 appsettings.json 为例,以下是配置示例:
{"Logging": { "Console": { "IncludeScopes": true, "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }}}在该配置中,IncludeScopes 被设置为 true,这意味着在控制台日志中将包含作用域信息。
在代码中使用 BeginScope
使用 BeginScope 方法在日志中添加上下文信息,如下代码手动显示:
public string Get(){ using (_logger.BeginScope("TenantName {TenantName}", "test")) { _logger.LogInformation("这是一条测试日志信息"); } return "ok";}在这段代码中,我们使用 BeginScope 创建了一个作用域,并设置了一个上下文变量。在这个作用域之内,日志信息将包含这个上下文变量。
将作用域信息 JSON化
通过实现自己的 ILogger 接口,我们可以将作用域信息以 JSON 格式输出:
public class ScopeLogger : ILogger{ private readonly string _categoryName; private static readonly AsyncLocal<Stack<object>> _scopeStack = new AsyncLocal<Stack<object>>(); public ScopeLogger(string categoryName) { _categoryName = categoryName; } public IDisposable BeginScope<TState>(TState state) where TState : notnull { if (_scopeStack.Value == null) { _scopeStack.Value = new Stack<object>(); } _scopeStack.Value.Push(state); return new Scope(() => _scopeStack.Value.Pop()); } public bool IsEnabled(LogLevel logLevel) => true; public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { var logEntry = new Dictionary<string, object> { ["Timestamp"] = DateTime.UtcNow, ["LogLevel"] = logLevel.ToString(), ["Category"] = _categoryName, ["Message"] = formatter(state, exception), ["Exception"] = exception?.ToString() }; if (_scopeStack.Value != null && _scopeStack.Value.Count > 0) { var scopes = new List<object>(); foreach (var scope in _scopeStack.Value) { scopes.Add(scope); } logEntry["Scopes"] = scopes; } var json = JsonSerializer.Serialize(logEntry, new JsonSerializerOptions { WriteIndented = true }); Console.WriteLine(json); } private class Scope : IDisposable { private readonly Action _onDispose; public Scope(Action onDispose) { _onDispose = onDispose; } public void Dispose() { _onDispose?.Invoke(); } }}public class ScopeLoggerProvider : ILoggerProvider{ public ILogger CreateLogger(string categoryName) { return new ScopeLogger(categoryName); } public void Dispose() { }}builder.Logging.ClearProviders();builder.Logging.AddProvider(new ScopeLoggerProvider());上面的代码创建了自己的 ILogger 实现,并将作用域信息以 JSON 格式输出。
页:
[1]