log4net是否支持在日志消息中包含调用堆栈

Ian*_*ose 8 .net debugging log4net

我希望在log4net消息中包含调用堆栈(例如,调用我的方法).有这样做的标准方法吗?

(我知道这会很慢,但我只需要做一些错误)

Rob*_*ine 12

是 - 您可以在模式布局中使用以下模式获取此堆栈信息:

%type %file %line %method %location %class
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅PatternLayout上的文档.

编辑以回应下面的Ian的评论:我不认为 log4net可以配置为写出整个堆栈.

您可以随时使用类似的东西new StackTrace().ToString()自行编写,但我猜您问的原因是您希望在日志记录配置中可以配置它.

我会有更深入的了解,但我的直觉是没有办法配置它,并且你最终必须实现自己的Layout类.

编辑++ OK - 这是一个自定义模式布局类,它派生自PatternLayout但在布局%堆栈中添加.

这段代码有点粗糙 - 仅供说明 - 不准备生产!(例如,您可能没有安全权限来访问您尝试打印的堆栈)

public class CustomPatternLayout : PatternLayout
{
    public CustomPatternLayout()
    {
        this.AddConverter("stack", typeof(StackTraceConverter));
    }
}

public class StackTraceConverter : PatternLayoutConverter
{
    protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
    {
        var stack = new StackTrace();

        var frames = stack.GetFrames();
        for (var i = 0; i < frames.Length; i++ )
        {
            var frame = frames[i];

            // if the stack frame corresponds to still being inside the log4net assembly, skip it.
            if (frame.GetMethod().DeclaringType.Assembly != typeof(LogManager).Assembly)
            {
                writer.WriteLine("{0}.{1} line {2}",
                    frame.GetMethod().DeclaringType.FullName,
                    frame.GetMethod().Name, 
                    frame.GetFileLineNumber());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下模式配置对其进行配置(请注意布局末尾的%stack):

  <layout type="ScratchPad.CustomPatternLayout,ScratchPad">
    <conversionPattern value="%date %-5level %message%newline %type %file %line %method %location %class %stack" />
  </layout>
Run Code Online (Sandbox Code Playgroud)