7

我正在使用 log4net,我在其中获取对静态类中记录器的引用,如下所示:

internal static class Constants
{
   public static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
}

并在整个应用程序中使用该引用,如下所示:

Constants.Log.Info(_message);

但是,我感觉这可能会导致问题,并且我意识到常量(全局?)变量可能是一件坏事。

  • 这种方法有什么问题吗?
  • 原因是什么?
  • 可以做些什么来解决这些问题?
4

2 回答 2

13

您是对的,如果您希望能够轻松区分日志级别并为每个类使用不同的日志目标(“附加程序”) ,那不是最好的方法。

通常建议每个类都有一个静态ILog实例,以它的完全限定类型命名:

namespace Animals
{
   public class Dog
   {
       private static readonly ILog Log = LogManager.GetLogger(typeof(Dog));
   }

   public class Cat
   {
       private static readonly ILog Log = LogManager.GetLogger(typeof(Cat));
   }
}

虽然与单例相比,这看起来需要更多的工作,但从长远来看,它非常方便。完成此操作后,很容易通过配置文件区分Dog和记录级别(使用log4net语法Cat显示的示例):

<log4net>

   <!-- appender definitions ommited -->

   <!-- default for all loggers in Animals namespace -->
   <logger name="Animals">
     <level value="WARN"/>
   </logger>

   <!-- ...but we need full debug for Dogs -->
   <logger name="Animals.Dog">
     <level value="DEBUG"/>
   </logger>

   <!-- ...and we want to send Cat messages over e-mail -->
   <logger name="Animals.Cat">
     <level value="INFO"/>
     <appender-ref ref="SmtpAppender"/> 
   </logger>

</log4net>

像 log4net 这样的日志框架也使用分层日志的概念:如果一个 logger 的名称后跟一个点是后代 logger 名称的前缀,则该 logger 被称为另一个 logger 的祖先。要使用此功能,最好避免手动命名记录器(使用硬编码strings),而是使用类型信息来包含整个命名空间。

于 2012-06-08T11:08:39.600 回答
-1

这实际上创建了一个单例,尽管这样做存在许多问题,包括进行有效的单元测试。单元测试不需要记录,这引入了不必要的依赖。

您应该考虑使用 IoC 容器和依赖注入。

于 2012-06-08T11:08:12.070 回答