LogCleanupJob.java 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package com.zsElectric.boot.system.quartz;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.beans.factory.annotation.Value;
  4. import org.springframework.scheduling.annotation.Scheduled;
  5. import org.springframework.stereotype.Component;
  6. import java.io.IOException;
  7. import java.nio.file.Files;
  8. import java.nio.file.Path;
  9. import java.nio.file.Paths;
  10. import java.nio.file.attribute.BasicFileAttributes;
  11. import java.time.Instant;
  12. import java.time.temporal.ChronoUnit;
  13. import java.util.stream.Stream;
  14. /**
  15. * 日志文件清理定时任务
  16. * 定期清理超过指定天数的历史日志文件
  17. *
  18. * @author zsElectric
  19. * @since 2026-01-06
  20. */
  21. @Slf4j
  22. @Component
  23. public class LogCleanupJob {
  24. @Value("${spring.application.name:zsElectric-boot}")
  25. private String appName;
  26. /**
  27. * 日志保留天数
  28. */
  29. private static final int LOG_RETENTION_DAYS = 30;
  30. /**
  31. * 日志目录
  32. */
  33. private static final String LOG_BASE_PATH = "/logs";
  34. /**
  35. * 每天凌晨3点执行一次
  36. * 清理超过30天的日志文件
  37. */
  38. @Scheduled(cron = "0 0 3 * * ?")
  39. public void cleanupExpiredLogs() {
  40. log.info("开始执行日志清理任务,清理{}天前的日志文件", LOG_RETENTION_DAYS);
  41. Path logDir = Paths.get(LOG_BASE_PATH, appName);
  42. if (!Files.exists(logDir)) {
  43. log.warn("日志目录不存在: {}", logDir);
  44. return;
  45. }
  46. Instant cutoffTime = Instant.now().minus(LOG_RETENTION_DAYS, ChronoUnit.DAYS);
  47. int deletedCount = 0;
  48. int failedCount = 0;
  49. try (Stream<Path> files = Files.list(logDir)) {
  50. for (Path file : (Iterable<Path>) files::iterator) {
  51. // 只处理 .log 文件,跳过当前正在写入的日志文件
  52. String fileName = file.getFileName().toString();
  53. if (!fileName.endsWith(".log") || fileName.equals("log.log")) {
  54. continue;
  55. }
  56. try {
  57. BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
  58. Instant lastModified = attrs.lastModifiedTime().toInstant();
  59. if (lastModified.isBefore(cutoffTime)) {
  60. Files.delete(file);
  61. deletedCount++;
  62. log.debug("已删除过期日志文件: {}", fileName);
  63. }
  64. } catch (IOException e) {
  65. failedCount++;
  66. log.error("删除日志文件失败: {}", fileName, e);
  67. }
  68. }
  69. } catch (IOException e) {
  70. log.error("读取日志目录失败: {}", logDir, e);
  71. }
  72. log.info("日志清理任务执行完成,成功删除{}个文件,失败{}个", deletedCount, failedCount);
  73. }
  74. }