在Log4Net或NLog(或其他一些记录器)中是否有一种方法可以以执行堆栈嵌套的XML或JSON格式输出日志?

时间:2013-12-22 14:13:07

标签: c# logging log4net nlog postsharp

在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来记录(当前仅使用缩进)每个方法入口/出口和异常

3 个答案:

答案 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方法覆盖。

See a similar answer here

答案 2 :(得分:0)

请参阅log4net PatternLayoutfn 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来实现此效果。 (我是作者)。