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

如何解决.NET Core 6 Web API中Serilog的‘The handle is invalid’错误

解决Serilog控制台Sink抛出"The handle is invalid"异常

问题场景

基于.NET Core 6的ASP.NET Core Web API项目,使用Serilog同时输出日志到文件和控制台,偶尔触发以下异常:

Caught exception while emitting to sink Serilog.Sinks.SystemConsole.ConsoleSink: System.IO.IOException: The handle is invalid.
at System.ConsolePal.WindowsConsoleStream.Write(ReadOnlySpan`1 buffer)
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.IO.StreamWriter.Write(String value)
at System.IO.TextWriter.SyncTextWriter.Write(String value)
at Serilog.Sinks.SystemConsole.ConsoleSink.Emit(LogEvent logEvent)
at Serilog.Core.Sinks.SafeAggregateSink.Emit(LogEvent logEvent)

当前配置信息

appsettings.json中的Serilog配置

"Serilog": {
    "Using": [
      "Serilog.Sinks.Console",
      "Serilog.Sinks.File"
    ],
    "MinimumLevel": "Information",
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "AppLogs/bckLog-.log",
          "rollingInterval": "Day",
          "restrictedToMinimumLevel": "Warning"
        }
      },
      {
        "Name": "Console"
      }
    ],
    "Enrich": [
      "FromLogContext"
    ]
  }

Program.cs中的初始化代码

Serilog.Debugging.SelfLog.Enable(message => { Log.Logger?.Error(message); Console.WriteLine(message); });
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(builder.Configuration).CreateLogger();
builder.Host.UseSerilog();

解决方案

该异常核心原因是应用尝试向已失效的控制台句柄写入日志,常见于Web API以无控制台方式运行的场景(如Windows服务、IIS进程、启动后控制台窗口被关闭)。以下是几种可行解决办法:

1. 移除控制台Sink(推荐非交互式场景)

若Web API无需控制台输出(如部署到IIS、容器或Windows服务),直接删除Serilog配置中的Console Sink:
修改appsettings.json的WriteTo节点,移除Console相关项:

"WriteTo": [
  {
    "Name": "File",
    "Args": {
      "path": "AppLogs/bckLog-.log",
      "rollingInterval": "Day",
      "restrictedToMinimumLevel": "Warning"
    }
  }
]

2. 为控制台Sink添加错误处理

保留控制台输出,但通过Serilog的Safe包装器捕获Sink异常,避免影响其他日志输出:

  • 方式一:手动在Program.cs中包装Console Sink:
Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration)
    .WriteTo.Safe(Serilog.Sinks.Console.ConsoleSink(), restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information)
    .CreateLogger();
  • 方式二:通过配置文件使用Safe包装器(需先安装Serilog.Sinks.Safe包):
"WriteTo": [
  {
    "Name": "File",
    "Args": {
      "path": "AppLogs/bckLog-.log",
      "rollingInterval": "Day",
      "restrictedToMinimumLevel": "Warning"
    }
  },
  {
    "Name": "Safe",
    "Args": {
      "inner": {
        "Name": "Console"
      }
    }
  }
]

3. 仅在开发环境启用控制台Sink

通过环境变量区分开发/生产环境,仅在开发阶段启用控制台输出:
修改Program.cs的日志初始化逻辑:

var loggerConfig = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration);

if (builder.Environment.IsDevelopment())
{
    loggerConfig.WriteTo.Console();
}

Log.Logger = loggerConfig.CreateLogger();
builder.Host.UseSerilog();

同时移除appsettings.json中默认的Console Sink配置。

4. 修复SelfLog的循环调用问题

当前SelfLog代码同时调用Log.Logger?.Error(message)和Console.WriteLine(message),可能触发循环日志(Console Sink出错时,SelfLog又写入控制台)。建议将SelfLog输出到文件:

Serilog.Debugging.SelfLog.Enable(File.CreateText("AppLogs/serilog-selflog.txt"));

内容的提问来源于stack exchange,提问作者Developer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:25:22