【发布时间】:2017-11-02 09:15:34
【问题描述】:
我正在创建自己的 SeriLog 接收器,使用 Building a Simple Sink 示例实现 ILogEventSink,目的是记录用户声明中的一些信息。要在 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();
如何在 sink 的 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;
}
}
【问题讨论】:
标签: c# httpcontext asp.net-core-2.0 serilog