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

如何为Log4j添加微秒级日志?自定义格式器及Log4j2问题排查

Log4j(含Log4j2)微秒级日志配置及问题解决

一、Log4j 1.x 实现微秒级日志输出

如果用的是Log4j 1.x版本,官方默认格式器不支持微秒输出,得自己动手写个自定义格式器来实现:

1. 自定义微秒转换器

先写一个PatternConverter子类,用来获取并格式化微秒部分:

import org.apache.log4j.pattern.PatternConverter;
import org.apache.log4j.spi.LoggingEvent;

public class MicrosecondPatternConverter extends PatternConverter {
    @Override
    protected String convert(LoggingEvent event) {
        // 从日志事件的毫秒时间戳,结合当前纳秒计算真实微秒
        long timestampMillis = event.getTimeStamp();
        long currentNanos = System.nanoTime();
        // 计算当前毫秒内的微秒数:(纳秒 % 1000000) 就是当前毫秒的微秒部分
        long microsInMillis = (currentNanos % 1000000);
        // 组合成完整的6位微秒(毫秒转微秒 + 当前毫秒内的微秒)
        long totalMicros = (timestampMillis % 1000) * 1000 + microsInMillis;
        return String.format("%06d", totalMicros);
    }

    // 提供实例创建方法,供Log4j调用
    public static MicrosecondPatternConverter newInstance(String[] options) {
        return new MicrosecondPatternConverter();
    }
}

2. 自定义PatternLayout

把上面的转换器注册到自定义Layout里,让Log4j识别新的转换符(比如用%m表示微秒):

import org.apache.log4j.PatternLayout;

public class MicrosecondPatternLayout extends PatternLayout {
    public MicrosecondPatternLayout() {
        super();
        // 注册转换器,关联转换符'm'
        addConverter('m', MicrosecondPatternConverter.class);
    }

    public MicrosecondPatternLayout(String pattern) {
        super(pattern);
        addConverter('m', MicrosecondPatternConverter.class);
    }
}

3. 配置文件使用

在log4j.properties里配置这个自定义Layout:

log4j.rootLogger=DEBUG, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
# 指定我们自己写的Layout类路径
log4j.appender.console.layout=com.yourpackage.MicrosecondPatternLayout
# 转换规则里用%d{HH:mm:ss,SSS}输出毫秒,加.%m输出微秒
log4j.appender.console.layout.ConversionPattern=%d{HH:mm:ss,SSS}.%m [%t] %-5level %logger{36} - %msg%n

这样输出的日志时间就会是类似12:42:05,972.123456的格式,包含完整的微秒信息。


二、Log4j2 微秒输出固定值的问题解决

你遇到的%d{ABSOLUTE_NANOS}输出微秒纳秒始终是803200的问题,其实是因为这个格式符的设计缺陷——它根本没获取真实的纳秒时间,只是在毫秒时间后面硬拼了固定后缀,完全是个坑!

正确的Log4j2微秒配置方式

Log4j2本身支持直接通过自定义日期格式输出微秒,不用依赖那个有问题的ABSOLUTE_NANOS。修改你的log4j2.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <Console name="console" target="SYSTEM_OUT">
            <!-- 用自定义日期格式,SSS是毫秒,后面加6位S表示微秒 -->
            <PatternLayout pattern="%d{HH:mm:ss,SSSSSS} [%t] %-5level %logger{36} - %msg%n"/>
            <!-- 如果需要纳秒,可以写成%{HH:mm:ss,SSSSSSSSS},9位S就是纳秒 -->
        </Console>
    </Appenders>
    <Loggers>
        <Root level="debug" additivity="false">
            <AppenderRef ref="console" />
        </Root>
    </Loggers>
</Configuration>

这样配置后,输出的时间就会是真实的微秒/纳秒值,不会再出现固定后缀的问题了。

另外,如果你需要ISO8601格式带微秒的时间,也可以用:

<PatternLayout pattern="%d{yyyy-MM-dd'T'HH:mm:ss.SSSSSS} [%t] %-5level %logger{36} - %msg%n"/>

内容的提问来源于stack exchange,提问作者Chetna rustagi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:16:16