asp.net core 自定义基于 HttpContext 的 Serilog Enricher

Intro

通过 HttpContext 我们可以拿到很多有用的信息,比如 Path/QueryString/RequestHeader 等请求信息, StatusCode/ResponseHeader 等响应信息,借助 HttpContext 我们可以在日志中记录很多有用的信息,于是需要自定义一个基于 HttpContext 的 Enricher

实现代码

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) =>            {                logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestIP", httpContext.GetUserIP()));                logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestPath", httpContext.Request.Path));                logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestMethod", httpContext.Request.Method));                logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Referer", httpContext.Request.Headers["Referer"].ToString()));            };        }        else        {            _enrichAction = enrichAction;        }    }    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)    {        var httpContext = _serviceProvider.GetService<IHttpContextAccessor>()?.HttpContext;        if (null != httpContext)        {            _enrichAction.Invoke(logEvent, propertyFactory, httpContext);        }    }}public static class EnricherExtensions{    public static LoggerConfiguration WithHttpContextInfo(this LoggerEnrichmentConfiguration enrich, IServiceProvider serviceProvider)    {        if (enrich == null)            throw new ArgumentNullException(nameof(enrich));        return enrich.With(new HttpContextEnricher(serviceProvider));    }    public static LoggerConfiguration WithHttpContextInfo(this LoggerEnrichmentConfiguration enrich, IServiceProvider serviceProvider, Action<LogEvent, ILogEventPropertyFactory, HttpContext> enrichAction)    {        if (enrich == null)            throw new ArgumentNullException(nameof(enrich));        return enrich.With(new HttpContextEnricher(serviceProvider, enrichAction));    }}

使用方式

上面的 Enricher 允许我们定义了一个委托来自定义加从 HttpContext 中添加一些我们想要记录的信息了

logFactory.AddSerilog(loggingConfig =>{    loggingConfig        .Enrich.FromLogContext()        .Enrich.WithHttpContextInfo(app.ApplicationServices, (logEvent, propertyFactory, httpContext) =>        {            logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestIP", httpContext.GetUserIP()));            logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestPath", httpContext.Request.Path));            logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("RequestMethod", httpContext.Request.Method));            logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("Referer", httpContext.Request.Headers["Referer"].ToString()));            if (httpContext.Response.HasStarted)            {                logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("ResponseStatus", httpContext.Response.StatusCode));            }        })        ;    var esConnString = Configuration.GetConnectionString("ElasticSearch");    if (esConnString.IsNotNullOrWhiteSpace())    {        loggingConfig.WriteTo.Elasticsearch(esConnString,            $"logstash-{ApplicationHelper.ApplicationName.ToLower()}");    }})

使用效果

More

上面的扩展可以自行修改,自己用的顺手就好~~

(0)

相关推荐