无法使用 Serilog 和 .Net Core 5 捕获实例化错误

Cannot catch instantiations errors with Serilog and .Net Core 5

我有一个带有 Serilog 的 .Net Core 5 应用程序。我正在测试错误日志记录,并且我有一个无法实例化的 class,因为我在 DI 注册中注释掉了一些服务。 这是我的 Program.cs 文件:

public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
           .Enrich.FromLogContext()
           .WriteTo.File("Logs/Startup.txt", Serilog.Events.LogEventLevel.Verbose)
           .CreateLogger();
        try
        {
            Log.Information("Starting up");
            CreateHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Application start-up failed");
            Environment.Exit(1);
        }
    }
public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
                    .ReadFrom.Configuration(hostingContext.Configuration))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });

Startup.txt 文件中,我只看到 Information 而不是错误。想法?

您遗漏的最明显的事情是 try/finally 中的 Log.CloseAndFlush() eta: 注意 Environment.Exit() 会使它变得无关紧要 - 这是首先要解决的问题。

Nick 写了一篇关于如何正确地端到端执行此操作的好文章:

您的初始记录器正在使用 File() 但您稍后调用 UseSerilog(callback) 这将用配置文件中的任何内容覆盖它。

CreateBootstrapLogger() 通过允许合并启动和以后的应用程序日志来解决所有这些问题:

public static int Main(string[] args)
{
    Log.Logger = new LoggerConfiguration()
       .Enrich.FromLogContext()
       .WriteTo.File("Logs/Log.txt")  // <-- No longer need a separate startup log
       .CreateBootstrapLogger();  // <-- Change this line

    try
    {
        Log.Information("Starting up");
        CreateHostBuilder(args).Build().Run();
    }
    catch (Exception ex)
    {
        Log.Fatal(ex, "Application start-up failed");
        return 1;  // <-- Change this line
    }
    finally  // <-- Add this block
    {
        Log.CloseAndFlush();
    }

    return 0;  // <-- Add this line
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
            .WriteTo.File("Logs/Log.txt") // <-- Add this line
            .ReadFrom.Configuration(hostingContext.Configuration))
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

如果您真的不想在同一个接收器中启动和定期记录事件,您可以改为为启动初始化一个单独的记录器:

public static int Main(string[] args)
{
    using var startup = new LoggerConfiguration()
       .Enrich.FromLogContext()
       .WriteTo.File("Logs/Startup.txt")
       .CreateLogger();

    try
    {
        startup.Information("Starting up");
        CreateHostBuilder(args).Build().Run();
    }
    catch (Exception ex)
    {
        startup.Fatal(ex, "Application start-up failed");
        return 1;  // <-- Change this line
    }

    return 0;  // <-- Add this line
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
            .ReadFrom.Configuration(hostingContext.Configuration))
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

(我仍然建议尽可能避免 Environment.Exit()。)