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

如何修改Java日志代码实现每次输出不同日志内容?

解决日志重复&实现自定义日志内容的方案

先搞定日志重复的问题

你的代码里日志重复的核心问题出在全局单例的Logger:Logger.getLogger("MyLog")拿到的是全局唯一实例,要是多次触发init()(比如程序重启、重复执行初始化逻辑),就会反复添加FileHandler,同一条日志会被多个Handler写入文件,自然就重复了。

1. 初始化前清掉旧Handler

在加新的FileHandler之前,先把Logger上已有的所有Handler移除,避免重复绑定:

public static void init(){
       FileHandler fh;
       try {
           // 先移除所有已绑定的处理器
           for(Handler handler : logger.getHandlers()){
               logger.removeHandler(handler);
           }
           
           fh = new FileHandler("/Users/hp/Desktop/example1.log");
           logger.addHandler(fh);
           SimpleFormatter formatter = new SimpleFormatter();
           fh.setFormatter(formatter);
           
           logger.info("Logger Initialized");
       } catch(Exception e) {
           logger.log(Level.WARNING,"Exception ::", e);
       }
   }

2. 加个开关确保初始化只跑一次

给init()加个标记,避免重复执行初始化逻辑:

private static boolean loggerReady = false;

public static void init(){
       if(loggerReady){
           return;
       }
       FileHandler fh;
       try {
           fh = new FileHandler("/Users/hp/Desktop/example1.log");
           logger.addHandler(fh);
           SimpleFormatter formatter = new SimpleFormatter();
           fh.setFormatter(formatter);
           
           logger.info("Logger Initialized");
           loggerReady = true;
       } catch(Exception e) {
           logger.log(Level.WARNING,"Exception ::", e);
       }
   }

实现自定义不同日志内容的方法

1. 动态拼日志内容

根据运行时的变量、状态生成独有的日志,比如记录时间、变量值:

// 记录当前时间
logger.info("程序启动时间:" + LocalDateTime.now());
// 记录错误码+异常信息
int errorCode = 500;
logger.warning("触发错误,错误码:" + errorCode + ",详情:除数不能为0");

2. 自定义日志格式

继承SimpleFormatter自己写格式,把线程ID、日志级别、时间戳这些信息加进去,每条日志自带唯一标识:

class CustomLogFormatter extends SimpleFormatter {
    @Override
    public String format(LogRecord record) {
        return String.format("[%s] [%s] 线程ID:%s %s%n",
                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")),
                record.getLevel().getName(),
                Thread.currentThread().getId(),
                record.getMessage());
    }
}
// 在init()里替换默认Formatter
fh.setFormatter(new CustomLogFormatter());

3. 给日志加上下文标记

用ThreadLocal存请求ID、用户ID这类上下文信息,让每条日志都带唯一标识,方便追踪:

// 定义ThreadLocal存请求ID
private static ThreadLocal<String> requestIdHolder = new ThreadLocal<>();

// 业务逻辑里设置请求ID
requestIdHolder.set(UUID.randomUUID().toString());
// 日志里带上
logger.info("请求ID:" + requestIdHolder.get() + ",处理完成");
// 用完记得清理
requestIdHolder.remove();

4. 按场景输出不同日志

针对不同异常、不同业务场景,输出差异化的日志内容,不要一概而论:

try {
    int a = 10/0;
} catch (ArithmeticException e) {
    logger.log(Level.SEVERE, "数学运算异常:除数不能为0,当前计算式:10/0", e);
} catch (NullPointerException e) {
    logger.log(Level.WARNING, "空指针异常:某对象未初始化就调用", e);
}

额外小技巧

  • 要是想让日志追加到文件末尾而不是覆盖,就用你注释掉的那个构造器:new FileHandler("/Users/hp/Desktop/example1.log", true),这样每次运行的日志都会接着之前的内容写。
  • 别在会被多次调用的方法里初始化Logger的Handler,确保初始化逻辑只执行一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:01:27