如何覆盖 NLog ≥ v5.0 中内置的 JSON 格式化程序/JSON 转换器?

问题描述 投票:0回答:1

在我们的项目中,我们有一些类属性需要在记录时进行审查。每个要审查的属性都具有自定义属性;我们称其为

CensorMeAttribute

因此,我们想要审查的任何属性都可以实现为:

[CensorMe]
public string Secret { get; set; }

我们目前覆盖 NLog 的内置 JSON 格式化程序/转换器,以便按照 NLog 的 wiki 文章

如何使用结构化日志记录
: 提供的指南来审查 CensorMe

属性的值
  1. 我们已经实现了具有以下签名的自定义
    NLog.IJsonConverter
public class CensorJsonConverter : NLog.IJsonConverter

以及适合我们用例的逻辑。

  1. 在我们项目的
    Program.cs
    中,我们当前重写了 JSON 转换器并在此静态方法中启用 NLog 作为日志记录提供程序:
private static void AddNLog(HostBuilderContext context, ILoggingBuilder loggingBuilder)
{
    NLog.Config.ConfigurationItemFactory.Default.JsonConverter = new CensorJsonConverter();

    var config = new NLogLoggingConfiguration(context.Configuration.GetSection("NLog"));

    loggingBuilder.AddNLog(config);
}

这里,对

loggingBuilder.AddNLog(config)
的调用就是对
ILoggingBuilder.AddNLog(LoggingConfiguration)
的调用。

通过此实现,

Secret
被记录为
\"Secret\":\"***\"
而不是
\"Secret\":\"actual secret value\"
这是我们想要保留的所需日志记录输出。


将 NLog 软件包版本升级到 ≥ v5.0 后,

NLog.Config.ConfigurationItemFactory.Default.JsonConverter
已过时。解决方法消息显示:

改为使用 LogFactory.ServiceRepository.ResolveInstance(typeof(IJsonConverter))。

我在

ResolveInstance()
属性上找不到任何
LogFactory.ServiceRepository
方法。有
RegisterService()
方法,该方法注册单例对象的实例以在 NLog 中使用(
ServiceRepository
文档
)。因此我尝试的是更换线路

NLog.[...].JsonConverter = new CensorJsonConverter();

致电

config.LogFactory.ServiceRepository.RegisterService([...]);

如下:

private static void AddNLog(HostBuilderContext context, ILoggingBuilder loggingBuilder)
{
    var config = new NLogLoggingConfiguration(context.Configuration.GetSection("NLog"));

    config.LogFactory.ServiceRepository.RegisterService(
        typeof(CensorJsonConverter),
        new CensorJsonConverter());

    loggingBuilder.AddNLog(config);
}

通过此实现,

Secret
将记录为
\"Secret\":\"actual secret value\"
。这不是所需的日志输出。


如何在不设置现在(NLog ≥ v5.0)过时的情况下覆盖内置 JSON 转换器

NLog.Config.ConfigurationItemFactory.Default.JsonConverter

或者是否有另一种方法可以在使用或不使用 NLog 的情况下实现对

CensorMe

 属性的类似处理?

.net logging nlog
1个回答
0
投票
你可以这样做:

private static void AddNLog(HostBuilderContext context, ILoggingBuilder loggingBuilder) { LogManager.Setup() .SetupExtensions(e => e.RegisterNLogWeb().RegisterConfigSettings(context.Configuration)) .SetupSerialization(s => s.RegisterJsonConverter(new CensorJsonConverter()) .LoadConfigurationFromSection(context.Configuration); loggingBuilder.AddNLogWeb(); }
请注意,如果您将秘密包装在继承自 

IFormattable

 的自定义类型中,那么 NLog 将默认忽略属性并只执行 
ToString()
 (无需自定义 JsonConverter)

public struct SecretValue : IFormattable { public string Value; string IFormattable.ToString(string format, IFormatProvider formatProvider) => ToString(); public override string ToString() => string.IsNullOrEmpty(Value) ? "" : "*****"; }
另请参阅:

https://github.com/NLog/NLog/wiki/How-to-use-structed-logging#customize-object-reflection

© www.soinside.com 2019 - 2024. All rights reserved.