Как сделать, чтобы JLLout выводил типы объектов NLog? - PullRequest
0 голосов
/ 25 октября 2019

Я регистрирую данные моего приложения, используя 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 голосов
/ 02 ноября 2019

NLog автоматически вводит свойство Type для объектов Exception. Но вы можете переопределить 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;
...