在配置准备就绪之前配置Serilog?

3

我有一个使用Serilog进行日志记录的Web API(.NET Core 3.1)。 Serilog在IWebHostBuilder中很早就被添加了:

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    return WebHost
        .CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseSerilog((context, configuration) =>
        {
            if (context.HostingEnvironment.IsDevelopment())
            {
                configuration.WriteTo.Console(LogEventLevel.Debug);
                return;
            }

            configuration.WriteTo.ApplicationInsights(TelemetryConverter.Traces, LogEventLevel.Error);
        });
}

这意味着(据我所知),我需要在此时已经配置好记录器。因此,这是我在主函数中做的第一件事:

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

    var host = CreateWebHostBuilder(args).Build();
    host.Run();
}

但是,代码行 .ReadFrom.Configuration(Configuration) 需要设置配置。通常情况下,这是在 StartUp 中完成的(据我所知),但此时尚未运行。显然,我可以将我的LoggerConfiguration移到稍后,但在配置之前将调用.UseSerilog
那么,当我还没有设置它时,如何使用IConfugration 配置Serilog?

3
可能相关:https://nblumhardt.com/2020/10/bootstrap-logger/请返回翻译后的文本。 - Ruben Bartelink
1个回答

8

@RubenBartelink在评论中提到了一份非常好的资源。

这也在Serilog for ASP.NET Core文档中有所描述。

特别是两阶段初始化部分,其中指出:

Two-stage initialization

The example at the top of this page shows how to configure Serilog immediately when the application starts.

This has the benefit of catching and reporting exceptions thrown during set-up of the ASP.NET Core host.

The downside of initializing Serilog first is that services from the ASP.NET Core host, including the appsettings.json configuration and dependency injection, aren't available yet.

To address this, Serilog supports two-stage initialization. An initial "bootstrap" logger is configured immediately when the program starts, and this is replaced by the fully-configured logger once the host has loaded. To use this technique, first replace the initial CreateLogger() call with CreateBootstrapLogger():

using Serilog;
using Serilog.Events;

public class Program
{
    public static int Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
            .Enrich.FromLogContext()
            .WriteTo.Console()
            .CreateBootstrapLogger(); // <-- Change this line!

Then, pass a callback to UseSerilog() that creates the final logger:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .UseSerilog((context, services, configuration) => configuration
            .ReadFrom.Configuration(context.Configuration)
            .ReadFrom.Services(services)
            .Enrich.FromLogContext()
            .WriteTo.Console())
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

It's important to note that the final logger completely replaces the bootstrap logger: if you want both to log to the console, for instance, you'll need to specify WriteTo.Console() in both places, as the example shows.

Consuming appsettings.json configuration

Using two-stage initialization, insert the ReadFrom.Configuration(context.Configuration) call shown in the example above. The JSON configuration syntax is documented in the Serilog.Settings.Configuration README.


很棒,谢谢。我找到了类似的东西并且跟随它。那确实有所提高,但这似乎更加出色 :-) - Jakob Busk Sørensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接