使用包装器时,Nlog Callsite错误

Sta*_*ker 14 c# logging nlog

我正在使用NLog进行日志记录,我使用包装器来调用日志方法,我的问题是:如果我尝试打印有关调用site(${callsite})的信息,它会打印包装器方法而不是导致记录器记录的原始方法.

有没有办法获得调用包装器方法的原始方法?

wag*_*ghe 20

看看我对这个问题的回答:

与特定NLog记录器名称匹配的问题

我已经从这个答案复制了示例代码(对于缩写的NLog包装器)以节省一些麻烦:

  class NLogLogger : ILogger
  {
    private NLog.Logger logger;

    //The Type that is passed in is ultimately the type of the current object that
    //Ninject is creating.  In the case of my example, it is Class1 and Class1 is
    //dependent on ILogger.
    public NLogLogger(Type t)
    {
      logger = NLog.LogManager.GetLogger(t.FullName);
    }

    //Trace, Warn, Error, Fatal eliminated for brevity

    public bool IsInfoEnabled
    {
      get { return logger.IsInfoEnabled; }
    }

    public bool IsDebugEnabled
    {
      get { return logger.IsDebugEnabled; }
    }

    public void Info(string format, params object [] args)
    {
      if (logger.IsInfoEnabled)
      {
        Write(LogLevel.Info, format, args);
      }
    }

    public void Debug(string format, params object [] args)
    {
      if (logger.IsDebugEnabled)
      {
        Write(LogLevel.Debug, format, args);
      }
    }

    private void Write(LogLevel level, string format, params object [] args)
    {
      LogEventInfo le = new LogEventInfo(level, logger.Name, null, format, args);
      logger.Log(typeof(NLogLogger), le);
    }
  }
Run Code Online (Sandbox Code Playgroud)

请注意,这个答案是在NInject的上下文中给出的.即使您没有使用NInject,相同的原则也适用于包装NLog.关键是与NLog沟通包装器的类型.

这是关于如何正确编写NLog包装器(即维护呼叫站点信息)的示例.关键在于Write方法.注意它是如何使用NLog的Log方法的.另请注意,它将包装类的类型作为第一个参数传递.NLog使用类型信息向上导航调用堆栈.一旦它看到一个方法,其DeclaringType是传入类型(即包装器的类型),它就知道堆栈的下一帧是调用方法.

另请参阅此链接(到NLog的源存储库)以获取另外两个"扩展"Logger的示例.一个通过包装,一个通过继承:

https://github.com/jkowalski/NLog/tree/master/examples/ExtendingLoggers

我不是100%肯定,但我认为你不能简单地包装NLog并将Info,Debug,Warn等方法委托给NLog,如下所示:

class MyNLogWrapper
{
  private readonly Logger logger = LogManager.GetCurrentClassLogger();

  public void Info(string msg)
  {
    logger.Info(msg);
  }
}
Run Code Online (Sandbox Code Playgroud)

你需要一种方法来告诉NLog你的包装器的类型,我认为你只能通过Logger.Log方法调用NLog(重载)来做到这一点.

如果这不够用,请发布您的包装以获得更多帮助.

  • 当传递扩展方法所在的类作为传递给`Log`的类型时,这似乎也适用于扩展方法. (2认同)