1. 简介
JUL(Java Util Logging)是 Java 内置的日志框架。虽然简单易用,但缺乏现代日志框架的灵活性和高级特性。因此许多项目会选择其他日志方案。
但在模块化软件和第三方依赖盛行的今天,应用中某些组件可能仍使用 JUL,即使我们更倾向于其他日志框架。这导致日志配置变得复杂。
本文将介绍如何利用 SLF4J 的 JUL 到 SLF4J 桥接器解决这个问题。
2. 依赖配置
首先在项目中添加 SLF4J 相关依赖。对于 Maven 项目,在 pom.xml
中加入以下依赖:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>2.0.16</version>
</dependency>
jul-to-slf4j
包含一个 java.util.logging
(JUL) 处理器——SLF4JBridgeHandler
,它负责将所有 JUL 日志记录路由到 SLF4J API。
⚠️ 注意:应用还需指定 SLF4J 的具体实现。本文以 slf4j-simple
为例:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.16</version>
</dependency>
3. 默认 JUL 日志输出
未配置桥接器时,若第三方库使用 JUL 记录日志,输出将采用 JUL 默认格式。例如:
import java.util.logging.Logger;
public class BusinessLogic {
static void julLog(Logger julLogger) {
julLogger.info("This is a JUL info log message!");
julLogger.warning("This is a JUL warning log message!");
}
}
运行 julLog()
方法将输出类似内容:
Jan 19, 2025 11:43:41 PM com.baeldung.BusinessLogic julLog INFO: This is a JUL info log message!
Jan 19, 2025 11:43:41 PM com.baeldung.BusinessLogic julLog WARNING: This is a JUL warning log message!
4. 配置桥接器
可通过编程方式或 logging.properties
文件配置桥接器。下面分别介绍。
4.1 编程式配置
在应用主类中编程式安装桥接器。此方法简单直接,确保在应用初始化阶段完成安装:
import org.slf4j.bridge.SLF4JBridgeHandler;
import java.util.logging.Logger;
public static void main(String[] args) {
// 移除现有处理器
SLF4JBridgeHandler.removeHandlersForRootLogger();
// 安装 SLF4J 桥接器
SLF4JBridgeHandler.install();
// 测试桥接器安装后的输出
BusinessLogic.julLog(julLogger);
BusinessLogic.slf4jLog(logger);
}
代码逻辑:
- 移除所有 JUL 处理器避免重复日志
- 安装 SLF4J 桥接器,将 JUL 日志重定向到 SLF4J
4.2 通过 logging.properties
配置
也可使用 JUL 的 logging.properties
文件声明式配置。此方法适合无法修改代码或添加编程配置的场景。
在 src/main/resources/logging.properties
中添加:
handlers = org.slf4j.bridge.SLF4JBridgeHandler
.level = INFO
配置说明:
handlers
指定SLF4JBridgeHandler
处理 JUL 根日志.level
设置默认日志级别为 INFO(仅记录该级别及以上日志)
JUL 默认使用 JAVA_HOME/conf/logging.properties
。需通过 JVM 参数指定自定义配置文件路径:
-Djava.util.logging.config.file=/path/to/logging.properties
❌ 缺点:此方式需管理 JUL 内部配置。编程式配置则可完全通过 SLF4J API 实现。
5. 测试日志配置
配置完成后,通过测试验证桥接器是否正常工作。
5.1 通过 JUL 记录日志
即使第三方库使用 JUL,日志消息现在也会通过 SLF4J 路由:
import java.util.logging.Logger;
public class BusinessLogic {
static void julLog(Logger julLogger) {
julLogger.info("This is a JUL info log message!");
julLogger.warning("This is a JUL warning log message!");
}
}
julLog()
输出将变为 SLF4J 格式(以 slf4j-simple 为例):
[main] INFO com.baeldung.JULAppWithProgrammaticSLF4J - This is a JUL info log message!
[main] WARN com.baeldung.JULAppWithProgrammaticSLF4J - This is a JUL warning log message!
5.2 直接通过 SLF4J 记录日志
虽然桥接器支持 JUL,但最佳实践是直接声明 SLF4J 日志器:
public class BusinessLogic {
static void slf4jLog(org.slf4j.Logger logger) {
logger.info("This is an SLF4J info log message!");
logger.error("This is an SLF4J error log message!");
}
}
通过同时测试 JUL 和 SLF4J 日志,可验证集成是否成功。
6. 总结
✅ 核心要点:
- JUL 到 SLF4J 桥接器解决了混合日志框架的统一管理问题
- 支持编程式和声明式两种配置方式
- 编程式配置更灵活,声明式配置适合特殊场景
- 测试时需同时验证 JUL 和 SLF4J 日志输出
通过桥接器,我们既保留了第三方库的 JUL 日志,又统一了日志管理,避免了多框架日志混乱的踩坑问题。