如何将 属性 添加到 ASP.NET Core 中的所有日志消息

How to add a property to all log messages in ASP.NET Core

我有一个 ASP.NET 核心应用程序,我们正在寻求增强我们的登录功能。基本上,我们想从请求 header 中获取值,并将其作为 属性 记录在该请求期间记录的任何内容上。这是一个例子:


public class ExampleController : Controller
{
    private readonly ILogger _logger;

    public ExampleController(ILogger<ExampleController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    [AllowAnonymous]
    public IActionResult TestLogging()
    {
        _logger.LogInformation("Insert Message Here");

        return Ok();
    }
}

因此,如果我们发送此请求 GET /Example/TestLogging,我们希望看到上述 header 附加到“在此处插入消息”日志消息。

看起来这应该可以通过中间件或过滤器或其他东西实现,但我不太确定如何去做。我们正在使用 Serilog 作为我们的日志提供程序,但最好使用 ILogger(可能使用 BeginScope)一般地执行此操作以保持实现不知情。我知道我们可以在我们的方法中写这样的东西:

using (var scope = _logger.BeginScope(new Dictionary<string, object>() {{"HeaderName": "HeaderValue"}}))
{
    _logger.LogInformation("Insert Message Here");
}

但我们希望对所有内容进行通用处理,而不是针对每个方法进行处理。

创建一个简单的中间件,它可以从 HttpContext 中提取每个请求所需的信息,如您所说,使用 BeginScope:

public class LoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

    public LoggingMiddleware(
        RequestDelegate next,
        ILogger<LoggingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        var state = new Dictionary<string, object>
        {
            ["headers:MY_HEADER"] = httpContext.Request.Headers["MY_HEADER"].ToString(),
        };

        using (_logger.BeginScope(state))
        {
            await _next(httpContext);
        }
    }
}

将您的中间件添加到依赖注入:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<LoggingMiddleware>();
}