.NET Core 日志 和 Serilog

2022年3月31日 2571点热度 1人点赞 1条评论
内容纲要
  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0-preview.2.22152.2" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0-preview.2.22152.2" />
    <PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
    <PackageReference Include="Serilog.Sinks.Console" Version="4.0.2-dev-00890" />
  </ItemGroup>

使用依赖注入单纯注入 Serilog 的方法:

    static IServiceProvider GetServiceProvider()
    {
        using var log = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Console()
            .Enrich.FromLogContext()
            .CreateLogger();

        Serilog.Log.Logger = log;

        var serviceCollection = new ServiceCollection();

        serviceCollection.AddLogging(builder => builder.AddSerilog(dispose: true));

        return serviceCollection.BuildServiceProvider();
    }

获取日志:

        var loggerProvider = GetServiceProvider().GetService<ILoggerProvider>()!;
        var logger = loggerProvider.CreateLogger(nameof(Program));

创建 Scope

日志范围注意事项
Microsoft.Extensions.Logging提供BeginScopeAPI,可用于添加任意属性以记录特定代码区域内的事件。API 有两种形式:

方法:IDisposable BeginScope(TState state)
扩展方法:IDisposable BeginScope(this ILogger logger, string messageFormat, params object[] args)

模板:

{SourceContext} {Timestamp:HH:mm} [{Level}] (ThreadId:{ThreadId}) {Message}{NewLine}{Exception} {Scope}
        using (logger.BeginScope("Checking mail"))
        {
            // Scope is "Checking mail"
            logger.LogInformation("Opening SMTP connection");

            using (logger.BeginScope("Downloading messages"))
            {
                // Scope is "Checking mail" -> "Downloading messages"
                logger.LogError("Connection interrupted");
            }
        }

file

临时增加一个属性

需要先开启 .Enrich.FromLogContext()


        using (LogContext.PushProperty("Test", 1))
        {
            // Process request; all logged events will carry <code>RequestId</code>
            Log.Information("{Test} Adding {Item} to cart {CartId}", 1,1);
        }

嵌套复杂一些:

using (LogContext.PushProperty("A", 1))
{
    log.Information("Carries property A = 1");

    using (LogContext.PushProperty("A", 2))
    using (LogContext.PushProperty("B", 1))
    {
        log.Information("Carries A = 2 and B = 1");
    }

    log.Information("Carries property A = 1, again");
}

ASP.NET Core 模板案例

  "Serilog": {
    "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Sinks.Elasticsearch", "Serilog.Sinks.Trace" ],
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Default": "Debug",
        "Microsoft": "Debug",
        "System": "Debug",
        "System.Net.Http.HttpClient": "Debug",
        "Microsoft.AspNetCore": "Debug",
        "Microsoft.Hosting.Lifetime": "Debug",
        "Microsoft.AspNetCore.Hosting.Diagnostics": "Debug"
      }
    },
    "Enrich": [ "FromLogContext", "WithMachineName" ],
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          "outputTemplate": "{SourceContext} {Scope} {Timestamp:HH:mm} [{Level}] {Message:lj} {Properties:j} {NewLine}{Exception} "
        }
      },

模板是:

{SourceContext} {Scope} {Timestamp:HH:mm} [{Level}] {Message:lj} {Properties:j} {NewLine}{Exception} 

配置日志输出:

            var logger = _loggerfactory.CreateLogger<IFreeSql>();

            fsql.Aop.CurdAfter += (s, e) =>
            {
#pragma warning disable CA2017 // 参数计数不匹配。
                logger.LogInformation("[Freesql] operation log,operation type:{CurdType} TableName: {DbName} , Time: {ElapsedMilliseconds}ms ,SQL: {Sql}", e.CurdType, e.Table.DbName, e.ElapsedMilliseconds, e.Sql, e.DbParms);
#pragma warning restore CA2017 // 参数计数不匹配。
            };
            services.AddSingleton(fsql);

效果:

file

在中间件很多多层调用时,注入属性示例:

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        var enrichers = new List<ILogEventEnricher>();
        if (!string.IsNullOrEmpty(correlationId))
        {
            enrichers.Add(new PropertyEnricher(_options.EnricherPropertyNames.CorrelationId, correlationId));
        }

        using (LogContext.Push(enrichers.ToArray()))
        {
            await next(context);
        }
    }

痴者工良

高级程序员劝退师

文章评论