如何制作NLog的JsonLayout输出对象类型?

时间:2019-10-25 15:14:26

标签: c# json logging nlog

我正在使用NLog和JsonLayout布局记录应用程序的数据。我为对象获取的输出不包括类型,我希望它使用其余的JSON记录类型。我正在记录的集合具有各种类型的项目,我希望该日志明确说明它们是什么,而读者不必根据其属性来推断它是哪种类型。

这就是我要得到的

"things": [
    [
        {
            "PropertyA": 1,
            "PropertyB": 2,
        }
    ],
    [],
    []
]

我想要记录的是类似JSON.Net的输出:

"things": [
    [
        {
            "$type": "MyNamespace.MyObject, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1234567890123456",
            "PropertyA": 1,
            "PropertyB": 2,
        }
    ],
    [],
    []
]

我该如何实现?如果还有其他同样可以做得很好的方法,我就不会使用JsonLayout。

1 个答案:

答案 0 :(得分:0)

NLog自动为异常对象注入类型属性。但是您可以覆盖NLog IJsonConverter,以便所有对象都可以使用它。

您可以像这样覆盖JSON转换:

internal class JsonLogTypeSerializer : NLog.IJsonConverter
{
    private NLog.IJsonConverter _originalConverter;
    public JsonLogModelSerializer(NLog.IJsonConverter originalConverter)
    {
        _originalConverter = originalConverter;
    }

    /// <summary>Serialization of an object into JSON format.</summary>
    /// <param name="value">The object to serialize to JSON.</param>
    /// <param name="builder">Output destination.</param>
    /// <returns>Serialize succeeded (true/false)</returns>
    public bool SerializeObject(object value, System.Text.StringBuilder builder)
    {
        if ( Convert.GetTypeCode(value) == TypeCode.Object
          && !(value is Exception)
          && !(value is IFormattable)
          && !(value is IEnumerable)
          && !value.GetType().IsValueType)
        {
            builder.Append("\"Type\": \"").Append(value.GetType().ToString()).Append("\" ");
        }

        return _originalConverter.SerializeObject(value, builder);
    }
}

然后您可以激活特殊的JsonConverter:

var oldJsonConverter = NLog.Config.ConfigurationItemFactory.Default.JsonConverter;
var newConverter = new JsonLogTypeSerializer(oldJsonConverter);
NLog.Config.ConfigurationItemFactory.Default.JsonConverter = newConverter;