如何在无Log4j实现的Apache Commons Logging日志开头添加线程ID?
给Apache Commons Logging(Jdk14Logger)日志添加线程ID的解决方案
这个问题我之前也踩过坑——你当前用的Jdk14Logger其实是Apache Commons Logging(ACL)对Java自带的java.util.logging(简称JUL)的包装,ACL本身只是个日志门面,日志格式完全由底层的JUL控制,所以你修改commons-logging.properties或者调用ACL的setProperty方法自然不会生效。下面给你两种可行的解决思路:
一、编程式配置JUL自定义Formatter
直接通过代码给JUL设置带线程ID的日志格式,步骤如下:
1. 自定义JUL Formatter类
写一个继承自java.util.logging.Formatter的类,在日志内容前拼接线程ID:
import java.util.logging.Formatter; import java.util.logging.LogRecord; public class ThreadIdPrefixFormatter extends Formatter { @Override public String format(LogRecord record) { // 获取当前线程ID long threadId = Thread.currentThread().getId(); // 保留JUL默认格式的同时,在开头加上线程ID前缀 return String.format("[Thread-%d] %s", threadId, super.format(record)); } }
2. 初始化JUL配置
在应用启动的入口处(比如main方法开头)初始化JUL的日志Handler,替换默认的Formatter:
import java.util.logging.ConsoleHandler; import java.util.logging.Logger; public class AppLogInitializer { public static void setupLogging() { // 获取JUL的根Logger(如果需要针对特定包配置,替换成Logger.getLogger("你的包名")) Logger rootLogger = Logger.getLogger(""); // 先移除默认的Handler,避免重复输出日志 for (var handler : rootLogger.getHandlers()) { rootLogger.removeHandler(handler); } // 创建新的控制台Handler ConsoleHandler consoleHandler = new ConsoleHandler(); // 绑定自定义的Formatter consoleHandler.setFormatter(new ThreadIdPrefixFormatter()); // 设置日志级别(根据你的需求调整,比如INFO、DEBUG) consoleHandler.setLevel(java.util.logging.Level.INFO); // 将Handler添加到根Logger rootLogger.addHandler(consoleHandler); rootLogger.setLevel(java.util.logging.Level.INFO); } }
3. 启动时加载配置
在你的应用启动类中调用初始化方法:
public class Main { public static void main(String[] args) { // 先初始化日志配置 AppLogInitializer.setupLogging(); // 然后正常使用ACL的日志 org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(Main.class); log.info("这是一条带线程ID的日志"); } }
二、通过JUL配置文件实现
如果不想写代码,也可以通过JUL的配置文件来指定自定义Formatter:
1. 创建JUL配置文件
在项目的资源目录下(比如src/main/resources)创建logging.properties文件,内容如下:
# 根日志级别 .level=INFO # 指定使用的Handler(这里用控制台输出) handlers=java.util.logging.ConsoleHandler # 控制台Handler的配置 java.util.logging.ConsoleHandler.level=INFO # 绑定你自定义的Formatter类(替换成你实际的包名+类名) java.util.logging.ConsoleHandler.formatter=com.yourpackage.ThreadIdPrefixFormatter
2. 启动时加载配置
启动应用时添加JVM参数,指定JUL配置文件的路径:
java -Djava.util.logging.config.file=src/main/resources/logging.properties -jar your-app.jar
关键说明
- 为什么之前的方法无效?
commons-logging.properties的作用是选择日志实现(比如指定用Log4j还是Jdk14Logger),而不是控制日志格式;ACL的setProperty方法是给底层日志实现预留的接口,但Jdk14Logger并没有实现对这些属性的处理,所以调用了也不会影响JUL的格式。 - 如果你需要更复杂的日志格式,可以在自定义Formatter的
format方法中完全自定义输出内容,比如添加时间戳、日志级别、类名等。
内容的提问来源于stack exchange,提问作者JackTheKnife
相关产品推荐
相关产品推荐

