Serilog 3.4与ASP.NET Core 2.1通过配置初始化日志仅输出3行就中断
问题原因
你遇到的问题是两种初始化方式的生效范围、时机差异导致的,核心有3个原因:
- 你在WebHost builder中通过lambda配置Serilog的方式,仅将Serilog注册为ASP.NET Core内置
ILogger<T>接口的实现,不会给Serilog静态类Log.Logger赋值。如果你的业务代码中直接使用Log.Information/Log.Debug等静态方法写日志,这部分日志会全部丢失,仅能看到ASP.NET Core框架启动时通过ILogger<T>输出的3行左右启动日志。 - 配置文件中缺少
Enrich.FromLogContext的配置,和你纯代码初始化的逻辑不一致,如果你有依赖日志上下文的输出会被过滤。 - 纯代码初始化时你在
finally块调用了Log.CloseAndFlush()保证缓存日志落盘,但是WebHost builder配置的方式没有加这个逻辑,程序退出时部分缓存的日志可能丢失。另外你纯代码初始化时最小日志级别是Debug,而配置文件里默认是Information,如果你业务日志级别是Debug也会被过滤。
修复方案
方案一:保留配置文件,调整初始化时机(推荐)
既能用配置文件管理Serilog规则,又能覆盖启动全生命周期的日志:
- 先在
appsettings.json的Serilog节点补充Enrich配置,对齐纯代码的初始化逻辑:
"Serilog": { "MinimumLevel": { // 如果需要输出Debug日志可以把Default改成Debug "Default": "Information", "Override": { "Microsoft": "Warning", "System": "Warning" } }, "Using": [ "Serilog.Sinks.File" ], // 新增Enrich配置 "Enrich": [ "FromLogContext" ], "WriteTo": [ { "Name": "File", "Args": { "outputTemplate": "[{Level}] {Timestamp:yyyy-MM-ddTHH:mm:sszzz} - {Message:lj}{NewLine}{Exception}", "path": "/var/log/somedir/somefile.log", // 可选:调试阶段可以关闭缓冲区避免日志丢失 "buffered": false } } ] }
- 调整Main方法的初始化逻辑,提前加载配置初始化静态Logger:
public static int Main(string[] args) { // 提前加载配置文件 var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddEnvironmentVariables() .Build(); // 用配置初始化静态Logger Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .CreateLogger(); try { Log.Information("Some service is starting"); CreateWebHostBuilder(args).Build().Run(); return 0; } catch(Exception ex) { Log.Fatal(ex, "Host terminated unexpectedly"); return 1; } finally { Log.CloseAndFlush(); } } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseSerilog(); // 不需要再重复配置
方案二:不使用静态Log类
如果你的业务代码全部依赖注入的ILogger<T>写日志,不需要用静态Log类,只需要修改两个点即可:
- 在
appsettings.json的Serilog节点补充"Enrich": [ "FromLogContext" ]配置(参考方案一的配置修改) - 调整
UseSerilog的调用,补充参数适配:
WebHost.CreateDefaultBuilder(args) .UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration .ReadFrom.Configuration(hostingContext.Configuration), writeToProviders: false)
内容的提问来源于stack exchange,提问作者psparago
相关产品推荐
相关产品推荐

