如何在NLog中排除DBUpdateException的某一Entry属性不被日志记录
问题描述
我有一个包含byte[]属性的实体,当触发DbUpdateException时,该异常会被写入JSON日志。由于DbUpdateException包含Entries列表,其中包含每个条目/实体的所有属性,我想知道是否有办法阻止该byte[]属性被记录。我使用的是NLog 5.2.5(JsonLayout)和EF Core 5。
解决方案
方法1:自定义NLog对象转换器过滤属性
NLog的JsonLayout支持通过自定义对象转换器,针对性处理DbUpdateException的序列化逻辑,过滤掉byte[]属性:
- 创建自定义转换器类:
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; } }
- 在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[]属性被过滤,可以给实体属性加自定义特性,再在转换器中识别过滤:
- 定义日志忽略特性:
[AttributeUsage(AttributeTargets.Property)] public class IgnoreInLogAttribute : Attribute { }
- 在实体的目标属性上标记:
public class YourEntity { public int Id { get; set; } [IgnoreInLog] public byte[] BinaryData { get; set; } // 其他属性... }
- 修改转换器的过滤逻辑:
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
相关产品推荐
相关产品推荐

