Log4j动态添加Appender导致日志语句重复递增问题求助
解决Log4j日志重复写入的问题
我一眼就看出问题所在了——你那个loggerCustom是static的,而且每次程序运行(每20秒一次)都会执行loggerCustom.addAppender(fh)。这就相当于每跑一次就给同一个Logger多塞一个FileAppender进去,Logger输出日志的时候会遍历所有绑定的Appender,所以第一次1个Appender写1条,第二次2个写2条,次数自然越来越多。重启程序后static变量重置,所以一开始正常,运行久了就出问题。
给你几个针对性的解决方案,结合你的代码来改:
方案1:避免重复添加相同的Appender
每次添加Appender前,先检查Logger里是否已经存在对应路径的FileAppender,只有不存在的时候才添加:
static Logger loggerCustom = Logger.getLogger("CustomLog"); // 你的定时任务执行代码里 PatternLayout plt = new PatternLayout(); plt.setConversionPattern("%-7p %d [%t] %c %x - %m%n"); String logFilePath = "logs\\" + strDate + "\\CustomLog.log"; // 遍历已有的Appender,检查是否存在目标文件的Appender boolean hasTargetAppender = false; Enumeration<?> appenders = loggerCustom.getAllAppenders(); while (appenders.hasMoreElements()) { Appender appender = (Appender) appenders.nextElement(); if (appender instanceof FileAppender) { FileAppender fileAppender = (FileAppender) appender; if (logFilePath.equals(fileAppender.getFile())) { hasTargetAppender = true; break; } } } if (!hasTargetAppender) { FileAppender fh = new FileAppender(plt, logFilePath); // 给Appender设置唯一名称,方便后续识别管理 fh.setName("CustomLogAppender_" + strDate); loggerCustom.addAppender(fh); loggerCustom.setAdditivity(false); }
方案2:更新日志文件时先移除旧Appender
如果你的strDate会变化(比如按天生成新日志文件),每次运行时先移除旧的Appender,再添加新的:
static Logger loggerCustom = Logger.getLogger("CustomLog"); // 你的定时任务执行代码里 PatternLayout plt = new PatternLayout(); plt.setConversionPattern("%-7p %d [%t] %c %x - %m%n"); String logFilePath = "logs\\" + strDate + "\\CustomLog.log"; final String APPENDER_NAME = "DynamicCustomAppender"; // 先移除并关闭旧的Appender,避免资源泄漏 Appender oldAppender = loggerCustom.getAppender(APPENDER_NAME); if (oldAppender != null) { oldAppender.close(); loggerCustom.removeAppender(oldAppender); } // 添加新的Appender FileAppender fh = new FileAppender(plt, logFilePath); fh.setName(APPENDER_NAME); loggerCustom.addAppender(fh); loggerCustom.setAdditivity(false);
额外注意事项
- 记得关闭旧的FileAppender,不然会占用文件句柄,导致资源泄漏。
- 如果是多线程环境下的定时任务,最好给Logger的操作加个同步锁,避免并发添加/移除Appender出现问题。
- 也可以考虑把Logger的初始化逻辑放到静态代码块里,确保只执行一次,但这种方式不适合动态变更日志文件的场景。
内容的提问来源于stack exchange,提问作者amitabh pandey
相关产品推荐
相关产品推荐

