例如在进行如下配置:
<rollingPolicy class="">
<!-- 路径 /www/wwwroot/-->
<fileNamePattern>${LOG_HOME}/sc-logs/.%</fileNamePattern>
<maxHistory>30</maxHistory>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
在TimeBasedRollingPolicy类中调用日志清理
//服务启动时执行日志清理
if (cleanHistoryOnStart) {
addInfo("Cleaning on start up");
Date now = new Date(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime());
cleanUpFuture = archiveRemover.cleanAsynchronously(now);
}
调用TimeBasedArchiveRemover类异步清理
public class ArhiveRemoverRunnable implements Runnable {
Date now;
ArhiveRemoverRunnable(Date now) {
this.now = now;
}
//异步进行日志清理
@Override
public void run() {
clean(now);
if (totalSizeCap != UNBOUNDED_TOTAL_SIZE_CAP && totalSizeCap > 0) {
capTotalSize(now);
}
}
}
计算要删除日志的日期,并匹配日志文件进行删除
int callCount = 0;
public void clean(Date now) {
long nowInMillis = now.getTime();
// for a live appender periodsElapsed is expected to be 1
int periodsElapsed = computeElapsedPeriodsSinceLastClean(nowInMillis);
lastHeartBeat = nowInMillis;
if (periodsElapsed > 1) {
addInfo("Multiple periods, . " + periodsElapsed + " periods, seem to have elapsed. This is expected at application start.");
}
for (int i = 0; i < periodsElapsed; i++) {
int offset = getPeriodOffsetForDeletionTarget() - i;
//获取需要删除的日志日期 如今天是2022-09-15 maxHistory为30 则dateOfPeriodToClean是从2022-08-15到2022-07-15 过早的日志则需要手动删除
Date dateOfPeriodToClean = rc.getEndOfNextNthPeriod(now, offset);
cleanPeriod(dateOfPeriodToClean);
}
}
public void cleanPeriod(Date dateOfPeriodToClean) {
//根据日期获取要清理的文件
File[] matchingFileArray = getFilesInPeriod(dateOfPeriodToClean);
//删除匹配到的文件
for (File f : matchingFileArray) {
addInfo("deleting " + f);
f.delete();
}
if (parentClean && matchingFileArray.length > 0) {
File parentDir = getParentDir(matchingFileArray[0]);
removeFolderIfEmpty(parentDir);
}
}
结论:
如果要在项目启动时就删除历史日志文件,需要在中添加true
另外,过于古老的日志是无法自动清除的,如今天是2022-09-15 maxHistory为30 则日志删除的范围是从 2022-07-15 到 2022-08-15 ,过早的日志则需要手动删除