2020-11-09

asp.net core中使用Serilog以及自定义Enricher

Serilog简介

与其他许多.NET库一样,Serilog还提供了对文件,控制台等的基本诊断日志记录。它易于设置,具有简洁的API,并且可以在最新的.NET平台之间移植。

使用和配置、自定义Enricher

由于 serilog 配置信息比较多,避免硬编码代码中,我们在 appsetting.jgon 同级目录中新建一个 serilogsetting.json 的日志配置文件,简单内容如下:

{	"Serilog": {		"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.Seq" ],		"MinimumLevel": {			"Default": "Information",			"Override": {				"System": "Error",				"Microsoft": "Error"			}		},		"WriteTo": [			{				"Name": "Console"			},			{				"Name": "Seq",				"Args": {					"serverUrl": "http://localhost:5341/",					"apiKey": "L2on8gpgjose5uldhdch"				}			}		]	}}

更多配置内容请参考:serilog wiki 文档

接下来,在 Program.cs 中添加一个方法,初始化这些配置,然后重写下构建主机的代码:

public class Program{ public static int Main(string[] args) {  var logConfig = GetLogConfig();  Log.Logger = new LoggerConfiguration()      .ReadFrom.Configuration(logConfig)      .Enrich.FormLogContext()      .CreateLogger();   try  {   // web host 初始化   var host = BuildWebHost(args);   host.Run();   return 0;  }  catch(Exception e)  {   Log.Fatal(ex, "{ApplicationContext} 出现错误:{messsage} !", AppName, ex.Message);   return 1;  }  finally  {   Log.CloseAndFlush();  } }  /// <summary> /// 读取日志配置 /// </summary> /// <returns></returns> private static IConfiguration GetLogConfig() {  var builder = new ConfigurationBuilder()      .AddJsonFile("serilogsetting.json", optional: false, reloadOnChange: true);  return builder.Build();  }}

然后,添加一个自定义Enircher,用来记录HttpContext,的数据。_enrichAction则可以自定义,默认记录ip,请求路径,请求方法,和返回响应码:

public class HttpContextEnricher:ILogEventEnricher{ private readonly IServiceProvider _serviceProvider; private readonly Action<LogEvent, ILogEventPropertyFactory, HttpContext> _enrichAction;  public HttpContextEnricher(IServiceProvider serviceProvider) : this(serviceProvider, null) {}   public HttpContextEnricher(IServiceProvider serviceProvider, Action<LogEvent, ILogEventPropertyFactory, HttpContext> enrichAction) {  _serviceProvider = serviceProvider;  if (enrichAction == null)  {   _enrichAction = (logEvent, propertyFactory, httpContext) =>{    var x_forwarded_for = new StringValues();    if (httpContext.Request.Headers.ContainsKey("X-Forwarded-For"))    {     x_forwarded_for = httpContext.Request.Headers["X-Forwarded-For"];    }    logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("client_ip", JsonConvert.SerializeObject(x_forwarded_for)));    logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("request_path", httpContext.Request.Path));    logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("request_method", httpContext.Request.Method));     if (httpContext.Response.HasStarted)     {      logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("response_status", httpContext.Response.StatusCode));     }   }  }else{   _enrichAction = enrichAction;  } }   public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) {  var httpContext = _serviceProvider.GetService<IHttpContextAccessor>()?.HttpContext;   if (null != httpContext){    _enrichAction.Invoke(logEvent, propertyFactory, httpContext);   } } }

现在,我们添加了一个记录HttpContext的Enricher,但是怎么用起来呢,怎么添加到日志对象中呢。就要靠asp.net core的中间件了。新建一个HttpContextLogMiddleware中间件:

public class HttpContextLogMiddleware{ private readonly RequestDelegate _next; public HttpContextLogMiddleware(RequestDelegate next) {  _next = next; } public async Task InvokeAsync(HttpContext context) {  var serviceProvider = context.RequestServices;  // 将我们自定义的Enricher添加到LogContext中。  // LogContext功能很强大,可以动态添加属性,具体使用介绍,参见官方wiki文档  using (LogContext.Push(new HttpContextEnricher(serviceProvider)))  {   await _next(context);  } }}// 使用扩展方法形式注入中间件public static IApplicationBuilder UseHttpContextLog( this IApplicationBuilder builder){ return builder.UseMiddleware<HttpContextLogMiddleware>();}

这样,我们就建立了一个中间件,接下来在Startup.cs的Configure方法中app.UseHttpContextLog();即可。

此处需要注意中间件的顺序,参见官方ASP.NET CORE的中间件介绍

这样,我们就添加了一个自定义的Enricher来记录请求的上下文信息。启动应用程序,看下输出结果:

原文转载:http://www.shaoqun.com/a/489605.html

ask me:https://www.ikjzd.com/w/2459

auditor:https://www.ikjzd.com/w/2437

pat:https://www.ikjzd.com/w/1079


Serilog简介与其他许多.NET库一样,Serilog还提供了对文件,控制台等的基本诊断日志记录。它易于设置,具有简洁的API,并且可以在最新的.NET平台之间移植。使用和配置、自定义Enricher由于serilog配置信息比较多,避免硬编码代码中,我们在appsetting.jgon同级目录中新建一个serilogsetting.json的日志配置文件,简单内容如下:{ "Ser
bol:https://www.ikjzd.com/w/291
派代:https://www.ikjzd.com/w/2197
如何从九寨沟到黄龙 :http://tour.shaoqun.com/a/14490.html
Facebook"送测广告"必须了解的10个要领:https://www.ikjzd.com/home/125944
亚马逊推出新借贷计划 / eBay自有支付体系加速前进:https://www.ikjzd.com/home/91597

No comments:

Post a Comment