调用 log4net 包装器方法后未在日志中获取文件名和行号

Posted

技术标签:

【中文标题】调用 log4net 包装器方法后未在日志中获取文件名和行号【英文标题】:Not getting the filename and linenumber in log after calling log4net wrapper method 【发布时间】:2016-07-27 05:55:58 【问题描述】:

我已经创建了如下的 log4net 包装类

public class Logger : ILogger


    private log4net.ILog _logger = log4net.LogManager.GetLogger(typeof(Logger));


    public void MyMethod(object message, params object[] args)
    
        if (args.Length == 0 || args == null)
        
            _logger.Info(message);
        
        else
        
            _logger.InfoFormat(message.ToString(), args);
        
    
 

我在控制器类中调用包装方法

   Logger obj=new Logger(); 
   obj.MyMethod("Constructor of AccountController class called.");

我在 webconfig 中将布局模式定义为

<log4net>
    <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
      <param name="File" value="C:\Log\My.log" />
      <param name="AppendToFile" value="true"/>     
      <maximumFileSize value="500KB" />
      <maxSizeRollBackups value="2" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date,%file(%line), [%-5level],%message%newline" />
      </layout>
    </appender>
    <root>
      <level value="All" />
      <appender-ref ref="RollingFile" />
    </root>
  </log4net>

按照我期望遵循日志的模式

2016-07-27 10:12:48,480,e:\MyProject\Controllers\AccountController.cs(24), [INFO ],调用 AccountController 类的构造函数。

但我得到了

2016-07-27 10:12:48,480,e:\MyProject\Infrastructure\Utilities\Logger.cs(15), [INFO ], AccountController 类的构造函数被调用。

文件名和行号我都弄错了。我错过了什么。

【问题讨论】:

【参考方案1】:

据我所知,c# 不像 c/c++,获取文件名和行号是不同的。也许它的实现是以下代码:

string currentFile = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName(); 
int currentLine = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileLineNumber();

所以,结果不是你所期望的。

另见Print the source filename and linenumber in C#

【讨论】:

感谢您的回复,我也可以通过 new StackFrame(0, true);我主要关心的是如何在不更改 PatternLayout 的情况下将此信息传递给 log4net Info 或 InfoFormat 方法【参考方案2】:

你会在这个答案中找到你需要的东西:https://***.com/a/3448439/106567。

关键是不要在包装器中使用ILog 接口。相反,您需要使用 Logger 类,您可以像这样调用它:

_logger.Log(MyLogWrapper.ThisDeclaringType, log4netLevel, message, ex);

重要的部分是第一个参数,它让 log4net 在访问方法名或文件名等内容时删除堆栈跟踪中不需要的部分。以这种方式编写包装器需要更多的工作,但您可以得到您想要的结果。

【讨论】:

以上是关于调用 log4net 包装器方法后未在日志中获取文件名和行号的主要内容,如果未能解决你的问题,请参考以下文章

在 C++/CLI 中使用时未创建 C# 应用程序 log4net 日志文件

有啥方法可以监控 log4net 日志文件以获取应用程序洞察力

可以将 log4net 配置为以自己的身份运行吗?

扫描后未在 sonarqube 中更新项目

扩展 log4net - 向每个日志添加额外数据

未在 libtool 包装器脚本中添加到 LD_LIBRARY_PATH 的已构建库目录