如何用NLog实现控制台仅打印ex.Message,文件输出完整异常?
问题描述
将整个异常对象打印到控制台会显得混乱,能否实现仅将ex.Message打印到控制台,而将完整异常对象(包括堆栈信息)输出到文件,或在使用Debug、Trace级别日志时输出完整异常?
假设异常ex内容为:Blah blah..at System.Number.StringToNumber(String... str...:line 269
当前代码如下:
catch (Exception ex) { _log.Error($"Failed to... Error: {ex}"); }
需要实现:控制台打印Failed to... Error: Blah blah,文件或使用_log.Debug/_log.Trace时打印完整异常信息。
请问是否需要编写自定义Console目标来处理消息参数,还是有更简便的实现方式?
解决方案
不需要自定义Console目标,利用日志框架的异常重载方法就能轻松实现,这是最简便的方式:
修改日志调用方式
不要直接把异常拼进字符串里,而是用日志框架提供的带异常参数的重载方法。以常见的NLog、Serilog为例:catch (Exception ex) { _log.Error(ex, "Failed to..."); }配置不同日志目标的输出模板
对于Console目标,配置输出模板只包含消息和异常的
Message部分:<!-- NLog示例配置 --> <target name="console" xsi:type="Console"> <layout>${message} Error: ${exception:format=Message}</layout> </target>或者Serilog的代码配置:
.WriteTo.Console(outputTemplate: "{Message} Error: {Exception:Message}{NewLine}")对于File目标或Debug/Trace级别,配置输出模板包含完整异常信息(堆栈、内部异常等):
<!-- NLog文件目标配置 --> <target name="file" xsi:type="File" fileName="logs/logfile.txt"> <layout>${message} ${exception:format=ToString}</layout> </target> <!-- Debug目标配置 --> <target name="debug" xsi:type="Debug"> <layout>${message} ${exception:format=ToString}</layout> </target>Serilog的Debug输出配置:
.WriteTo.Debug(outputTemplate: "{Timestamp:HH:mm:ss} [{Level:u3}] {Message}{NewLine}{Exception}")
核心原理
日志框架的异常重载会把异常对象单独传递,而非直接拼接成字符串。这样就能在不同目标的模板中,通过{exception:format=xxx}语法灵活控制异常输出:format=Message:仅输出异常消息format=ToString:输出完整异常信息(含堆栈)- 还可以自定义格式,比如
format=Message,StackTrace只输出消息和堆栈
内容的提问来源于stack exchange,提问作者theateist
相关产品推荐
相关产品推荐

