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

  • 相关阅读:
    《软件需求最佳实践》阅读笔记06
    《软件需求最佳实践》阅读笔记05
    《软件需求最佳实践》阅读笔记04
    《软件需求最佳实践》阅读笔记03
    《软件需求最佳实践》阅读笔记02
    项目目标文档
    Eclipse使用maven构建web项目(创建项目)
    eclipse项目上有红叉内部不报错
    ajax文件上传;post方式getparameter获取不到值;getReader取值方法
    去除url中的& = ;并到Map中的方法:
  • 原文地址:https://www.cnblogs.com/etoumao/p/12776737.html
Copyright © 2011-2022 走看看