Глобальная настройка области ведения журнала в ASP.Net Core

Я хочу, чтобы определенные ключевые биты информации (имя службы, версия службы, имя хоста и т. Д.) Регистрировались в каждом сообщении журнала в службе 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>();
            });
}

Отсюда я получаю следующую запись:

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 .

Обратите внимание, как ServiceNameпоявляется только при ведении журнала на уровне хоста. Журнал уровня запроса не включает его.

Есть ли механизм для настройки области для каждого сообщения журнала, поступающего из 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();
        }
    });

РЕДАКТИРОВАТЬ

Даже при использовании промежуточного программного обеспечения, описанного выше, сообщения журнала от Microsoft.AspNetCore.Hosting.Diagnosticslogger не содержат полей с заданной областью. Например, обратите внимание, как во втором сообщении журнала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

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();
    }

Возможно, вам придется использоватьGetServices<ILoggerProvider>и позаботьтесь о списке, если у вас более одного провайдера.

Другие вопросы по тегам