diff --git a/Logger.cs b/Logger.cs
index f39301b..d0e8b0f 100644
--- a/Logger.cs
+++ b/Logger.cs
@@ -41,7 +41,9 @@ public static void Initialize(string logDirectory, string version = "Unknown", b
}
LogFile = Path.Combine(logDirectory, $"{DateTime.Now:yyyy-MM-dd-HHmmss}.log");
-
+
+ PruneExpiredLogs(logDirectory);
+
// Write session header to log file
WriteToFile("=== BootstrapMate Session Started ===");
WriteToFile($"Version: {version}");
@@ -68,6 +70,52 @@ public static void Initialize(string logDirectory, string version = "Unknown", b
}
}
+ ///
+ /// Deletes logs in older than the retention
+ /// window. Every run writes a new timestamped file and nothing has ever removed
+ /// one, so on a machine that has been enrolled for a year the directory holds
+ /// hundreds of them.
+ ///
+ ///
+ /// Age comes from the file's last write time rather than its name: the directory
+ /// also collects logs written by wrapper scripts, which do not follow the
+ /// timestamped naming, and those need expiring too.
+ ///
+ internal static void PruneExpiredLogs(string logDirectory, int? retentionDays = null)
+ {
+ var days = retentionDays ?? BootstrapMate.Core.BootstrapMateConstants.LogRetentionDays;
+ if (days <= 0)
+ {
+ return;
+ }
+
+ try
+ {
+ var cutoff = DateTime.Now.AddDays(-days);
+
+ foreach (var file in Directory.GetFiles(logDirectory, "*.log"))
+ {
+ try
+ {
+ var info = new FileInfo(file);
+ if (info.LastWriteTime < cutoff)
+ {
+ info.Delete();
+ }
+ }
+ catch
+ {
+ // A log still held open elsewhere throws here. Skip it and try
+ // again next run rather than aborting the sweep.
+ }
+ }
+ }
+ catch
+ {
+ // Retention is best-effort and must never stop a bootstrap run.
+ }
+ }
+
public static void Debug(string message)
{
Log(LogLevel.Debug, message);
diff --git a/src/BootstrapMate.Core/BootstrapMateConstants.cs b/src/BootstrapMate.Core/BootstrapMateConstants.cs
index 3279ac7..d30c8f3 100644
--- a/src/BootstrapMate.Core/BootstrapMateConstants.cs
+++ b/src/BootstrapMate.Core/BootstrapMateConstants.cs
@@ -29,6 +29,12 @@ public static class BootstrapMateConstants
/// Log file directory.
public const string LogDirectory = @"C:\ProgramData\ManagedBootstrap\logs";
+ ///
+ /// How long session logs are kept. Every run writes a new timestamped file, so
+ /// without a window the directory grows for the life of the machine.
+ ///
+ public const int LogRetentionDays = 30;
+
/// Cache directory for downloaded packages.
public const string CacheDirectory = @"C:\ProgramData\ManagedBootstrap\cache";