带有 Mono 的 Log4Net 缺少文件名和行号

Log4Net with Mono is missing file name and line numbers

我有一个简单的 C# 应用程序,我可以 运行 在 windows 平台或 linux 平台 (CentOS 7) 上使用 mono 4.2.3.4/832de4b。

当我尝试在 windows 机器上使用 log4Net 2.0.5 记录内容时,我使用 RollingFileAppender 得到以下输出:

2016-03-24 09:09:40,374 DEBUG 8 C:\src\Test\Program.cs::20::This is my debug message.
2016-03-24 09:09:40,397 INFO  8 C:\src\Test\Program.cs::21::This is my info message.
2016-03-24 09:09:40,398 WARN  8 C:\src\Test\Program.cs::22::This is my warning message.
2016-03-24 09:09:40,398 FATAL 8 C:\src\Test\Program.cs::23::This is my fatal message.
2016-03-24 09:09:40,399 ERROR 8 C:\src\Test\Program.cs::24::This is my error message.

当我将其复制到 linux 框并使用单声道执行时,我得到以下信息:

2016-03-24 09:58:58,913 DEBUG 1 ::0::This is my debug message.
2016-03-24 09:58:58,920 INFO  1 ::0::This is my info message.
2016-03-24 09:58:58,920 WARN  1 ::0::This is my warning message.
2016-03-24 09:58:58,923 FATAL 1 ::0::This is my fatal message.
2016-03-24 09:58:58,923 ERROR 1 ::0::This is my error message.

为什么我的输出中缺少文件名和行号?理想情况下,我希望与 rsyslog 一起工作,但现在我正在尝试让我的简单应用程序正常工作。

注意:我有一个围绕 log4net 的包装器 class,我使用来自 here.

的信息实现了它

RollingFileAppender 配置如下所示:

    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
        <file value="test_logfile.txt" />
        <appendToFile value="true" />
        <rollingStyle value="Size" />
        <maxSizeRollBackups value="10" />
        <maximumFileSize value="50MB" />
        <staticLogFileName value="true" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date %-5level %thread %file::%line::%message%newline" />
        </layout>
    </appender>

原因是 log4net 首先获取此信息的方式。我没有查看源代码,但我很确定它使用类似以下内容的堆栈跟踪获取此信息:

var frame = new System.Diagnostics.StackTrace(true).GetFrame(0);
var filename = frame.GetFileName(); 
var lineNumber = frame.GetFileLineNumber();

运行time 从哪里得到这些信息?通常来自您放在 .dll 或 .exe 文件(那些 .pdb 文件)附近的调试符号。尽量不要将 .pdb 文件放在你的 exe 和上面的 运行 代码附近 - 它 return 没有文件名和行号。

现在单声道。首先,mono 使用另一种调试符号格式(.mdb 文件)。如果你在 windows 上也 运行 - 很可能你没有使用 mono 编译器编译,所以你有常规的 .NET .pdb 文件。其次 - 默认情况下,单声道不会收集您想要的信息,即使使用正确的符号也是如此。您必须传递 --debug 标志 ("mono --debug ").

总结:

  1. 用单声道编译器编译。
  2. 将调试符号文件 (.mdb) 与您的 .exe 一起使用。
  3. 运行 带有 --debug 标志的单声道。