有两种可能性
- 日志适配器作为完整替换(首选,但需要 JVM 启动选项)
- 桥接处理程序,将 JDK 输出传输到 log4j,例如,对 webapps 有用
Log4j JDK 日志适配器
JDK 日志适配器是 java.util.logging.LogManager
的自定义实现,它使用 Log4j。此适配器可与 Log4j API 或 Log4j Core 一起使用。当与 API 一起使用时,JUL 的一些功能不受支持。但是,这确实允许除 Core 提供程序之外的任何其他 Log4j 提供程序与 JUL 一起使用。
要求
JDK 日志适配器依赖于 Log4j API,并且可选地依赖于 Log4j Core。有关更多信息,请参见 运行时依赖项。
用法
要使用 JDK 日志适配器,您必须将系统属性 java.util.logging.manager
设置为 org.apache.logging.log4j.jul.LogManager
。
这必须通过命令行(即使用 -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager
参数)或在对 LogManager
或 Logger
进行任何调用之前使用 System.setProperty()
来完成。
兼容性
在每个 Logger
的基础上支持使用 java.util.logging.Filter
。但是,建议使用 Log4j 中的标准 过滤器 功能。
不支持使用 java.util.logging.Handler
类。自定义处理程序应改为使用适当的 追加器 或编写自己的 Appender
插件。
Java 日志级别动态转换为 Log4j 日志级别。下表列出了 Java 日志级别与其等效的 Log4j 级别之间的转换。自定义级别应实现为 LevelConverter
的实现,并且必须将 Log4j 属性 log4j.jul.levelConverter
设置为您的自定义类名。使用默认的 LevelConverter
实现,自定义日志级别将映射到正在记录到的 Logger
的当前级别。
默认级别转换
Java 级别 | Log4j 级别 |
---|---|
OFF |
OFF |
SEVERE |
ERROR |
WARNING |
WARN |
INFO |
INFO |
CONFIG |
CONFIG |
FINE |
DEBUG |
FINER |
TRACE |
FINEST |
FINEST |
ALL |
ALL |
Log4j JDK 日志桥接处理程序
LogManager 并不总是可用,因为您必须设置 JVM 范围内的有效系统属性 - 例如,在 Web 服务器中,如果您不是管理员,则无法做到这一点。
Log4jBridgeHandler
是一个替代方案,可以通过 logging.properties
声明性地使用。
它的性能不如 LogManager,但仍然可以使用:LogManager 替换了 JDK 实现,因此您的日志代码(使用 JDK 语法)实际上直接使用 log4j。当使用 BridgeHandler 时,原始 JDK 实现及其配置(例如日志级别)仍然完全有效,但日志事件通过此处理程序“写入”到 log4j,就像您调用了 log4j.Logger.debug() 等一样;它就像一个 FileHandler,但不是写入文件,而是“写入”到 log4j 记录器 - 因此与使用 LogManager 相比,有一些开销。
用法
JUL 配置文件 logging.properties
需要以下行
handlers = org.apache.logging.log4j.jul.Log4jBridgeHandler
并且 JUL 日志转到 log4j2。此外,您通常希望使用以下内容
org.apache.logging.log4j.jul.Log4jBridgeHandler.propagateLevels = true
在 Tomcat 上的 webapp(以及可能的其他服务器)中,您只需创建一个包含上述内容的 WEB-INF/classes/logging.properties
文件。此文件中定义的桥接和日志级别仅对您的 webapp 有效,并且不会对同一 Tomcat 实例上的其他 webapp 产生任何影响。
或者,您可以在 webapp 的初始化代码中调用 Log4jBridgeHandler.install()
,例如,在 ServletContextListener
或 ServletFilter
静态类初始化或 contextInitialized()
中。
重要:JDK 的日志级别应与 log4j 的日志级别匹配。您可以手动执行此操作,也可以通过 Log4jBridgeHandler.propagateLevels = true
使用自动级别传播。