如何修改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
相关产品推荐
相关产品推荐

