JUL 是 Java 的内置日志框架。它使用起来很简单,但缺乏现代替代方案所提供的灵活性和高级功能。因此,许多应用程序选择了其他东西。
但是在这个模块化软件和第三方依赖的世界中,我们的应用程序中的某些东西可能会使用 JUL,尽管我们不愿意这样做。这使得正确配置日志变得更加复杂。
在本文中,我们将了解SLF4J的 JUL 到 SLF4J桥如何帮助解决这个问题。
依赖项
首先,我们在项目中包含 SLF4J 依赖项。对于 Maven 项目,我们需要将slf4j-api 和jul-to-slf4j 依赖项添加到pom.xml文件中:
<dependency> |
jul-to-slf4j工件由java.util.logging (JUL) 处理程序(即SLF4JBridgeHandler)组成,它将所有传入的 JUL 记录路由到 SLF4J API。
请注意,应用程序还必须指定要使用的 SLF4J API SLF4J 日志记录实现。因此,对于本文,我们假设我们的应用程序使用slf4j-simple:
<dependency> |
默认 JUL 日志
在配置桥接器之前,如果库通过 JUL 进行日志记录,则输出将使用默认的 JUL 格式。例如,请考虑以下代码:
import java.util.logging.Logger; |
在没有 JUL-to-SLF4J 桥接器的情况下运行此代码时,julLog()会产生类似以下内容的输出:
Jan 19, 2025 11:43:41 PM com.jdon.BusinessLogic julLog INFO: This is a JUL info log message! |
配置网桥
我们可以通过两种方式之一配置桥接器:通过编程或通过logging.properties文件。让我们分别看一下。
程序化配置
我们可以在主应用程序类中以编程方式设置 SLF4J 桥接器。此方法非常简单,可确保在应用程序的初始化阶段安装桥接器:
import org.slf4j.bridge.SLF4JBridgeHandler; |
在此代码中,我们首先删除所有现有的 JUL 处理程序以防止重复的日志条目。然后,我们安装 SLF4J 桥接器,它将所有 JUL 日志记录重定向到 SLF4J。
使用logging.properties进行配置
或者,我们可以使用 JUL 的logging.properties文件以声明方式配置桥接器。此方法非常适合无法修改代码库或添加编程配置的应用程序。
为此,我们首先创建src/main/resources/logging.properties并指定 JUL 处理程序和日志记录级别:
handlers = org.slf4j.bridge.SLF4JBridgeHandler |
在此配置中:
- handlers行指定SLF4JBridgeHandler应该处理 JUL 根记录器的日志记录
- .level属性将默认日志记录级别设置为INFO,这意味着只会记录此级别或更高级别的消息
-Djava.util.logging.config.file=/path/to/logging.properties |
这确保加载我们的自定义日志配置而不是默认配置。
请注意,这种方法效果很好,但它的缺点是我们需要管理一些 JUL 内部组件才能使其工作。编程方法允许我们坚持使用 SLF4J API 进行配置。
测试日志配置
现在我们已经设置了 JUL 到 SLF4J 桥接器,我们可以测试我们的日志配置以确保一切按预期工作。
1. 通过 JUL 记录
即使第三方库使用 JUL 记录日志,日志消息现在也将通过 SLF4J 路由:
import java.util.logging.Logger; |
这些日志将由 SLF4J 后端(例如 slf4j-simple)而不是 JUL 处理,并且julLog()输出类似于:
[main] INFO com.jdon.JULAppWithProgrammaticSLF4J - This is a JUL info log message! |
2. 通过 SLF4J 直接记录
虽然上一节显示我们现在可以将 JUL 与 SLF4J 一起使用,但最好声明一个 SLF4J 记录器:
public class BusinessLogic { |
通过测试基于 JUL 和基于 SLF4J 的日志记录,我们可以确认集成正常运行。