特定NLog日志记录器名称匹配问题

4

我在NLog.config中配置了两个规则:

<logger name="Model" level="Info" writeTo="modelLog" final="true" />
<logger name="*" minlevel="Debug" writeTo="logFile" />

我正在尝试使用以下代码写入第一个:

LogEventInfo eventInfo = new LogEventInfo();
eventInfo.Level = LogLevel.Info;
eventInfo.LoggerName = "Model";
eventInfo.TimeStamp = DateTime.Now;
logger.Log(eventInfo);

但它一直落入第二个规则。我本以为eventInfo.LoggerName = "Model";会直接进入第一个规则?

1个回答

4

我现在不在电脑旁,无法尝试您的情况,但我有几个问题。

  1. 您能否尝试使用“常规”日志记录功能(信息、调试),看看是否按预期工作?

  2. 您是如何解决您的记录器的?也就是说,“记录器”的名称是什么?

如果实际记录器的名称不是“Model”,那么我猜它将不符合“Model”条件,即使您在LogEventInfo的Name字段中传递了“Model”。

[编辑] 这是一个更好的NLog记录器包装器的简化示例,可以在Ninject Logging扩展中使用。该包装器以保留调用站点信息的方式委托日志记录调用到底层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);
    }
  }

显然,这个例子没有涉及到异常处理。但是,我认为它展示了正确的封装NLog的方式。很容易实现完整的Ninject Logging Extension ILogger接口,将每个Info、Debug、Warn等调用委托给一个中心Write方法,该方法将创建LogEventInfo类,然后使用底层的NLog logger实例记录它,传递包装日志记录器的类型(在我的示例中为typeof(NLogLogger))。传递包装日志记录器的类型对于维护应用程序代码中的日志记录调用的调用站点信息至关重要。
基于在Ninject Logging Extensions git repository中找到的NLog包装器。 更多关于依赖注入和命名日志记录器(如NLog和log4net)的信息。 有关天真的日志记录器包装器问题的更多信息,请参见此处的答案。

我认为问题在于实际使用的记录器名称必须与配置文件中的记录器名称匹配,而不是通过LogEventInfo传递的名称。实际上,在您的应用程序中使用单个记录器G6.Infrastructure.Logging.NLogLogger。这是注入NLog或log4net记录器时常见的问题。由于现在不在电脑前,所以很难找到并添加好的链接,但是这里在SO上有一些关于这个困境的帖子。 - wageoghe
在我的个人资料中查看关于“依赖注入和命名日志记录器”的问题,还有一些我对标记为NLog的帖子的回答,你可能会找到一些关于注入依赖于正确“命名”的日志记录器的陷阱的信息。 - wageoghe
Ninject。看起来所有内置的日志记录模块都在v2中被删除了。 - mattdwen
我之前使用了 var logger = LogManager.GetCurrentClassLogger();。 现在我在这个类中添加了第二个日志器 var modelLogger = LogManager.GetLogger("Model"); 并开始使用它。 我对“名称”匹配的理解有误。 这可能更像是一个变通方法而不是解决方案,但它可以工作。 - mattdwen
你能为Ninject编写自己的“解析器”吗?如果可以,你知道在对象的“解析”阶段是否可以访问正在创建的对象类型。例如,如果Class1依赖于ILogger,那么当Ninject构建Class1时,Ninject需要知道使用哪个对象来提供ILogger实现。如果您可以编写自己的解析器(对于ILogger),并且如果您的解析器知道正在解析Class1的依赖项,则可以使用该类型(Class1)获取Class1的特定于类的ILogger。 - wageoghe
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接