我们使用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对象的根目录?
感谢您的帮助。
答案 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聊聊。