拥有多个记录器实例而不是拥有一个静态记录器类有什么好处?

Wol*_*olf 5 java logging log4j logback slf4j

所以我研究了关于登录 Java(slf4j、log4j、logback 等)的最佳实践,似乎库之间同意记录 API 应该是什么样子。我一直阅读的建议是这样的代码,您可以在其中为每个类创建一个记录器:

class Foo{
  Logger logger = Logger.getLogger(Foo.class);
  //...
  logger.info("my log message");
  //...
}
Run Code Online (Sandbox Code Playgroud)

现在我并没有真正受益于为不同的类设置单独的记录器。为什么信息/调试/等。Logger 类中的方法不是静态的?

请不要给出诸如“好处是您可以根据类配置记录器。例如,您可以将各个类的日志级别设置为 DEBUG...”之类的回答,因为我认为这是您可以的也可以使用完全静态的 Logger 类来完成。

如果您环顾四周(例如在 stackoverflow 上:Log4J:创建 Logger 实例的策略),您会发现人们使用这样的习惯用法:

Logger.getLogger(Thread.currentThread().getStackTrace()[2].getClass().getCanonicalName());
Run Code Online (Sandbox Code Playgroud)

现在,您不必为每个类都创建一个记录器,而只需在静态(例如)info() 方法中调用上面的代码,您可以在其中确定调用类并应用所有记录器配置,就像您在其他情况下所做的一样。

那么谁能告诉我为什么有人应该为每个类使用一个记录器而不是使用一个静态记录器的真正原因?纯粹是历史原因吗?我错过了什么吗?我知道这可能会对性能产生影响,但它实际上在内存使用方面是积极的(当然在运行时方面是消极的)......

更新我想你甚至可以在静态信息/调试/等中使用这个代码。方法,它比上面的代码漂亮且性能更高:

Reflection.getCallerClass()
Run Code Online (Sandbox Code Playgroud)

然而,对该方法的支持似乎有问题 >=JDK7

And*_*ner 0

在静态方法中调用该行info()会对性能产生不利影响,因为每次都需要创建整个堆栈跟踪,而且速度非常慢

将记录器实例分配给每个类的静态变量意味着您可以显式了解该类,也可以使用昂贵的方法在加载类时从堆栈跟踪中确定一次类名。然后,您可以一遍又一遍地使用相同的记录器,而不必再次解析调用类。