将NLog属性设置为JSON? [英] Layout NLog properties as JSON?

查看:321
本文介绍了将NLog属性设置为JSON?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚如何将LogEventInfo对象中的所有属性记录到JSON格式的字符串中.根据 github上的问题,我试图做这样的事情:

I am trying to figure out how to log all the properties in a LogEventInfo object to a JSON-formatted string. Per the issue on github, I tried to do something like this:

<target xsi:type="ColoredConsole" name="coloredConsole">
  <layout xsi:type="JsonLayout">
    <attribute name="timestamp" layout="${longdate}"/>
    <attribute name="level" layout="${level:uppercase=true}"/>
    <attribute name="exception" layout="${onexception:${exception:format=tostring}}" />
    <attribute name="properties" encode="false">
      <layout type="JsonLayout">
        <attribute name="properties" layout="${all-event-properties}" />
      </layout>
    </attribute>
  </layout>
</target>

...但不幸的是,我的属性包含复杂的对象(我有两个属性,名称分别为"properties"和"tags",其中"properties"是IDictionary<string, object>,"tags"是IList<string> in LogEventInfo.Properties属性),只是不进行序列化.我最终得到类似于以下内容的内容:

... but unfortunately, my properties contain complex objects (I have two properties with the names of "properties" and "tags", where "properties" is a IDictionary<string, object> and "tags" is an IList<string> in the LogEventInfo.Properties property) that simply do not serialize. I end up with something resembling this:

{ "timestamp": "2017-05-18 08:41:28.7730", "level": "INFO", "properties": { "properties": "properties=System.Collections.Generic.Dictionary`2[System.String,System.Object], tags=System.Collections.Generic.List`1[System.String]" } }

我期望(并希望)一个序列化的JSON字典,该字典可以为我提供日志消息的上下文,但是显然那不是我所得到的.

I was expecting (and hoping for) a serialized JSON dictionary that would give me the context of the log message, but clearly that is not what I am getting.

如何正确序列化LogEventInfo对象中的属性?

How can I properly serialize the properties in my LogEventInfo object?

推荐答案

好吧,NLog中似乎有一个错误,所以我有点自己制作了渲染器.这就是我所做的.首先,我使用JSON.NET进行了扩展:

Well, it looks like there's a bug in NLog, so I kinda made my own renderer. Here's what I did. First, I made an extension method using JSON.NET:

public static string ToJson(this object obj, bool format = false, string dateFormat = null)
{
    var settings = new JsonSerializerSettings
    {
        NullValueHandling = NullValueHandling.Ignore
    };

    if (!String.IsNullOrWhiteSpace(dateFormat))
    {
        settings.Converters = new List<JsonConverter>
        {
            new IsoDateTimeConverter {DateTimeFormat = dateFormat}
        };

        return JsonConvert.SerializeObject(obj, format ? Formatting.Indented : Formatting.None, settings);
    }

    return JsonConvert.SerializeObject(obj, format ? Formatting.Indented : Formatting.None, settings);
}

...接下来,我像这样创建了一个LayoutRenderer:

...next, I created a LayoutRenderer like so:

[LayoutRenderer("json-event-properties")]
public class JsonEventPropertiesLayoutRenderer : LayoutRenderer
{
    /// <summary>
    /// Renders the specified environmental information and appends it to the specified <see cref="T:System.Text.StringBuilder" />.
    /// </summary>
    /// <param name="builder">The <see cref="T:System.Text.StringBuilder" /> to append the rendered data to.</param>
    /// <param name="logEvent">Logging event.</param>
    protected override void Append(StringBuilder builder, LogEventInfo logEvent) {
        if (logEvent.Properties == null || logEvent.Properties.Count == 0)
            return;
        var serialized = logEvent.Properties.ToJson();
        builder.Append(serialized);
    }
}

在我的应用程序中,启动时,我这样注册了LayoutRenderer:

In my application, when starting up, I registered my LayoutRenderer like so:

LayoutRenderer.Register<JsonEventPropertiesLayoutRenderer>("json-event-properties");

...最后,我像这样配置NLog目标:

... and finally, I configured the NLog target like this:

    <layout xsi:type="JsonLayout">
    <attribute name="timestamp" layout="${longdate}"/>
    <attribute name="level" layout="${level:uppercase=true}"/>
    <attribute name="exception" layout="${onexception:${exception:format=tostring}}" />
    <attribute name="message" layout="${message}" />
    <attribute name="properties" layout="${json-event-properties}" encode="false"/>
  </layout>

以这种方式运行,JSON格式正确,并且可以访问我的LogEventInfo对象中的属性.

Running like this, the JSON properly formatted and I got access to the properties in my LogEventInfo object.

这篇关于将NLog属性设置为JSON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆