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存在两处编译错误,需修正:
- 变量声明为
_pattern,但创建FileHandler时误用了pattern,变量名不匹配; 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
相关产品推荐
相关产品推荐

