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()}"); } })
使用效果
more
上面的扩展可以自行修改,自己用的顺手就好~~