简体   繁体   中英

How to make NLog's JsonLayout output object types?

I'm logging my application's data using NLog, with the JsonLayout layout. The output I'm getting for my objects doesn't include the type, and I'd like it to log the types with the rest of the JSON. The collection I'm logging has items of various types, and I'd like the log to specifically state what those are, without the reader having to infer which type it is based on its properties.

Here's what I'm getting

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

What I'd like to log is something like JSON.Net's output:

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

How do I achieve this? I'm not set on using JsonLayout if there's something else that'd do equally well.

NLog automatically injects a Type-property for Exception-objects. But you can override the NLog IJsonConverter so it happens for all objects:

You can override the JSON conversion like this:

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);
    }
}

Then you can activate the special JsonConverter:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM