微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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,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,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,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,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

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

Reference

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐