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

相關文章
相關標籤/搜索