diff --git a/src/main/java/de/tosox/zonerelay/ApplicationModule.java b/src/main/java/de/tosox/zonerelay/ApplicationModule.java index 2e1a944..bb7e77d 100644 --- a/src/main/java/de/tosox/zonerelay/ApplicationModule.java +++ b/src/main/java/de/tosox/zonerelay/ApplicationModule.java @@ -83,7 +83,7 @@ UserSettings provideUserSettings(UserSettingsManager manager) { @Provides @Singleton LogManager provideLogManager(JTextPane outputPane, AppPaths paths, UserSettings settings) { - return new LogManager(outputPane, paths.getLogsDir(), settings.getLogLevel()); + return new LogManager(outputPane, paths.getLogsDir(), settings.getLogLevel(), settings.getLogRetentionCount()); } @Provides diff --git a/src/main/java/de/tosox/zonerelay/shared/config/UserSettings.java b/src/main/java/de/tosox/zonerelay/shared/config/UserSettings.java index b736c19..4849aa2 100644 --- a/src/main/java/de/tosox/zonerelay/shared/config/UserSettings.java +++ b/src/main/java/de/tosox/zonerelay/shared/config/UserSettings.java @@ -12,25 +12,30 @@ public class UserSettings { private static final String DEFAULT_LANGUAGE = "en-US"; private static final LogLevel DEFAULT_LOGLEVEL = LogLevel.INFO; private static final ArchiveCleanupStrategy DEFAULT_CLEANUP = ArchiveCleanupStrategy.KEEP_LATEST_ONLY; + private static final int DEFAULT_LOG_RETENTION_COUNT = 10; private final String language; private final LogLevel logLevel; private final ArchiveCleanupStrategy archiveCleanupStrategy; + private final int logRetentionCount; public UserSettings() { this.language = DEFAULT_LANGUAGE; this.logLevel = DEFAULT_LOGLEVEL; this.archiveCleanupStrategy = DEFAULT_CLEANUP; + this.logRetentionCount = DEFAULT_LOG_RETENTION_COUNT; } @JsonCreator public UserSettings( @JsonProperty("language") String language, @JsonProperty("logLevel") LogLevel logLevel, - @JsonProperty("archiveCleanupStrategy") ArchiveCleanupStrategy archiveCleanupStrategy) { + @JsonProperty("archiveCleanupStrategy") ArchiveCleanupStrategy archiveCleanupStrategy, + @JsonProperty("logRetentionCount") Integer logRetentionCount) { this.language = language != null ? language : DEFAULT_LANGUAGE; this.logLevel = logLevel != null ? logLevel : DEFAULT_LOGLEVEL; this.archiveCleanupStrategy = archiveCleanupStrategy != null ? archiveCleanupStrategy : DEFAULT_CLEANUP; + this.logRetentionCount = logRetentionCount != null ? logRetentionCount : DEFAULT_LOG_RETENTION_COUNT; } public static UserSettings defaults() { diff --git a/src/main/java/de/tosox/zonerelay/shared/logging/LogManager.java b/src/main/java/de/tosox/zonerelay/shared/logging/LogManager.java index 321fb2c..615f5bd 100644 --- a/src/main/java/de/tosox/zonerelay/shared/logging/LogManager.java +++ b/src/main/java/de/tosox/zonerelay/shared/logging/LogManager.java @@ -1,6 +1,7 @@ package de.tosox.zonerelay.shared.logging; import lombok.Getter; +import org.apache.commons.io.FileUtils; import javax.swing.*; import java.io.IOException; @@ -8,21 +9,24 @@ import java.nio.file.Path; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.Comparator; +import java.util.List; @Getter public class LogManager { private final Path logFolder; private final Logger fileLogger; private final Logger uiLogger; + private final int logRetentionCount; - public LogManager(JTextPane outputPane, Path logsDir, LogLevel logLevel) { + public LogManager(JTextPane outputPane, Path logsDir, LogLevel logLevel, int logRetentionCount) { + this.logRetentionCount = logRetentionCount; this.logFolder = createRunLogFolder(logsDir); this.fileLogger = new FileLogger(logFolder.resolve("app.log"), logLevel); this.uiLogger = new UILogger(outputPane); } private Path createRunLogFolder(Path baseDir) { - // TODO: Clean up log directories DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"); String folderName = "log_" + formatter.format(LocalDateTime.now()); Path folder = baseDir.resolve(folderName); @@ -31,6 +35,20 @@ private Path createRunLogFolder(Path baseDir) { } catch (IOException e) { throw new RuntimeException("Could not create log folder: " + folder, e); } + pruneOldLogFolders(baseDir); return folder; } + + private void pruneOldLogFolders(Path baseDir) { + try (var stream = Files.list(baseDir)) { + List runs = stream + .filter(p -> Files.isDirectory(p) && p.getFileName().toString().startsWith("log_")) + .sorted(Comparator.comparing(p -> p.getFileName().toString())) + .toList(); + int excess = runs.size() - logRetentionCount; + for (int i = 0; i < excess; i++) { + FileUtils.deleteDirectory(runs.get(i).toFile()); + } + } catch (IOException ignored) {} + } }