我正在ILogEventSink
使用“构建一个简单的接收器”示例创建自己的SeriLog接收器,以记录用户声明中的某些信息。为了访问Core中的HttpContext,我通常会注入的实例,IHttpContextAccessor
但是该示例显示了在扩展方法中创建接收器的实例,例如
public class MySink : ILogEventSink
{
private readonly IFormatProvider _formatProvider;
public MySink(IFormatProvider formatProvider)
{
_formatProvider = formatProvider;
}
public void Emit(LogEvent logEvent)
{
// How to get HttpContext here?
}
}
public static class MySinkExtensions
{
public static LoggerConfiguration MySink(
this LoggerSinkConfiguration loggerConfiguration,
IFormatProvider formatProvider = null)
{
return loggerConfiguration.Sink(new MySink(formatProvider));
}
}
...然后使用水槽...
var log = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.MySink()
.CreateLogger();
如何在接收器的Emit方法中访问当前的HttpContext?还是可以通过DI框架创建接收器?
我有一个MVC站点,使用Serilog.AspNetCore v2.1.0针对.Net 4.6.2运行时运行Asp.Net Core 2框架。
更新-解决方法
在@tsimbalar的指针之后,我创建了类似于以下代码的中间件。在我的StartUp.Configure
方法中,我会app.UseMiddleware<ClaimsMiddleware>();
在应用程序身份验证步骤完成后使用来添加它(否则将不会加载任何声明)。
public class ClaimsMiddleware
{
private static readonly ILogger Log = Serilog.Log.ForContext<ClaimsMiddleware>();
private readonly RequestDelegate next;
public ClaimsMiddleware(RequestDelegate next)
{
this.next = next ?? throw new ArgumentNullException(nameof(next));
}
public async Task Invoke(HttpContext httpContext)
{
if (httpContext == null) throw new ArgumentNullException(nameof(httpContext));
// Get values from claims here
var myVal = httpContext
.User
.Claims
.Where(x => x.Type == "MyVal")
.Select(x => x.Value)
.DefaultIfEmpty(string.Empty)
.SingleOrDefault();
using (LogContext.PushProperty("MyVal", myVal))
{
try
{
await next(httpContext);
}
// Never caught, because `LogException()` returns false.
catch (Exception ex) when (LogException(httpContext, ex)) { }
}
}
private static bool LogException(HttpContext httpContext, Exception ex)
{
var logForContext = Log.ForContext("StackTrace", ex.StackTrace);
logForContext.Error(ex, ex.Message);
return false;
}
}
更新我认为您可能想看一下这篇文章:http : //mylifeforthecode.github.io/enriching-serilog-output-with-httpcontext-information-in-asp-net-core/
这个想法是注册一个自定义的中间件,该中间件会将所有上下文信息添加到LogContext
请求期间的当前信息中。
为了使其正常工作,您必须使用以下命令配置记录器
Log.Logger = new LoggerConfiguration()
// snip ....MinimumLevel.Debug()
.Enrich.FromLogContext()
// snip ...
.CreateLogger();
Nicholas Blumhardt的这篇文章可能也有帮助:https : //blog.getseq.net/smart-logging-middleware-for-asp-net-core/
警告-以下解决方案在这种情况下不起作用
如果记录器过早注册(在Program.Main()中),则以下解决方案将不起作用
首先,如果您想添加附加信息到记录的事件中,我相信您想要的是一个Enricher。
然后,您可以:
AddHttpContextAccessor()
):services.AddHttpContextAccessor();
ILogEventEnricher
中接受的实现IHttpContextAccessor
IHttpContextAccessor
(通过将type参数添加IHttpContextAccessor
到Startup.Configure()
您可以像这样配置记录器:
var logger = new LoggerConfiguration()
.EnrichWith(new MyEnricher(contextAccessor))
.WriteTo.Whatever()
.CreateLogger();
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句