You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6 Web应用如何实现Shutdown Hook记录终止日志?

解决ASP.NET Core 6中Serilog无法记录应用终止事件的问题

问题原因

  1. 事件触发条件错误:在Visual Studio的IIS Express宿主环境下,关闭浏览器标签页不会直接终止应用——ASP.NET Core应用会保持 idle 状态,直到超时回收或手动停止调试。只有手动点击调试工具栏的「停止」按钮,或控制台宿主下按Ctrl+C,才会触发ApplicationStopping和ApplicationStopped事件。
  2. Serilog日志未及时刷新:异步写入的日志 sink(如文件、控制台)可能在应用终止前未完成写入,导致日志丢失。

解决方案

1. 正确触发终止事件

在Visual Studio中测试时,不要通过关闭浏览器终止应用,而是:

  • 点击调试工具栏的「停止」按钮(▶️旁边的方形按钮)
  • 若使用控制台宿主(通过dotnet run启动),按Ctrl+C组合键

2. 配置Serilog确保日志写入完整

在应用启动时配置Serilog,并在关闭事件中手动刷新日志,避免丢失:

var builder = WebApplication.CreateBuilder(args);

// 配置Serilog,替换为你的日志输出目标
builder.Host.UseSerilog((context, config) =>
{
    config.WriteTo.Console()
          .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day)
          .Enrich.FromLogContext();
});

// 注册服务
builder.Services.AddControllers();

var app = builder.Build();

var logger = app.Services.GetRequiredService<ILogger<Program>>();

// 注册应用生命周期事件
app.Lifetime.ApplicationStarted.Register(() =>
{
    logger.LogInformation("应用已启动,开始运行");
});

app.Lifetime.ApplicationStopping.Register(() =>
{
    logger.LogInformation("应用进入关闭流程");
    // 手动刷新Serilog日志,确保所有待写入日志完成
    Log.CloseAndFlush();
});

app.Lifetime.ApplicationStopped.Register(() =>
{
    // 此事件触发时部分服务已释放,建议直接使用Serilog静态类
    Log.Information("应用已完全终止");
    Log.CloseAndFlush();
});

// 中间件配置
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

3. 优先使用ApplicationStopping记录关键日志

ApplicationStopped事件触发时,应用的服务容器已开始释放,部分依赖可能不可用。建议将核心的关闭日志放在ApplicationStopping事件中,此阶段服务仍处于可用状态。

内容的提问来源于stack exchange,提问作者Green Grasso Holm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:23:31