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

如何配置NLog目标的Layout以获取异常的原始序列化数据?

获取NLog中异常的原始序列化数据

好问题!默认的${exception:format=toString,Data}会输出格式化后的字符串,丢失了异常对象的原始结构和类型信息。要获取类似Visual Studio异常窗口里的原始数据结构,你可以试试以下几种配置方式:

方法1:用JsonLayout序列化完整异常对象

这是最直接的方式,NLog的JsonLayout可以直接将异常对象序列化为JSON,保留所有原始属性(包括嵌套的内部异常、Data字典的键值对等)。

示例配置:

<target name="jsonExceptionTarget" xsi:type="File" fileName="exceptions-raw.json">
  <layout xsi:type="JsonLayout">
    <!-- 序列化完整异常对象,自动包含所有属性 -->
    <attribute name="RawException" encode="false">
      <layout xsi:type="JsonLayout" includeAllProperties="true" maxRecursionLimit="10" />
    </attribute>
    <!-- 可选:添加其他日志元数据 -->
    <attribute name="Timestamp" value="${date:format=o}" />
    <attribute name="LogLevel" value="${level}" />
  </layout>
</target>

如果需要更精细控制要包含的属性,也可以手动指定:

<attribute name="RawException" encode="false">
  <layout xsi:type="JsonLayout" maxRecursionLimit="10">
    <property name="ExceptionType" value="${exception:format=Type}" />
    <property name="Message" value="${exception:format=Message}" />
    <property name="StackTrace" value="${exception:format=StackTrace}" />
    <property name="Data" value="${exception:format=Data}" />
    <property name="InnerExceptions" value="${exception:format=InnerException:maxInnerExceptionLevel=10}" />
  </layout>
</attribute>

这种方式生成的JSON结构和Visual Studio异常窗口展示的原始数据几乎一致,能保留所有类型信息(比如Data里的数值、布尔值不会被转成字符串)。

方法2:自定义布局渲染器实现完全控制

如果需要更灵活的序列化逻辑(比如用Newtonsoft.Json而非System.Text.Json,或者自定义序列化规则),可以写一个自定义NLog布局渲染器:

using NLog;
using NLog.LayoutRenderers;
using System.Text.Json;

[LayoutRenderer("exception-raw")]
public class RawExceptionLayoutRenderer : LayoutRenderer
{
    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
        if (logEvent.Exception == null) return;

        var serializerOptions = new JsonSerializerOptions
        {
            WriteIndented = true,
            ReferenceHandler = ReferenceHandler.IgnoreCycles, // 处理循环引用
            MaxDepth = 10 // 匹配你的maxInnerExceptionLevel设置
        };

        var rawJson = JsonSerializer.Serialize(logEvent.Exception, serializerOptions);
        builder.Append(rawJson);
    }
}

然后在NLog配置中注册这个扩展,并使用${exception-raw}:

<extensions>
  <!-- 替换成你的程序集名称 -->
  <add assembly="YourApplicationAssembly" />
</extensions>

<target name="rawExceptionTarget" xsi:type="File" fileName="raw-exceptions.log">
  <layout>${date:format=yyyy-MM-dd HH:mm:ss} - ${exception-raw}</layout>
</target>

注意事项

  • 记得设置maxRecursionLimit或maxInnerExceptionLevel来避免因深层嵌套异常导致的序列化问题。
  • 如果使用JsonLayout,encode="false"很重要,否则JSON会被转义成字符串,失去原始结构。

内容的提问来源于stack exchange,提问作者Bram Van Den Bossche

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:58:02