升级Serilog 7后单文件发布的.NET7控制台应用为何启动失败?
控制台应用此前运行正常,近期更新所有NuGet包(包括将Serilog.AspNetCore从6.1.0升级至7.0.0)并重新部署后,抛出如下未处理异常:
Unhandled exception. System.InvalidOperationException: No Serilog:Using configuration section is defined and no Serilog assemblies were found. This is most likely because the application is published as a single-file.
当前使用.NET 7.0,勾选了「生成单文件(Produce single file)」选项(此前可正常工作),希望继续使用该选项。以下是Serilog配置代码及配置节:
// Configure Serilog string logFormat = "[{Timestamp:yyyy-MM-dd hh:mm:ss tt}][{Level:u3}] {Message:lj}{NewLine}{Exception}"; Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(appServices.Configuration) .WriteTo.Console(LogEventLevel.Verbose, logFormat) .WriteTo.File(LogFile, LogEventLevel.Verbose, logFormat) .WriteTo.List(LogEvents) .CreateLogger();
配置节:
"Serilog": { "MinimumLevel": { "Default": "Information", "Override": { "Microsoft": "Warning", "System": "Warning" } } }
请问Serilog 7版本中的哪些变更可能导致该问题?
这个问题由Serilog 7.x针对单文件发布场景的加载逻辑变更引发:
移除默认自动程序集扫描行为:Serilog 6.x及更早版本会自动扫描当前应用域内的程序集,加载Sink、Enricher等扩展组件。但7.x版本为优化单文件发布下的启动性能、减少无效资源扫描,默认关闭了该自动扫描机制,要求显式指定需加载的Serilog组件程序集。
单文件发布的程序集加载限制:应用打包为单文件时,所有依赖程序集被嵌入到单个可执行文件中,常规程序集扫描无法直接定位Serilog相关扩展组件(比如你用到的Serilog.Sinks.Console、Serilog.Sinks.File),而7.x不再自动适配该场景,因此触发异常。
解决办法任选其一即可:
- 代码中显式声明所需程序集
在LoggerConfiguration链式调用中添加Using方法,指定用到的Sink所在程序集:
Log.Logger = new LoggerConfiguration() .ReadFrom.Configuration(appServices.Configuration) .Using<Serilog.Sinks.Console.ConsoleSink>() // 声明Console Sink程序集 .Using<Serilog.Sinks.File.FileSink>() // 声明File Sink程序集 .WriteTo.Console(LogEventLevel.Verbose, logFormat) .WriteTo.File(LogFile, LogEventLevel.Verbose, logFormat) .WriteTo.List(LogEvents) .CreateLogger();
- 配置文件中添加Serilog:Using节
在appsettings.json的Serilog配置块中添加Using数组,列出所有用到的Serilog组件程序集名称:
"Serilog": { "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], "MinimumLevel": { "Default": "Information", "Override": { "Microsoft": "Warning", "System": "Warning" } } }
两种方式都能让Serilog在单文件发布场景下正确定位所需组件,解决异常问题。
内容的提问来源于stack exchange,提问作者Jonathan Wood

