面向云技术架构 - 痴者工良

  • 首页
  • 工良写的电子书
    • kubernetes 教程
    • 从 C# 入门 Kafka
    • 多线程和异步
    • 动态编程-反射、特性、AOP
    • 表达式树
  • 本站文章导航
  • 隐私政策
愿有人陪你颠沛流离
遇到能让你付出的事物或者人,都是一种运气。
能遇到,就该珍惜。或许你们最终没能在一起,但你会切实地感受到力量。
正因为这样,那段相遇才变得有价值,才没有辜负这世间的每一段相遇。
  1. 首页
  2. .NET
  3. 正文

.NET Core 日志 和 Serilog

2022年3月31日 913点热度 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);
        }
    }
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: serilog
最后更新:2022年8月3日

痴者工良

高级程序员劝退师

点赞
< 上一篇
下一篇 >

文章评论

  • 痴者工良

    编译期日志生成方案 https://github.com/dotnet/docs/blob/main/docs/core/extensions/logger-message-generator.md

    2022年7月5日
    回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    取消回复

    文章目录
    • 创建 Scope
    • 临时增加一个属性
    • ASP.NET Core 模板案例

    COPYRIGHT © 2022 whuanle.cn. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    粤ICP备18051778号

    粤公网安备 44030902003257号