【问题标题】:using slf4j with log4j2将 slf4j 与 log4j2 一起使用
【发布时间】:2026-01-10 09:25:01
【问题描述】:

我最近一直在尝试 log4j2。现在,我想用 slf4j 对其进行测试,并想知道如果我用 log4j2 尝试 slf4j,log4j2 中的所有功能(例如通过中断器的异步日志记录)是否可用。我尝试将 slf4j jar 文件和 log4j2 和破坏者 jar 文件添加到测试项目中(我添加了 log4j-slf4j jar,但不完全确定它是否仅适用于 log4j 或 log4j2)。当我使用 log4j2 时,我可以将语句注销到日志文件。当我尝试 slf4j 时,它不起作用(而且我不确定它是我的配置还是 slf4j 未设置为使用 log4js 中断日志记录这一事实?欢迎提出任何建议。我将使用更多信息更新帖子和示例代码也是如此。

【问题讨论】:

标签: java logging log4j slf4j log4j2


【解决方案1】:

是的,无论您的应用使用 log4j2 api、slf4j api 还是 log4j-1.2 api,通过中断器的异步记录器都应该可以工作。请参阅 log4j2 常见问题页面了解要包含的 jar。你需要一个用于 slf4j api 的 jar,此外你还需要 log4j-api-2.x、log4j-core-2.x 和 log4j-slf4j-impl-2.x jar。相同的 log4j2.xml 配置文件应该可以工作。

更新:not all Log4j2 functionality is available via the SLF4J API

更新 2:Is it safe to program directly to the Log4j2 API?

【讨论】:

  • 是 log4j2 使用的中断环缓冲区中的对象,随着新日志事件的出现而预先分配和变异,还是随着每个日志事件创建新对象?
  • 如果所有记录器都是异步的(使用系统属性 AsyncLoggerContextSelector),那么带有 RingBufferLogEvents 的环形缓冲区会被预先分配,并且随着新的日志事件的出现,条目会发生变化。然而,这并不是完全无垃圾的,因为日志事件包含 Message 对象;如果您调用logger.info("Some parameterized msg, param={}", someObject);,则会创建一个ParameterizedMessage 对象,该对象会创建参数的字符串快照。这是为了防止可变参数对象在调用 logger.info 和后台线程写入文件之间发生变化。
  • 当使用混合异步/同步记录器时,使用不同的环形缓冲区。在这种情况下,环形缓冲区预先分配了LogEventWrapper 对象,这些对象可以容纳标准的LogEvent 对象。这里为每次调用logger.log(...) 创建一个标准的LogEvent 对象,并通过设置LogEventWrapper 字段将其放入环形缓冲区。所以这里有一个权衡:更大的灵活性,但由于更多的对象创建可能会导致小的性能损失。在这两种情况下,一旦后台线程写入日志事件,环形缓冲区插槽就会被清除(因此可以对对象进行 GC)。
  • 多莫阿里加托。我在使用 log4j2 测试时注意到了 GC 活动,因此问了这个问题。感谢您回来,当然也感谢您在 log4j2 上的工作。我正在尝试使用堆外测试日志记录并与 log4j2 和 logback-reactor 进行比较,但现在将使用 log4j2。
  • 我正在使用异步 - 我通过您提到的标志在系统属性中指定它。