由于log4j仅在appender是RollingFileAppender时maxBackupIndex才有效;所以本文根据自己的需要, 扩展log4j自带的DailyRollingFileAppender,增加对maxBackupIndex参数的支持。
注意:需要重写DailyRollingFileAppender的rollOver方法,但是此方法是default的,所以需要建一个同名包才能继承重写这个方法,即项目结构应该如下图,使用与DailyRollingFileAppender完全相同:
完整代码如下:
/**
* @Description: 扩展DailyRollingFileAppender,增加对 maxBackupIndex参数的支持
* @Author: Li - Robin
* @Date: 2021/2/19 14:52
*/
public class DailyRollingFileAppender2 extends DailyRollingFileAppender {
/**
* 保留的备份文件个数(最近几个)
*/
protected int maxBackupIndex;
public void setMaxBackupIndex(int maxBackupIndex) {
this.maxBackupIndex = maxBackupIndex;
}
public int getMaxBackupIndex() {
return maxBackupIndex;
}
@Override
public void activateOptions() {
super.activateOptions();
//无特殊处理,仅仅打印下maxBackupIndex
if (this.maxBackupIndex != 0) {
LogLog.debug("Appender maxBackupIndex=" + maxBackupIndex);
}
}
/**
* 在原来的滚动生成规则上增加文件个数判断,删除多余的文件
*
* @throws IOException
*/
@Override
void rollOver() throws IOException {
super.rollOver();
if (this.maxBackupIndex <= 0) {
return;
}
File file = new File(this.fileName);
String simpleFileName = file.getName();
File parentPath = new File(file.getParent());
// check path
if (!parentPath.exists()) {
LogLog.error("Appender file: " + fileName + " don't exist");
return;
}
AtomicInteger fileCount = new AtomicInteger(this.maxBackupIndex);
try (Stream<File> files = Stream.of(parentPath.listFiles())) {
//过滤出以simpleFileName 开头的文件,且不包含simpleFileName 本身
files.filter(logFile -> !logFile.getName().equals(simpleFileName) && logFile.getName().startsWith(simpleFileName))
//按照修改时间倒叙
.sorted((l1, l2) -> Long.valueOf(l2.lastModified()).compareTo(l1.lastModified()))
//保留前 maxBackupIndex 个文件
.forEach(logFile -> {
if (fileCount.getAndDecrement() > 0) {
//保留最近的文件
return;
}
try {
//删除多余的文件
logFile.delete();
} catch (Exception e) {
e.printStackTrace();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}