需求描述:
- 每天凌晨3点清理7天前的日志文件
- 日志文件清理定时任务
代码实现
package com.yang.job;
import com.hzys.base.config.AppConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.File;
import java.util.Arrays;
import java.util.List;
/**
* 日志文件清理定时任务
* 每天凌晨3点清理7天前的日志文件
*/
@Slf4j
@Component
public class LogCleanupJob {
/**
* 清理多少天前的文件
*/
private static final int DAYS_BEFORE = 7;
/**
* 日志子目录列表
*/
private static final List<String> LOG_SUB_DIRS = Arrays.asList("debug", "info", "warn", "error");
// 从系统环境变量或JVM参数获取日志根路径,如果未设置则使用默认路径
@Value("${JAR_DIR:${user.dir}}")
private String jarDir;
@Resource
private AppConfig appConfig;
/**
* 每天凌晨3点执行日志清理
* 清理规则:删除7天前修改的日志文件
*/
// @Scheduled(cron = "0 */1 * * * ?")
@Scheduled(cron = "0 0 3 * * ?")
public void cleanupOldLogs() {
String logRootPath = jarDir + File.separator + "logs";
log.info("===== 开始执行日志文件清理任务 =====");
log.info("日志根目录: {}", logRootPath);
try {
// 计算7天前的时间戳
long sevenDaysAgo = System.currentTimeMillis() - (DAYS_BEFORE * 24 * 60 * 60 * 1000L);
int totalDeleted = 0;
int totalError = 0;
// 清理主日志目录下的文件
totalDeleted += cleanupDirectory(logRootPath, sevenDaysAgo, totalError);
// 清理各子目录下的文件
for (String subDir : LOG_SUB_DIRS) {
String subDirPath = logRootPath + File.separator + subDir;
if (appConfig.getIsDebug()) {
log.info("subDirPath is : {}", subDirPath);
}
totalDeleted += cleanupDirectory(subDirPath, sevenDaysAgo, totalError);
}
log.info("===== 日志文件清理任务完成,共删除 {} 个文件,删除失败 {} 个文件 =====", totalDeleted, totalError);
} catch (Exception e) {
log.error("执行日志文件清理任务时发生错误", e);
}
}
/**
* 清理指定目录下的过期文件
*
* @param directoryPath 目录路径
* @param expireTimeMillis 过期时间戳(毫秒)
* @param errorCount 错误计数器
* @return 删除的文件数量
*/
private int cleanupDirectory(String directoryPath, long expireTimeMillis, int errorCount) {
int deletedCount = 0;
File directory = new File(directoryPath);
if (!directory.exists() || !directory.isDirectory()) {
log.info("目录不存在或不是有效的目录: {}", directoryPath);
return deletedCount;
}
File[] files = directory.listFiles();
if (files == null) {
log.info("无法获取目录下的文件列表: {}", directoryPath);
return deletedCount;
}
for (File file : files) {
if (file.isFile() && file.lastModified() < expireTimeMillis) {
if (file.delete()) {
deletedCount++;
log.info("已删除过期日志文件: {}", file.getAbsolutePath());
} else {
errorCount++;
log.info("删除过期日志文件失败: {}", file.getAbsolutePath());
}
}
}
return deletedCount;
}
}
