在Log4Net或NLog(或其他一些记录器)中是否有办法以执行堆栈嵌套的XML或JSON格式输出日志,这样如果函数A()
调用B(7)
来调用{ {1}},它会输出如下内容:
C("something")
甚至更好:
<Method name="A">
<Method name="B" params="(int) 7">
<Method name="C" params="(string) 'something'"/>
</Method>
</Method>
为什么呢?所以我能够使用(例如)XML Notepad或一些<Method name="A">
<Method name="B" params="(int) 7">
<Params>
<int>7</int>
</Params>
<Method name="C">
<Params>
<string>something</string>
</Params>
</Method>
</Method>
</Method>
- 观众(不知道任何显着的......)快速折叠(不相关)或展开(相关)子 - 试图了解出了什么问题时调用。我使用PostSharp
来记录(当前仅使用缩进)每个方法入口/出口和异常
答案 0 :(得分:2)
日志记录框架没有关于方法边界的信息,因此无法正确格式化XML。您可以尝试扩展框架并将其他信息传递给日志记录方法。
获取此输出的更简单方法是在Aspect方面执行所有消息格式化,并将日志记录框架配置为仅输出消息文本而不包含任何其他信息。
例如,在 log4net 配置中:
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message%newline" />
</layout>
在您方面的OnEntry方法中,您将打开XML标记(或JSON对象),并在OnExit方法中关闭标记。您可以从下面的简单示例开始,针对您的特定情况优化代码(例如,在 RuntimeInitialize , CompileTimeInitialize 方法中初始化记录器实例和格式化字符串)。
[Serializable]
public class XmlLogAttribute : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
ILog log = LogManager.GetLogger(args.Method.DeclaringType);
if (log.IsDebugEnabled)
{
log.DebugFormat("<Method name=\"{0}\">", args.Method.Name);
log.Debug("<Params>");
foreach (object methodArgument in args.Arguments)
{
if (methodArgument == null)
{
log.Debug("<null/>");
}
else
{
log.DebugFormat("<{0}>{1}</{0}>", methodArgument.GetType(), methodArgument);
}
}
log.Debug("</Params>");
}
}
public override void OnExit(MethodExecutionArgs args)
{
ILog log = LogManager.GetLogger(args.Method.DeclaringType);
log.Debug("</Method>");
}
}
答案 1 :(得分:0)
您必须在log4net中创建自己的XmlLayoutBase FormatXml方法覆盖。
答案 2 :(得分:0)
请参阅log4net PatternLayout的fn nth(n: i32, p: (i32, i32)) -> HashSet<(i32, i32)> {
let s0 = HashSet::new();
let mut s1 = HashSet::new();
s1.insert(p);
nthLoop(n, s1, s0)
}
。收获显然很昂贵,但应该给出一些结果。还可以更改日志信息的呈现。在log4net.Ext.Json项目中,可以使用decorator来实现此效果。 (我是作者)。