Serilog在Asp.NetCoreWebApi中的应用

2023-05-16

Serilog

  • Serilog应用
    • 基本配置应用
    • 控制输出日志Level
      • 1、restrictedToMinimumLevel
      • 2、levelSwitch
      • 3、使用Filter使不同等级日志写入不同的文本
    • 丰富日志内容
      • 1、配置Properties节点
      • 2、实现ILogEventEnricher接口
      • 3、在中间件中加入
    • 参考资料

Serilog应用

在asp.netcore webApi项目中使用Serilog记录日志。

基本配置应用

添加Serilog包引用

Install-Package Serilog.AspNetCore -Version 4.1.0

此包中有依赖Serilog.Settings.Configuration,Serilog.Sinks.Console,Serilog.Sinks.File不需要再单独安装;然后在startup或者From中注册serilog:

public Startup(IConfiguration configuration)
{
     Configuration = configuration;
     // 从配置文件中读取配置
     Log.Logger = new LoggerConfiguration().Enrich.FromLogContext().ReadFrom.Configuration(Configuration).CreateLogger();
}
public void ConfigureServices(IServiceCollection services)
{
     services.AddLogging(loggingBuilder =>
            {
                loggingBuilder.ClearProviders();
                loggingBuilder.AddSerilog(dispose: true);
            });
}

在appsettings.json中加入配置

"Serilog":{
    "MinimumLevel": {
      "Default": "Information", 
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo":[
       {
        "Name": "Console"
      },
      {
        "Name": "File",
        "Args": {
          "path": "Logs\\log-.txt",
          "rollingInterval": "Day", //按天使用新文件
          "fileSizeLimitBytes": "20971520", //每个文件最大大小,已B为单位,此处20M
          "rollOnFileSizeLimit": true,//超出指定大小使用新文件
          "outputTemplate": "{Timestamp:HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
        }
      }
    ]
}

运行代码之后再项目目录下会出现Logs文件夹,里面会有以日期命名的txt文件,如下图:
在这里插入图片描述

控制输出日志Level

1、restrictedToMinimumLevel

可以使用restrictedToMinimumLevel属性设置写入到文本中最低日志等级

//写入大于等于Error级别的日志
"WriteTo":[
   {
        "Name": "File",
        "Args": {
          "path": "Logs\\ErrorLog\\log-.txt",
          "rollingInterval": "Day",
          "restrictedToMinimumLevel": "Error",
          "fileSizeLimitBytes": "20971520",
          "rollOnFileSizeLimit": true,
          "outputTemplate": "{Timestamp:HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
    }
]

Error日志
可以看到文本中只记录了类型是Error的错误日志

2、levelSwitch

"Serilog":{
   //先声明
   "LevelSwitches": {
      "$errorSwitch": "Error",
      "$infoSwitch": "Information",
      "$warnSwitch": "Warning"
    },
   "WriteTo":[
         {
        "Name": "File",
        "Args": {
          "path": "Logs\\WarnLog\\log-.txt",
          "restrictedToMinimumLevel": "Error",
          "levelSwitch": "$warnSwitch",
          "rollingInterval": "Day",
          "fileSizeLimitBytes": "20971520",
          "rollOnFileSizeLimit": true,
          "outputTemplate": "{Timestamp:HH:mm:ss.fff} [{Level}] {Message}{NewLine}{Exception}"
        }
      }
   ]
}

WARN
注意:levelSwitch设置值之后,restrictedToMinimumLevel设置的值将会被忽略;

3、使用Filter使不同等级日志写入不同的文本

restrictedToMinimumLevellevelSwitch只能设置最小日志level,不能一个文本只写入指定的level的日志,可以使用Filter来过滤,要使用Filter的expression需要引入Serilog.Filters.Expressions

Install-Package Serilog.Filters.Expressions -Version 2.1.0

例如在Information文件夹下面只写入Information日志

  "Serilog": {
    "MinimumLevel": {
      "Default": "Debug", 
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo":[
      {
         "Name": "Logger",
         "Args": {
            "configureLogger": {
              "Filter": [
                {
                  "Name": "ByIncludingOnly",
                  "expression": "@Level = 'Information'"
                }
              ],
              "WriteTo": [
                {
                  "Name": "File",
                  "Args": {
                    "path": "Logs\\Information\\log-.txt",
                    "rollingInterval": "Day",
                    "fileSizeLimitBytes": "20971520",
                    "rollOnFileSizeLimit": true,
                    "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}"
                  }
                }
              ]
            }
         }
      }
    ]
   }

Serilog提供了多种Filter 表达式公式,具体见github:Serilog.Filters.Expressions

丰富日志内容

serilog除了默认的内容还可以自定义内容输出,此处记录几种配置方式:

1、配置Properties节点

"Serilog":{
   "MinimumLevel": {
     "Default": "Information", 
     "Override": {
       "Microsoft": "Warning",
       "System": "Warning"
     }
   },
   "WriteTo":[
      {
       "Name": "Console",
       "Args": {
       //日志输出模板
         "outputTemplate": "[{Level}] [{Timestamp:HH:mm:ss}]  {Application} {Message}{NewLine}{Exception}"
       }
     }
   ],
   "Properties": {
   //在此定义
     "Application": "SerilogTest"
   }
}

自定义属性

2、实现ILogEventEnricher接口

  1. 创建自定义CustomEnricher类实现ILogEventEnricher接口
    public class CustomEnricher : ILogEventEnricher
    {
        private const string PropertyName = "CustomInfo";

        public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
        {
            logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(PropertyName, "Enrich扩展"));
        }
    }
  1. 构建扩展方法
    public static class CustomLoggerConfigurationExtensions
    {
        public static LoggerConfiguration WithCustomInfo(this LoggerEnrichmentConfiguration enrichmentConfiguration)
        {
            if(enrichmentConfiguration == null) throw new ArgumentNullException(nameof(enrichmentConfiguration));
            return enrichmentConfiguration.With<CustomEnricher>();
        }
    }
  1. 使用
//在构建时通过扩展方法添加
Log.Logger = new LoggerConfiguration().Enrich.WithCustomInfo().ReadFrom.Configuration(Configuration).CreateLogger();

也可以直接在配置文件中加入,在加入时需要引入自定义属性所在dll名

"Serilog": {
    "LevelSwitches": {
      "$errorSwitch": "Error",
      "$infoSwitch": "Information",
      "$warnSwitch": "Warning"
    },
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    //引入dll名,
    "using": [ "QuartzWebApi" ],
    "Enrich": [ "WithCustomInfo", "FromLogContext", "WithMachineName", "WithThreadId", "WithProcessId" ],
    //输出
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          "outputTemplate": "[{Level}] [{Timestamp:HH:mm:ss}] [Enrich:{SourceContext}/{MachineName}/{ProcessId}/{ThreadId}/{CustomInfo}] {Message}{NewLine}{Exception}"
        }
      }
    ]
  }

Tip: 此处引用了几个Serilog提供的Enrich,除了FromLogContext以外,WithMachineName、WithThreadId、WithProcessId都需要额外引入对应的包

Install-Package Serilog.Enrichers.Environment  //WithMachineName
Install-Package Serilog.Enrichers.Thread  //WithThreadId
Install-Package Serilog.Enrichers.Process //WithProcessId

自定义Enrich

3、在中间件中加入

在asp.netcore api中间件中通过静态类LogContext添加属性

//从上下文中获取请求用户名
            app.Use(async (httpContext, next) =>
            {
                var userName = httpContext.User.Identity != null && httpContext.User.Identity.IsAuthenticated
                    ? httpContext.User.Identity.Name
                    : "Guest"; 
                LogContext.PushProperty("UserName", userName);  
                await next.Invoke();
            });
 "Serilog":{
    "MinimumLevel": {
      "Default": "Information", 
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo":[
       {
        "Name": "Console",
        "Args": {
        //日志输出模板
          "outputTemplate": "[{Level}] [{Timestamp:HH:mm:ss}] [UserName:{UserName}] {Message}{NewLine}{Exception}"
        }
      }
    ]
}

中间件

Tip: 可以通过请求上下文获取请求信息输入到日志中,例如IP,参数…

参考资料

github serilog各组件库

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Serilog在Asp.NetCoreWebApi中的应用 的相关文章

随机推荐