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

当对象含带异常的属性时,如何使用NLog结构化日志?

问题描述

使用NLog结构化日志记录对象时触发异常:System.IO.FileNotFoundException: 'Could not find file 'C:\Non-Existent-File'.',该异常来自FileInfo的Length属性访问。需求是让NLog忽略该属性,或仅记录Bar.ToString()结果。

代码示例:

public class Foo()
{
     public FileInfo Bar { get; set; } = new FileInfo(@"C:\Non-Existent File");
     // 更多属性
}

public class App
{
    private static readonly Logger MyLogger = LogManager.GetLogger("MyLogger");

    public App()
    {
        MyLogger.Info("Foo is [{@foo}]", new Foo());
    }
}

已尝试设置JsonLayout的MaxRecursionLimit=0,但未解决问题。

解决方案

方法1:自定义类型转换器处理FileInfo

注册自定义转换器,让NLog序列化FileInfo时仅输出路径字符串,避免访问触发异常的属性:

// 程序启动时执行注册
NLog.Config.ConfigurationItemFactory.Default.TypeConverters.RegisterConverter<FileInfo>(new FileInfoConverter());

public class FileInfoConverter : NLog.LayoutRenderers.Wrappers.TypeConverterWrapper
{
    protected override object Convert(object value)
    {
        if (value is FileInfo fileInfo)
        {
            return fileInfo.ToString(); // 仅返回文件路径字符串
        }
        return base.Convert(value);
    }
}

方法2:通过配置过滤属性

排除触发异常的单个属性

在NLog配置的JsonLayout中,使用excludeProperties指定忽略FileInfo的Length属性:

<layout xsi:type="JsonLayout">
  <attribute name="foo" encode="false" layout="${json-encode:${event-properties:foo}:excludeProperties=Bar.Length}" />
</layout>

手动记录Bar的字符串表示

如果不需要Bar的其他属性,直接在日志调用时传入Bar.ToString():

// 修改日志调用代码
MyLogger.Info("Foo is [Bar: {bar}, ...]", foo.Bar.ToString());

方法3:全局对象转换配置

通过NLog全局序列化配置,指定FileInfo仅序列化指定属性(如FullName),避免访问异常属性:

// 全局配置(程序启动时执行)
LogManager.Setup().SetupSerialization(s =>
{
    s.RegisterObjectTransformation<FileInfo>(fileInfo => new { FullName = fileInfo.FullName });
});

内容的提问来源于stack exchange,提问作者JasonC

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 15:28:17