无法使用 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()
。)
我有一个带有 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()
。)