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

如何在NLog中排除DBUpdateException的某一Entry属性不被日志记录

问题描述

我有一个包含byte[]属性的实体,当触发DbUpdateException时,该异常会被写入JSON日志。由于DbUpdateException包含Entries列表,其中包含每个条目/实体的所有属性,我想知道是否有办法阻止该byte[]属性被记录。我使用的是NLog 5.2.5(JsonLayout)和EF Core 5。

解决方案

方法1:自定义NLog对象转换器过滤属性

NLog的JsonLayout支持通过自定义对象转换器,针对性处理DbUpdateException的序列化逻辑,过滤掉byte[]属性:

  1. 创建自定义转换器类:
using NLog;
using System.Linq;
using Microsoft.EntityFrameworkCore;

public class FilteredDbUpdateExceptionRenderer : IJsonConverter
{
    public object ConvertToJson(object value)
    {
        if (value is DbUpdateException dbEx)
        {
            return new
            {
                dbEx.Message,
                dbEx.InnerException,
                Entries = dbEx.Entries.Select(entry =>
                {
                    var entityType = entry.Entity.GetType();
                    // 过滤所有byte[]类型的属性
                    var filteredProps = entityType.GetProperties()
                        .Where(p => p.PropertyType != typeof(byte[]))
                        .ToDictionary(p => p.Name, p => p.GetValue(entry.Entity));
                    return new
                    {
                        EntityType = entityType.Name,
                        Properties = filteredProps
                    };
                })
            };
        }
        // 非目标类型直接返回原对象
        return value;
    }
}
  1. 在NLog配置中注册并使用该转换器:
<nlog>
    <extensions>
        <add assembly="你的程序集名称"/> <!-- 替换为包含自定义类的程序集名 -->
    </extensions>
    <targets>
        <target name="jsonFile" xsi:type="File" fileName="logs/log.json">
            <layout xsi:type="JsonLayout">
                <attribute name="exception" layout="${exception:format=ToString}" />
                <converters>
                    <add type="你的命名空间.FilteredDbUpdateExceptionRenderer" />
                </converters>
            </layout>
        </target>
    </targets>
    <rules>
        <logger name="*" minlevel="Error" writeTo="jsonFile" />
    </rules>
</nlog>

方法2:通过特性标记指定忽略的属性

如果需要更精准地控制哪些byte[]属性被过滤,可以给实体属性加自定义特性,再在转换器中识别过滤:

  1. 定义日志忽略特性:
[AttributeUsage(AttributeTargets.Property)]
public class IgnoreInLogAttribute : Attribute { }
  1. 在实体的目标属性上标记:
public class YourEntity
{
    public int Id { get; set; }
    [IgnoreInLog]
    public byte[] BinaryData { get; set; }
    // 其他属性...
}
  1. 修改转换器的过滤逻辑:
var filteredProps = entityType.GetProperties()
    .Where(p => !p.IsDefined(typeof(IgnoreInLogAttribute)))
    .ToDictionary(p => p.Name, p => p.GetValue(entry.Entity));

方法3:配置层面直接过滤固定名称属性(简单场景)

如果要过滤的byte[]属性名称固定,也可以直接在NLog配置中通过条件排除,适合属性名称明确且不变的场景:

<layout xsi:type="JsonLayout">
    <attribute name="exception" layout="${exception:format=ToString}" />
    <!-- 假设要过滤的属性名为BinaryData -->
    <attribute name="entries" layout="${exception:format=Entries}" when="not contains('${exception:format=Entries}', 'BinaryData')" />
</layout>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 12:33:19