如何让Serilog控制台Sink仅记录异常消息而非堆栈跟踪?
如何让Serilog控制台Sink仅记录异常消息(无需额外依赖)
以下两种方案均无需引入Serilog.Expressions等额外依赖,仅使用Serilog核心及控制台Sink即可实现:
方案一:自定义文本格式化器
通过包装默认的消息模板格式化器,在日志输出前替换异常对象为仅保留消息的实例,从而避免输出堆栈跟踪。
首先实现自定义格式化器:
using Serilog; using Serilog.Events; using Serilog.Formatting; using System.IO; public class ConsoleExceptionMessageFormatter : ITextFormatter { private readonly ITextFormatter _innerFormatter; public ConsoleExceptionMessageFormatter(ITextFormatter innerFormatter) { _innerFormatter = innerFormatter; } public void Format(LogEvent logEvent, TextWriter output) { if (logEvent.Exception != null) { // 创建仅包含异常消息的新实例,丢弃堆栈信息 var messageOnlyException = new Exception(logEvent.Exception.Message); logEvent = new LogEvent( logEvent.Timestamp, logEvent.Level, messageOnlyException, logEvent.MessageTemplate, logEvent.Properties); } _innerFormatter.Format(logEvent, output); } }
然后配置Serilog时使用这个格式化器:
Log.Logger = new LoggerConfiguration() .WriteTo.Console(new ConsoleExceptionMessageFormatter( new MessageTemplateTextFormatter("{Timestamp:HH:mm:ss} [{Level:u3}] {Message:lj}{Exception}{NewLine}"))) .CreateLogger();
方案二:通过解构转换简化输出
利用Serilog的解构配置,将Exception类型转换为仅包含Message的结构,再在输出模板中直接引用该属性。
配置示例:
Log.Logger = new LoggerConfiguration() // 解构Exception对象,仅保留Message属性 .Destructure.ByTransforming<Exception>(ex => new { ex.Message }) // 在模板中直接输出解构后的消息 .WriteTo.Console(outputTemplate: "{Timestamp:HH:mm:ss} [{Level:u3}] {Message:lj}{@Exception.Message}{NewLine}") .CreateLogger();
注意事项
- 方案一完全兼容原有
{Exception}模板语法,输出风格和原有控制台日志一致,只是去掉了堆栈; - 方案二更简洁,但需要调整模板为
{@Exception.Message}来引用解构后的属性; - 两种方案都不会影响其他Sink(如文件、Seq)的异常输出,这些Sink仍会记录完整的异常堆栈。
内容的提问来源于stack exchange,提问作者lonix
相关产品推荐
相关产品推荐

