zoukankan      html  css  js  c++  java
  • 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, 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

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

    Reference

  • 相关阅读:
    luoguP4336 [SHOI2016]黑暗前的幻想乡 容斥原理 + 矩阵树定理
    luoguP4208 [JSOI2008]最小生成树计数 矩阵树定理
    luoguP2303 [SDOI2012]Longge的问题 化式子
    poj1704 Georgia and Bob 博弈论
    poj3537 Crosses and Crosses 博弈论
    luoguP4783 [模板]矩阵求逆 线性代数
    luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分
    [Luogu5319][BJOI2019]奥术神杖(分数规划+AC自动机)
    Forethought Future Cup
    Codeforces Round 554 (Div.2)
  • 原文地址:https://www.cnblogs.com/weihanli/p/12105239.html
Copyright © 2011-2022 走看看