From bac2d614a9346207e5f0c44106d9a26172bdd8fb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Nov 2023 16:16:11 +0900 Subject: [PATCH 1/7] Add a session timestamp prefix to log files --- osu.Framework/Logging/Logger.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/osu.Framework/Logging/Logger.cs b/osu.Framework/Logging/Logger.cs index ffe863113c..b6d83e927c 100644 --- a/osu.Framework/Logging/Logger.cs +++ b/osu.Framework/Logging/Logger.cs @@ -23,11 +23,19 @@ public class Logger { private static readonly object static_sync_lock = new object(); - // separate locking object for flushing so that we don't lock too long on the staticSyncLock object, since we have to - // hold this lock for the entire duration of the flush (waiting for I/O etc) before we can resume scheduling logs - // but other operations like GetLogger(), ApplyFilters() etc. can still be executed while a flush is happening. + /// + /// Separate locking object for flushing so that we don't lock too long on the staticSyncLock object, since we have to + /// hold this lock for the entire duration of the flush (waiting for I/O etc) before we can resume scheduling logs + /// but other operations like GetLogger(), ApplyFilters() etc. can still be executed while a flush is happening. + /// private static readonly object flush_sync_lock = new object(); + /// + /// Logs are stored with a consistent unix timestamp prefix per session (across all loggers) for logical grouping of + /// log files on disk. + /// + private static readonly long session_startup_timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + /// /// Whether logging is enabled. Setting this to false will disable all logging. /// @@ -83,7 +91,7 @@ public static Storage Storage /// /// Gets the name of the file that this logger is logging to. /// - public string Filename => $@"{Name}.log"; + public string Filename { get; } public int TotalLogOperations => logCount.Value; @@ -109,6 +117,7 @@ private Logger(string name, bool checkedReserved) Name = name; logCount = GlobalStatistics.Get(nameof(Logger), Name); + Filename = $"{session_startup_timestamp}.{Name}.log"; } /// From 1dd4f15df0e8ed8a14eb1e221d5ad668e648397a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Nov 2023 16:20:15 +0900 Subject: [PATCH 2/7] Remove unnecessary deleting of previous log file --- osu.Framework/Logging/Logger.cs | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/osu.Framework/Logging/Logger.cs b/osu.Framework/Logging/Logger.cs index b6d83e927c..d7db8d5fd5 100644 --- a/osu.Framework/Logging/Logger.cs +++ b/osu.Framework/Logging/Logger.cs @@ -266,10 +266,7 @@ public static Logger GetLogger(string name) string nameLower = name.ToLowerInvariant(); if (!static_loggers.TryGetValue(nameLower, out Logger l)) - { static_loggers[nameLower] = l = Enum.TryParse(name, true, out LoggingTarget target) ? new Logger(target) : new Logger(name, true); - l.clear(); - } return l; } @@ -418,28 +415,6 @@ private void writePendingLines() /// public static event Action NewEntry; - /// - /// Deletes log file from disk. - /// - private void clear() - { - lock (flush_sync_lock) - { - scheduler.Add(() => - { - try - { - Storage.Delete(Filename); - } - catch - { - // may fail if the file/directory was already cleaned up, ie. during test runs. - } - }); - writer_idle.Reset(); - } - } - private bool headerAdded; private void ensureHeader() From 270c7f43741ef769f31135671f24a8ab51a2d499 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Nov 2023 16:29:58 +0900 Subject: [PATCH 3/7] Cycle logs at startup (keeping 7 days) --- osu.Framework/Logging/Logger.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Framework/Logging/Logger.cs b/osu.Framework/Logging/Logger.cs index d7db8d5fd5..4dbf4ef7d1 100644 --- a/osu.Framework/Logging/Logger.cs +++ b/osu.Framework/Logging/Logger.cs @@ -73,8 +73,17 @@ public static Storage Storage { storage = value ?? throw new ArgumentNullException(nameof(value)); - // clear static loggers so they are correctly purged at the new storage location. + // clear static loggers so they are correctly initialised at the new storage location. static_loggers.Clear(); + + DateTime logCycleCutoff = DateTime.UtcNow.AddDays(-7); + var logFiles = new DirectoryInfo(storage.GetFullPath(string.Empty)).GetFiles(); + + foreach (var fileInfo in logFiles) + { + if (fileInfo.CreationTimeUtc < logCycleCutoff) + fileInfo.Delete(); + } } } From ea53982c4577116469c671a55f5376f4b33c59f9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Nov 2023 16:38:08 +0900 Subject: [PATCH 4/7] Remove static logger clearing Keeping this would cause the header to be output multiple times. --- osu.Framework/Logging/Logger.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Framework/Logging/Logger.cs b/osu.Framework/Logging/Logger.cs index 4dbf4ef7d1..b188059965 100644 --- a/osu.Framework/Logging/Logger.cs +++ b/osu.Framework/Logging/Logger.cs @@ -73,9 +73,6 @@ public static Storage Storage { storage = value ?? throw new ArgumentNullException(nameof(value)); - // clear static loggers so they are correctly initialised at the new storage location. - static_loggers.Clear(); - DateTime logCycleCutoff = DateTime.UtcNow.AddDays(-7); var logFiles = new DirectoryInfo(storage.GetFullPath(string.Empty)).GetFiles(); From cdcddadddedc40dc09d59cfa07a2394875389bb3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Nov 2023 17:07:13 +0900 Subject: [PATCH 5/7] Catch any and all errors taht could occur when cycling logs --- osu.Framework/Logging/Logger.cs | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/osu.Framework/Logging/Logger.cs b/osu.Framework/Logging/Logger.cs index b188059965..fb73019012 100644 --- a/osu.Framework/Logging/Logger.cs +++ b/osu.Framework/Logging/Logger.cs @@ -73,14 +73,7 @@ public static Storage Storage { storage = value ?? throw new ArgumentNullException(nameof(value)); - DateTime logCycleCutoff = DateTime.UtcNow.AddDays(-7); - var logFiles = new DirectoryInfo(storage.GetFullPath(string.Empty)).GetFiles(); - - foreach (var fileInfo in logFiles) - { - if (fileInfo.CreationTimeUtc < logCycleCutoff) - fileInfo.Delete(); - } + cycleLogs(); } } @@ -423,6 +416,25 @@ private void writePendingLines() private bool headerAdded; + private static void cycleLogs() + { + try + { + DateTime logCycleCutoff = DateTime.UtcNow.AddDays(-7); + var logFiles = new DirectoryInfo(storage.GetFullPath(string.Empty)).GetFiles(); + + foreach (var fileInfo in logFiles) + { + if (fileInfo.CreationTimeUtc < logCycleCutoff) + fileInfo.Delete(); + } + } + catch (Exception e) + { + Log($"Cycling logs failed ({e})"); + } + } + private void ensureHeader() { if (headerAdded) return; From 03bbab7f0c9170a50a4adf551caea2f2e8d64dbc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Nov 2023 17:57:19 +0900 Subject: [PATCH 6/7] Make `Logger.Storage` publicly accessible --- osu.Framework/Logging/Logger.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Framework/Logging/Logger.cs b/osu.Framework/Logging/Logger.cs index fb73019012..5766dc8e89 100644 --- a/osu.Framework/Logging/Logger.cs +++ b/osu.Framework/Logging/Logger.cs @@ -68,7 +68,7 @@ public class Logger /// public static Storage Storage { - private get => storage; + get => storage; set { storage = value ?? throw new ArgumentNullException(nameof(value)); From 3c917b64ae0ce42c0832d4c0589932c886eb5227 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Nov 2023 19:09:03 +0900 Subject: [PATCH 7/7] Only delete `.log` files --- osu.Framework/Logging/Logger.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Framework/Logging/Logger.cs b/osu.Framework/Logging/Logger.cs index 5766dc8e89..d35f536d2a 100644 --- a/osu.Framework/Logging/Logger.cs +++ b/osu.Framework/Logging/Logger.cs @@ -421,7 +421,7 @@ private static void cycleLogs() try { DateTime logCycleCutoff = DateTime.UtcNow.AddDays(-7); - var logFiles = new DirectoryInfo(storage.GetFullPath(string.Empty)).GetFiles(); + var logFiles = new DirectoryInfo(storage.GetFullPath(string.Empty)).GetFiles("*.log"); foreach (var fileInfo in logFiles) {