log4net.ext.json - 可选属性

时间:2016-01-11 20:52:57

标签: json log4net

我们使用log4net.ext.json将日志序列化为JSON格式的文件。但是,我无法弄清楚如何将可选字段添加到json对象的根目录,而不向不显示该数据的日志添加不必要的数据。让我解释一下:

我们有几种不同类型的日志,每种日志都有自己的自定义渲染器和日志对象。我们想要的是让这些对象的数据出现在JSON对象的基础中,因为它符合我们的多平台日志标准。

以下是一个示例:我们在记录入站和出站请求以及对Web服务的响应时使用了一个HttpData对象。在我们的appender中,我们获取HttpData对象并将其属性值(例如HttpRoute字段)放入LoggingEvent属性对象中。

然后我们按如下方式配置appender:

<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="D:\log.txt"/>
  <rollingStyle value="Size"/>
  <maxSizeRollBackups value="10"/>
  <maximumFileSize value="100MB"/>
  <AppendToFile value="true"/>
  <layout type="log4net.Layout.SerializedLayout, log4net.Ext.Json">
    ...
    <member value="HttpRoute:HttpRoute"/>
    ...
  </layout>
</appender>

SerializedLayout非常智能,可以从loggingEvent属性中提取HttpRoute的值,并生成如下所示的JSON:

{
  ...,
  "HttpRoute": "/my/route/to/the/api",
  ...
}

这很完美!但是,当HttpRoute在LoggingEvent属性中找不到 时,它会假定指定的字段是字符串文字,并生成:

{
  ...,
  "HttpRoute": "HttpRoute",
  ...
}

这不太理想。

有没有办法让HttpRoute只在日志记录事件属性中有值时出现?或者是否有另一种方法可以将日志记录对象中的字段输出到记录的JSON对象的根目录?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我现在听到你了。

你试过吗?

<member value="HttpRoute"/>

我在Member.cs中找到了罪魁祸首:

    /// <param name="loggingEvent">the event to get value from</param>
    /// <param name="obj">value found</param>
    /// <returns>success of finding a NestedLayout not null</returns>
    protected virtual bool GetDefaultValue(Core.LoggingEvent loggingEvent, out object obj)
    {
        obj = Option ?? Name;
        return true;
    }

快速解决方法是覆盖该方法并仅返回Option,而不是?? Name

    protected override bool GetDefaultValue(Core.LoggingEvent loggingEvent, out object obj)
    {
        obj = Option;
        return true;
    }

然后,您需要在配置中声明新的成员类型:

<member value="HttpRoute:HttpRoute" type="Your.Member"/>

如果您认为这应该是默认设置,请让enhancement聊聊。