使用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
相关产品推荐
相关产品推荐

