欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-29 10:46:32
asp.net core 自定义基于 HttpContext 的 Serilog Enricher Intro 通过 HttpContext 我们可以拿到很多有用的信息,比如 Path/QueryString/RequestHeader 等请求信息, StatusCode/ResponseHeade ......

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()}");
    }
})

使用效果

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

more

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

reference