当前位置: 首页 > 知识库问答 >
问题:

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

聂永怡
2023-03-14

因此,我研究了有关在Java中登录的最佳实践(slf4j、log4j、logback等),看起来,库之间已经同意了日志API应该是什么样子。我一直在读的建议是这样的代码,您可以为每个类创建一个记录器:

class Foo{
  Logger logger = Logger.getLogger(Foo.class);
  //...
  logger.info("my log message");
  //...
}

现在,我并没有真正得到为不同的类使用不同的记录器的好处。为什么Logger类中的info/debug/etc.方法不是静态的?

请不要给出类似“好处是您可以根据类配置日志记录器。例如,您可以将单个类的日志级别设置为调试…”这样的anwser,因为我认为这也是完全静态记录器类可以实现的。

如果您环顾四周(例如stackoverflow:Log4J:Strategies for creating Logger Instance),您会发现有人使用这样的习惯用法:

Logger.getLogger(Thread.currentThread().getStackTrace()[2].getClass().getCanonicalName());

现在,您可以在静态(例如)info()方法中调用上面的代码,而不是为每个类创建一个记录器,在该方法中,您可以确定调用的类并像其他方法一样平等地应用所有记录器配置。

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

更新我想你甚至可以在static info/debug/etc.方法中使用这段代码,这段代码比上面的代码更漂亮、性能更好:

Reflection.getCallerClass()

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

共有1个答案

薛经纶
2023-03-14

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

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

 类似资料:
  • 问题内容: 是否应该将记录器声明为静态?通常,我已经看到记录器的两种类型的声明: 要么 应该使用哪一个?两者的优缺点是什么? 问题答案: 非静态形式的优点是,您可以像下面的(抽象)基类中声明它,而不必担心会使用正确的类名: 但是,其缺点显然是将为该类的每个实例创建一个全新的记录器实例。这本身可能并不昂贵,但会增加大量开销。如果您想避免这种情况,请改用表格。但是它的缺点是,您必须在每个单独的类中声明

  • 我使用的是播放框架,其中日志是默认的记录器引擎。为了便于跟踪,我希望将两个不同的活动(和)记录在两个单独的文件中。为此,我有两个追加器和两个记录器。每个记录器都用特定的appender标记。 我希望通过事务记录器(如登录或注册相关活动(如 但不管用。有什么想法吗? 我所说的“不工作”是指相同的日志被附加到两个记录器中,而不是特定于特定的日志。例如。如果我从播放代码调用,事务和登录记录器都将用户X已

  • 现在,问题是,当我以以下方式进行日志记录时: 尽管根记录器级别被设置为“错误”,但日志条目仍然存在于两个日志文件中。然而,当我去掉“it.pkg.testpkg.service”记录器(通过注释或删除它)时,条目停止进入根记录器。我不太清楚这是怎么回事。 目前,我已经找到了一个临时解决方案,方法是在“root_file_appender”中添加以下条目: 谢了。

  • 。 > 有人能简单定义一下是什么吗? 是 泛型是禁止对象上非< code>K的额外键,还是允许它们,只是指示它们的属性不被转换为< code>T? 对于给定的示例: 它和这个完全一样吗

  • 我正在将一个应用程序从Log4J 1.2.16迁移到Log4J 2.13.3。为此,我使用log4j21.2到2.13.3桥。在我自己的开发机器上,一切都运转良好。但是,当我将应用程序部署到测试服务器时,日志只会发送到根日志记录器,我定义的其他日志文件保持为空。 配置文件完全相同,只是附件中的路径不同。我的开发机器运行Windows,测试服务器运行Linux。该应用程序已部署到Weblogic 1