在 ASP.Net Core 中全局设置日志记录范围

RB.*_*RB. 7 asp.net-core microsoft-extensions-logging

我想获取记录在 ASP.Net Core 服务中的每条日志消息上的某些关键信息位(服务名称、服务版本、主机名等)。

我有以下代码:

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();

        using (host.Services.GetRequiredService<ILogger<Program>>().BeginScope("ServiceName: {0}", "bob-service"))
        {
            host.Run();
        }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(builder =>
            {
                builder.AddConsole(o => o.IncludeScopes = true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}
Run Code Online (Sandbox Code Playgroud)

从这里我得到以下日志:

info: Microsoft.Hosting.Lifetime[0]
      => ServiceName: bob-service
      Now listening on: http://localhost:5002

info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      => ConnectionId:0HLSO8706NGBN => RequestPath:/ RequestId:0HLSO8706NGBN:00000001, SpanId:|aa5794ba-408ad22a63064421., TraceId:aa5794ba-408ad22a63064421, ParentId: => Middleware_Scope => /Index
      Executed handler method OnGet, returned result .
Run Code Online (Sandbox Code Playgroud)

请注意ServiceNameonly如何出现在主机级日志记录中。该请求记录并没有包括它。

是否有一种机制可以为来自 ASP.Net Core 的每个日志消息设置范围。

我已经尝试添加一个中间件来执行此操作,并且它大部分都可以工作,但是日志记录没有出现在"Microsoft.AspNetCore.Hosting.Diagnostics"日志消息中(尽管据我所知,它出现在其他所有内容上)。

app
    .Use(async (context, next) =>
    {
        // Middleware to add scoped values to log messages.
        var logger = context.RequestServices.GetRequiredService<ILogger<Startup>>();
        using (logger.BeginScope("ServiceName: {0}", "bob-service")))
        {
            await next();
        }
    });
Run Code Online (Sandbox Code Playgroud)

编辑

即使使用上述中间件,来自Microsoft.AspNetCore.Hosting.Diagnostics记录器的日志消息也不包含作用域字段。例如,请注意在第二条日志消息中,Middleware_Scope范围内的消息没有出现。

info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[6]
      => ConnectionId:0HLSOTDVELPJA => RequestPath:/css/site.css RequestId:0HLSOTDVELPJA:00000001, SpanId:|2fbd556d-44cc7c919266ccaf., TraceId:2fbd556d-44cc7c919266ccaf, ParentId: => Middleware_Scope
      The file /css/site.css was not modified

info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      => ConnectionId:0HLSOTDVELPJD => RequestPath:/js/site.js RequestId:0HLSOTDVELPJD:00000001, SpanId:|2fbd5570-44cc7c919266ccaf., TraceId:2fbd5570-44cc7c919266ccaf, ParentId:
      Request finished in 29.8413ms 304 application/javascript
Run Code Online (Sandbox Code Playgroud)

ale*_*ina 1

我不知道这是否正确,但我开始使用ILoggerProvider而不是全局设置范围ILogger<T>,并为其设置我自己的范围提供程序,如下所示:

    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();
        
        // ... other logging configurations, like ClearProviders() and AddJsonConsole(o => o.IncludeScopes = true);

        var provider = host.Services.GetService<ILoggerProvider>()
        if (provider is ISupportExternalScope scopedProvider)
        {
            var scopes = new LoggerExternalScopeProvider();
            scopes.Push("ServiceName: bob-service");
            scopedProvider.SetScopeProvider(scopes);
        }

        host.Run();
    }
Run Code Online (Sandbox Code Playgroud)

GetServices<ILoggerProvider>如果您有多个提供商,您可能必须使用并维护一份列表。