From 174fb4a0560f3d0d3f7387818b98cec62d33a276 Mon Sep 17 00:00:00 2001 From: kevincw01 <455203+kevincw01@users.noreply.github.com> Date: Mon, 20 Jul 2026 02:18:22 +0000 Subject: [PATCH] Add independent FileLogLevels config for disk logging ServerLogger currently gates both the dashboard's live log entry list and the on-disk log file with a single level check (LogLevels), so lowering verbosity to reduce disk writes also removes entries from the live dashboard, and vice versa. Add an optional FileLogLevels dictionary to ServerLoggerConfiguration, mirroring the existing LogLevels dictionary. When set, it independently gates the StoreInFile() call in StoreLogEntry(), separate from what's shown on the dashboard. When left empty (the default), file writing falls back to the existing LogLevels set, preserving current behavior for anyone not using the new option. This lets, e.g., Information+ show on the dashboard while only Warning+ is written to disk. --- src/server/Logging/ServerLogger.cs | 29 ++++++++++++++++++++++++++--- src/server/appsettings.json | 12 +++++++++--- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/server/Logging/ServerLogger.cs b/src/server/Logging/ServerLogger.cs index 5fb01921..9e91c5f7 100644 --- a/src/server/Logging/ServerLogger.cs +++ b/src/server/Logging/ServerLogger.cs @@ -41,6 +41,16 @@ public class ServerLoggerConfiguration { [LogLevel.Information] = ConsoleColor.Green }; + + /// + /// The set of logging levels that are written to the log file on disk. This is + /// independent of LogLevels above (which gates both the dashboard's live entry list and + /// the file write) -- if this dictionary is non-empty, only levels present as keys here + /// are written to disk, while the dashboard continues to show everything permitted by + /// LogLevels. If this dictionary is empty (the default), file writing falls back to the + /// same set as LogLevels, preserving the original behaviour. + /// + public Dictionary FileLogLevels { get; set; } = new(); } /// @@ -214,7 +224,7 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, category = category, label = label, exception = exception?.ToString() ?? string.Empty - }); + }, logLevel); } /// @@ -222,7 +232,10 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, /// "writes to file". /// /// - private void StoreLogEntry(LogEntry entry) + /// The log level of this entry, used to independently gate whether + /// it's written to the file (see FileLogLevels on ServerLoggerConfiguration) separately + /// from whether it's added to the in-memory list the dashboard reads from. + private void StoreLogEntry(LogEntry entry, LogLevel logLevel) { // This used to be locked, but Lists are *so* fast that we're not going to be able to // cause lock contention. Even if we do, it's non critical. Just move on. @@ -240,7 +253,17 @@ private void StoreLogEntry(LogEntry entry) } catch { } - StoreInFile(entry); + _config ??= _getCurrentConfig(); + + // Empty FileLogLevels means "not configured" -- fall back to the same set as + // LogLevels, preserving the original (pre-patch) behaviour of writing everything + // that's shown live to the file as well. + bool writeToFile = _config.FileLogLevels.Count == 0 + ? _config.LogLevels.ContainsKey(logLevel) + : _config.FileLogLevels.ContainsKey(logLevel); + + if (writeToFile) + StoreInFile(entry); } private void StoreInFile(LogEntry logEntry) diff --git a/src/server/appsettings.json b/src/server/appsettings.json index 8bd3450b..b23cbb06 100644 --- a/src/server/appsettings.json +++ b/src/server/appsettings.json @@ -5,7 +5,7 @@ // will be logged. The order of log levels is: // Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5, and None = 6. "LogLevel": { - "Default": "Trace", + "Default": "Information", "Microsoft": "Error", "System": "Error" }, @@ -16,12 +16,18 @@ "FileTemplate": "log-%Y-%m-%d.txt", // Template for daily logging file "MaxLogsToStoreMB": 20, // Maximum amount of logs to store in MB. Once this is hit old log files get dumped (not trimmed, dumped) "LogLevels": { - "Debug": "Yellow", - "Trace": "Gray", "Information": "White", "Warning": "Cyan", "Error": "Red", "Critical": "Magenta" + }, + // Independent gate for what gets written to disk (see FileLogLevels on + // ServerLoggerConfiguration). If empty, falls back to LogLevels above. Colors here are + // unused for file output but kept as the dictionary value type for consistency. + "FileLogLevels": { + "Warning": "Cyan", + "Error": "Red", + "Critical": "Magenta" } } },