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

Java日志自定义Formatter问题:日志行未显示指定时间格式

问题原因

你把日期格式化逻辑放在了getHead()方法中,但这个方法只会在Handler初始化或者轮转新日志文件时执行一次,不会为每条日志记录添加前缀,所以每行日志开头没有日期。

修复方案

修改CustomFormatter的format()方法,在每条日志内容前添加格式化后的日期时间。另外注意SimpleDateFormat不是线程安全的,日志系统通常会在多线程环境下运行,建议用ThreadLocal包装它,或者使用Java 8+提供的线程安全的DateTimeFormatter。

方案1:使用ThreadLocal包装SimpleDateFormat(兼容Java 7及以下)

public class CustomFormatter extends Formatter {
    private final ThreadLocal<SimpleDateFormat> sdf = ThreadLocal.withInitial(
        () -> new SimpleDateFormat("MM-dd-yyyy HH:mm:ss")
    );

    @Override
    public String format(LogRecord rec) {
        StringBuffer buf = new StringBuffer(1000);
        // 在日志内容前添加日期时间,使用日志记录的时间戳更准确
        buf.append(sdf.get().format(new Date(rec.getMillis())))
           .append(": \t")
           .append(formatMessage(rec))
           .append("\n");
        return buf.toString();
    }

    @Override
    public String getHead(Handler h) {
        return "";
    }

    @Override
    public String getTail(Handler h) {
        return "";
    }
}

方案2:使用Java 8+的DateTimeFormatter(推荐)

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class CustomFormatter extends Formatter {
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss");

    @Override
    public String format(LogRecord rec) {
        StringBuffer buf = new StringBuffer(1000);
        // 基于日志记录的时间戳生成格式化时间
        LocalDateTime logTime = LocalDateTime.ofInstant(
            rec.getInstant(), ZoneId.systemDefault()
        );
        buf.append(FORMATTER.format(logTime))
           .append(": \t")
           .append(formatMessage(rec))
           .append("\n");
        return buf.toString();
    }

    @Override
    public String getHead(Handler h) {
        return "";
    }

    @Override
    public String getTail(Handler h) {
        return "";
    }
}
主类代码的小问题修复

你的Main.java存在两处编译错误,需修正:

  1. 变量声明为_pattern,但创建FileHandler时误用了pattern,变量名不匹配;
  2. fh在try块内部声明,外部的fh.close()会找不到变量。

修正后的Main.java:

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

private static Logger logger = Logger.getLogger("org.somecompany.someproject");

public static void main(String[] args){
    FileHandler fh = null;
    try{
        String pattern = "myLogger.log.%g";
        int numLogFiles = 10;
        int fileSize = 1000000;
        boolean appendToFile = true;
        fh = new FileHandler(pattern, fileSize, numLogFiles, appendToFile);

        fh.setFormatter(new CustomFormatter());
        logger.addHandler(fh);
        logger.setLevel(Level.ALL);
    } catch(IOException i) { 
        System.out.println("Unable to init logger");
    }

    logger.info("Begin");
    logger.info("Line 1");
    logger.info("Line 2");
    logger.info("End");

    if(fh != null) {
        fh.close();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 05:10:20