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

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

Intro

经过 HttpContext 咱们能够拿到不少有用的信息,好比 Path/QueryString/RequestHeader 等请求信息, StatusCode/ResponseHeader 等响应信息,借助 HttpContext 咱们能够在日志中记录不少有用的信息,因而须要自定义一个基于 HttpContext 的 Enricherhtml

实现代码

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 中添加一些咱们想要记录的信息了git

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

上面的扩展能够自行修改,本身用的顺手就好~~github

Reference

原文出处:https://www.cnblogs.com/weihanli/p/12105239.htmlapp

相关文章
相关标签/搜索