Asp.Net Core是否在请求之间保留CallContext?
我们有一个用例,可以将上下文属性(用户名)附加到线程,可以从我们的日志记录框架(NLog,MDLC)中提取该属性。据我所知,MDLC使用CallContext
。
我们需要每个请求都具有干净的上下文属性。我们是否需要在开始时清除CallContext?
答案 0 :(得分:1)
NLog.Web.AspNetCore提供了许多布局渲染器,可以捕获HttpRequest-context-properties进行日志记录(无需注入NLog MDLC)。
这将探测HttpRequest-Header的值JSNLog-RequestId
,如果为空则回退到AspNetCore-RequestId,如果也为空则回退到AspNetCore-TraceIdentifer
${aspnet-request:header=JSNLog-RequestId:whenEmpty=${mdlc:item=RequestId:whenEmpty=${aspnet-traceIdentifier}}}
可用的${aspnet} Layout-renderers列表
NLog在NetCore上使用AsyncLocal,如果您使用的是Microsoft Extension Logging(MEL),则可以使用ILogger.BeginScope将属性注入NLog MDLC中(并在离开范围时清除)
也可以使用MappedDiagnosticsLogicalContext.SetScoped填充NLog MDLC,当离开using-scope时也会清除。
答案 1 :(得分:-1)
我们使用Serilog(应该或多或少与NLog等效)。它与Aspnet核心的ILogger具有很好的集成。
您可以创建中间件并使用ILogger.BeginScope
public class LoggerMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<LoggerMiddleware> _logger;
public LoggerMiddleware(RequestDelegate next, ILogger<LoggerMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
var dictionary = new Dictionary<string, object>
{
{ "Username", context.User?.Identity?.Name; }
};
using (_logger.BeginScope(dictionary))
{
await _next(context);
}
}
}
通过我们的Serilog集成,我们可以在日志模板中使用Username
,并且在整个HTTP调用中保留了docker run -v /host/folder:/data some-image
(具有不同的线程)。
此Wiki https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-Core-2后,您的NLog整数应该相似