网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > .Net >

.NET 中 Logger 常被忽视的方法 BeginScope

时间:2025-01-21 09:11

人气:

作者:admin

标签:

导读:BeginScope 方法是 .NET 中 ILogger 接口的一部分,用于创建日志记录的作用域(Scope)。这种作用域可以将特定的上下文信息包含在日志中,从而提高日志的可读性和调试效率。 配置日志包含...

BeginScope 方法是 .NET 中 ILogger 接口的一部分,用于创建日志记录的作用域(Scope)。这种作用域可以将特定的上下文信息包含在日志中,从而提高日志的可读性和调试效率。

配置日志包含作用域信息

首先,需要在日志配置中启用包含作用域信息。以 appsettings.json 为例,以下是配置示例:

{
  "Logging": {
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Default": "Information",
        "Microsoft.AspNetCore": "Warning"
      }
    }
  }
}

在该配置中,IncludeScopes 被设置为 true,这意味着在控制台日志中将包含作用域信息。

在代码中使用 BeginScope

使用 BeginScope 方法在日志中添加上下文信息,如下代码手动显示:

[HttpGet(Name = "Get")]
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 格式输出。

 

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信