如何配置Serilog使控制台输出异常Message,文件输出完整堆栈?
解决方案
要实现控制台接收器输出异常的Message,文件接收器输出完整的ToString(),只需通过Serilog.Expressions的条件表达式和自定义模板分支分别处理两种接收器的异常输出逻辑,具体修改如下:
1. 重构模板生成逻辑
将原有的GetBaseTemplateString改为可接收异常输出模板参数的方法,让控制台和文件可以传入不同的异常输出表达式:
private static string GetBaseTemplateString(string exceptionTemplate) { var scope = LogProperty.Scope; return $"{{#if {scope} is not null}}{{{scope}}}: {{#end}}" + "{@m}\n" + exceptionTemplate; }
2. 分别定义控制台和文件的异常输出模板
- 控制台模板加入空值判断,仅在存在异常时输出
Message内容 - 文件模板保留原逻辑,输出完整异常信息(包含栈跟踪等)
修改后的接收器模板方法:
private static ExpressionTemplate GetConsoleTemplate() { // 控制台仅输出异常Message,避免无异常时输出null var exceptionTemplate = "{#if @x is not null}{@x.Message}{#end}"; var template = "[{@l:u3}] " + GetBaseTemplateString(exceptionTemplate); return new ExpressionTemplate(template, theme: TemplateTheme.Code); } private static ExpressionTemplate GetFileTemplate() { // 文件输出完整异常详情(自动调用ToString()) var exceptionTemplate = "{@x}"; var template = "[{@t:HH:mm:ss} {@l:u3}] " + GetBaseTemplateString(exceptionTemplate); return new ExpressionTemplate(template); }
3. 原日志配置保持不变
你的原LoggerConfiguration代码无需修改,模板逻辑的调整已经适配了两个接收器的需求:
return new LoggerConfiguration() .MinimumLevel.Is(LogEventLevel.Debug) .WriteTo.Console(GetConsoleTemplate(), _levelSwitch.MinimumLevel) .WriteTo.File(GetFileTemplate(), logPath.FullName) .Enrich.FromLogContext() .CreateLogger();
关键说明
- Serilog.Expressions中
@x代表日志事件的异常对象,通过@x.Message可直接访问异常的Message属性 - 加入
{#if @x is not null}条件判断,避免无异常时输出无效字符 - 文件接收器使用
{@x}时,Serilog会自动调用异常的ToString()方法输出完整栈跟踪信息
内容的提问来源于stack exchange,提问作者void.pointer
相关产品推荐
相关产品推荐

