ASP.NET Core 6.0 Web API发布后控制台空白,Serilog配置引发异常
你的Serilog配置存在两个核心问题,导致发布后程序启动失败:
配置文件路径错误或未被包含在发布包中
你手动创建ConfigurationBuilder加载appsettings.json时,没有指定文件的正确路径。调试时文件和exe在同一目录,但发布后如果项目文件没设置复制该文件到输出目录,exe所在目录会找不到appsettings.json,导致加载配置失败,Logger创建抛出未捕获异常,程序直接退出,无任何输出。Serilog初始化时机和方式错误
在ConfigureSerilog方法中手动构建配置并初始化Logger,没有复用ASP.NET Core已加载的IConfiguration(它已经处理了环境变量、命令行参数、不同环境的配置文件等),同时在AddLogging时没有正确处理Logger的生命周期,也没有添加异常捕获,导致初始化失败时无法排查问题。
步骤1:确保配置文件被包含在发布输出中
打开项目的.csproj文件,添加或修改以下配置,确保appsettings.json被复制到发布目录:
<ItemGroup> <Content Update="appsettings.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToPublishDirectory>Always</CopyToPublishDirectory> </Content> <!-- 开发环境配置文件不需要发布 --> <Content Update="appsettings.Development.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToPublishDirectory>Never</CopyToPublishDirectory> </Content> </ItemGroup>
步骤2:使用ASP.NET Core官方推荐的Serilog初始化方式
ASP.NET Core 6.0推荐在Program.cs中通过Host.UseSerilog集成Serilog,复用框架已加载的配置,避免手动构建配置的问题:
var builder = WebApplication.CreateBuilder(args); // 集成Serilog,复用框架的IConfiguration builder.Host.UseSerilog((context, loggerConfig) => { loggerConfig .ReadFrom.Configuration(context.Configuration) .Enrich.FromLogContext() // 可选:添加日志上下文信息 .WriteTo.Console(); // 确保控制台输出日志,方便排查启动问题 }); // 添加控制器服务 builder.Services.AddControllers(); var app = builder.Build(); // 可选:启用Serilog请求日志,记录接口调用信息 app.UseSerilogRequestLogging(); app.MapControllers(); try { Log.Information("API 启动成功"); app.Run(); } catch (Exception ex) { Log.Fatal(ex, "API 启动失败"); } finally { Log.CloseAndFlush(); }
如果你想保留自定义的ConfigureSerilog方法
修改方法,传入框架已有的IConfiguration,并添加异常捕获:
public static void ConfigureSerilog(IServiceCollection services, IConfiguration configuration) { Logger log = null; try { log = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .WriteTo.Console() // 强制添加控制台输出,确保启动日志能看到 .CreateLogger(); Log.Logger = log; Log.Information("API Started"); services.AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); // 指定dispose: true,让框架管理Logger的生命周期 loggingBuilder.AddSerilog(log, dispose: true); }); } catch (Exception ex) { // 如果Serilog初始化失败,用控制台输出错误 Console.WriteLine($"Serilog配置错误:{ex.Message}"); log?.Fatal(ex, "API启动失败,原因是Serilog配置错误"); throw; } }
然后在Program.cs中调用:
var builder = WebApplication.CreateBuilder(args); ConfigureSerilog(builder.Services, builder.Configuration); // 其他服务配置...
验证发布后的运行
发布后,检查exe所在目录是否存在appsettings.json,然后运行exe,此时如果配置正确,控制台会输出启动日志和托管端口;如果仍有问题,控制台会输出具体的错误信息,帮助你排查。
内容的提问来源于stack exchange,提问作者Peru

