首页 > 解决方案 > 无法使用 Serilog 和 .Net Core 5 捕获实例化错误

问题描述

我有一个带有 Serilog 的 .Net Core 5 应用程序。我正在测试错误日志,并且我有一个无法实例化的类,因为我在 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错误而不是错误。想法?

标签: asp.net-coreserilogasp.net-core-5.0serilog-sinks-file

解决方案


您的初始记录器正在使用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()。)


推荐阅读