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

使用Serilog HTTP Sink记录异常时找不到outputTemplate参数的问题

解决Serilog HTTP Sink结合Exceptions插件捕获嵌套异常的问题

首先明确:outputTemplate是Serilog顶层Logger配置的参数,不是HTTP Sink独有的。你不需要在HTTP Sink里找这个参数,而是要在全局Logger配置或者HTTP Sink的格式化器里指定,同时配合Serilog.Exceptions的解构策略来捕获嵌套InnerException。

以下是具体步骤和代码示例:

1. 确保安装必要的NuGet包

Install-Package Serilog
Install-Package Serilog.Sinks.Http
Install-Package Serilog.Exceptions
Install-Package Serilog.Sinks.Console # 可选,用于本地调试验证

2. 正确配置Logger,捕获嵌套异常

核心是启用ExceptionDestructuringPolicy来解析异常的所有细节(包括多层InnerException),再根据需求配置输出格式:

方式1:发送结构化JSON日志(推荐)

HTTP Sink默认会把日志事件序列化为JSON,包含所有结构化属性(包括Serilog.Exceptions解析出的ExceptionDetails字段,里面有完整的嵌套异常信息):

using Serilog;
using Serilog.Exceptions;

Log.Logger = new LoggerConfiguration()
    // 启用异常解构,自动捕获多层嵌套InnerException
    .Destructure.With<ExceptionDestructuringPolicy>()
    // 本地控制台输出(可选,用于验证格式)
    .WriteTo.Console(
        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception} {Properties:j}"
    )
    // 发送到远程HTTP服务器,默认传输JSON格式的结构化日志
    .WriteTo.Http("https://your-remote-log-endpoint")
    .CreateLogger();

// 测试嵌套异常
try
{
    try
    {
        int zero = 0;
        int result = 1 / zero;
    }
    catch (Exception ex)
    {
        throw new InvalidOperationException("内层异常触发外层错误", ex);
    }
}
catch (Exception ex)
{
    Log.Error(ex, "Error occured");
}

此时HTTP请求的Body会包含类似这样的JSON(简化版):

{
  "Timestamp": "2024-06-03T13:00:00.000+03:30",
  "Level": "Error",
  "MessageTemplate": "Error occured",
  "Message": "Error occured",
  "ExceptionDetails": {
    "Type": "System.InvalidOperationException",
    "Message": "内层异常触发外层错误",
    "StackTrace": "...",
    "InnerException": {
      "Type": "System.DivideByZeroException",
      "Message": "Attempted to divide by zero.",
      "StackTrace": "...",
      "InnerException": null
    }
  }
}

方式2:发送指定格式的文本日志

如果你的远程服务器要求接收纯文本格式,可以给HTTP Sink指定TextFormatter,传入你需要的输出模板:

using Serilog.Formatting.Display;

// ... 其他配置不变
.WriteTo.Http(
    requestUri: "https://your-remote-log-endpoint",
    textFormatter: new MessageTemplateTextFormatter(
        "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception} {Properties:j}"
    )
)

这种方式下,HTTP请求的Body就是你指定格式的文本,且{Exception}会自动展开所有嵌套的InnerException信息。

3. 关键说明

  • Serilog.Exceptions的ExceptionDestructuringPolicy会自动解析异常的所有嵌套层级、栈追踪、异常类型等信息,不需要额外配置就能捕获InnerException。
  • HTTP Sink本身不负责格式定义,格式由顶层的outputTemplate(针对文本输出)或序列化器(针对JSON输出)控制。
  • 如果需要自定义JSON结构,可以使用JsonFormatter并传入配置参数,调整序列化后的字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:23:14