You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在无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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:04:58