Serilog:为每个请求创建和跟踪唯一的日志上下文吗?

时间:2018-08-22 02:29:11

标签: asp.net-core-mvc serilog

如何在ASP.NET Core MVC应用程序中为每个请求保留唯一的日志上下文?

我一直在寻找如何实现这一目标的时间。我只能以为我缺少明显的东西。

例如,基本上来说,我有一个接受一些有效负载的端点。然后,它将属性推送到日志记录上下文中以丰富日志(在处理请求等过程中从有效负载或从存储库中检索日志)。

我要确保的是,如果有多个异步HTTP请求进入,则该上下文对于该请求是唯一的,并在请求处理完成后将其丢弃,以免混淆。

有没有办法做到这一点?已经考虑了吗?我正在Main方法中设置Serilog,并将其添加到WebHostBuilder中。我以为我需要做某种DI,但是我不想丢失MVC应用程序完全启动之前输出的日志。

编辑:当前如何设置

public static void Main(string[] args)
{
    Log.Logger = new LoggerConfiguration()
        .ReadFrom.Configuration(Configuration)
        .CreateLogger();

     try
     {
        Log.Information("Starting web host...");
        BuildWebHost(args).Run();
     }
     catch (Exception ex)
     {
        Log.Fatal(ex, "Host terminated unexpectedly");
     }
     finally
     {
        Log.CloseAndFlush();
     }
 }

 private static IWebHost BuildWebHost(string[] args) =>
     WebHost.CreateDefaultBuilder(args)
         .UseSerilog()
         .UseKestrel()
         .UseUrls("http://*:5000")
         .UseStartup<Startup>()
         .Build();

1 个答案:

答案 0 :(得分:0)

我在我的一个项目中使用中间件来实现此功能:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

public class LoggingEnrichmentMiddleware
{
    private readonly ILogger<LoggingEnrichmentMiddleware> _logger;

    private readonly RequestDelegate _next;

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

    public async Task Invoke(HttpContext context)
    {
        using (_logger.BeginScope(
            "{Method} {Path} {Query} {RemoteIp} {LocalIp}",
            context.Request.Method,
            context.Request.Path,
            context.Request.QueryString,
            context.Connection.RemoteIpAddress,
            context.Connection.LocalIpAddress))
        {
            await _next(context);
        }
    }
}

请确保在您的Startup.Configure方法中添加中间件:

app.UseMiddleware<LoggingEnrichmentMiddleware>();