瀏覽代碼

feat(logs): 增加日志文件自动清理功能

- 将日志总大小上限从1GB提升至3GB
- 配置应用启动时自动清理过期日志
- 新增定时任务LogCleanupJob,每天凌晨3点清理30天前日志文件
- 实现对日志文件的过期判断及删除,并记录删除结果
- 提供日志目录不存在及文件删除失败的错误处理和日志输出
wzq 3 周之前
父節點
當前提交
381f97d5e7

+ 88 - 0
src/main/java/com/zsElectric/boot/system/quartz/LogCleanupJob.java

@@ -0,0 +1,88 @@
+package com.zsElectric.boot.system.quartz;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.stream.Stream;
+
+/**
+ * 日志文件清理定时任务
+ * 定期清理超过指定天数的历史日志文件
+ *
+ * @author zsElectric
+ * @since 2026-01-06
+ */
+@Slf4j
+@Component
+public class LogCleanupJob {
+
+    @Value("${spring.application.name:zsElectric-boot}")
+    private String appName;
+
+    /**
+     * 日志保留天数
+     */
+    private static final int LOG_RETENTION_DAYS = 30;
+
+    /**
+     * 日志目录
+     */
+    private static final String LOG_BASE_PATH = "/logs";
+
+    /**
+     * 每天凌晨3点执行一次
+     * 清理超过30天的日志文件
+     */
+    @Scheduled(cron = "0 0 3 * * ?")
+    public void cleanupExpiredLogs() {
+        log.info("开始执行日志清理任务,清理{}天前的日志文件", LOG_RETENTION_DAYS);
+
+        Path logDir = Paths.get(LOG_BASE_PATH, appName);
+
+        if (!Files.exists(logDir)) {
+            log.warn("日志目录不存在: {}", logDir);
+            return;
+        }
+
+        Instant cutoffTime = Instant.now().minus(LOG_RETENTION_DAYS, ChronoUnit.DAYS);
+        int deletedCount = 0;
+        int failedCount = 0;
+
+        try (Stream<Path> files = Files.list(logDir)) {
+            for (Path file : (Iterable<Path>) files::iterator) {
+                // 只处理 .log 文件,跳过当前正在写入的日志文件
+                String fileName = file.getFileName().toString();
+                if (!fileName.endsWith(".log") || fileName.equals("log.log")) {
+                    continue;
+                }
+
+                try {
+                    BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
+                    Instant lastModified = attrs.lastModifiedTime().toInstant();
+
+                    if (lastModified.isBefore(cutoffTime)) {
+                        Files.delete(file);
+                        deletedCount++;
+                        log.debug("已删除过期日志文件: {}", fileName);
+                    }
+                } catch (IOException e) {
+                    failedCount++;
+                    log.error("删除日志文件失败: {}", fileName, e);
+                }
+            }
+        } catch (IOException e) {
+            log.error("读取日志目录失败: {}", logDir, e);
+        }
+
+        log.info("日志清理任务执行完成,成功删除{}个文件,失败{}个", deletedCount, failedCount);
+    }
+}

+ 3 - 1
src/main/resources/logback-spring.xml

@@ -39,7 +39,9 @@
             <!-- 最大保留30天的日志 -->
             <maxHistory>30</maxHistory>
             <!-- 总日志文件大小不超过3GB -->
-            <totalSizeCap>1GB</totalSizeCap>
+            <totalSizeCap>3GB</totalSizeCap>
+            <!-- 应用启动时清理过期日志 -->
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
         </rollingPolicy>
         <!-- 临界值过滤器,输出大于INFO级别日志 -->
         <filter class="ch.qos.logback.classic.filter.ThresholdFilter">