From cb6fcb0450da28607e1a7307f5638cccbd6ce9f7 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 6 Jun 2022 21:46:21 -0400 Subject: rework VerboseLogging option to allow enabling for specific mods --- src/SMAPI/Framework/Logging/LogManager.cs | 19 ++++++++++--------- src/SMAPI/Framework/Models/SConfig.cs | 17 ++++++++++------- src/SMAPI/Framework/SCore.cs | 8 ++++---- src/SMAPI/SMAPI.config.json | 12 ++++++++++-- 4 files changed, 34 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index ed5b6959..d811ed5c 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -31,8 +31,8 @@ namespace StardewModdingAPI.Framework.Logging /// Prefixing a low-level message with this character indicates that the console interceptor should write the string without intercepting it. (The character itself is not written.) private const char IgnoreChar = InterceptingTextWriter.IgnoreChar; - /// Get a named monitor instance. - private readonly Func GetMonitorImpl; + /// Create a monitor instance given the ID and name. + private readonly Func GetMonitorImpl; /// Regex patterns which match console non-error messages to suppress from the console and log. private readonly Regex[] SuppressConsolePatterns = @@ -88,23 +88,23 @@ namespace StardewModdingAPI.Framework.Logging /// The log file path to write. /// The colors to use for text written to the SMAPI console. /// Whether to output log messages to the console. - /// Whether verbose logging is enabled. This enables more detailed diagnostic messages than are normally needed. + /// The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting. /// Whether to enable full console output for developers. /// Get the screen ID that should be logged to distinguish between players in split-screen mode, if any. - public LogManager(string logPath, ColorSchemeConfig colorConfig, bool writeToConsole, bool isVerbose, bool isDeveloperMode, Func getScreenIdForLog) + public LogManager(string logPath, ColorSchemeConfig colorConfig, bool writeToConsole, HashSet verboseLogging, bool isDeveloperMode, Func getScreenIdForLog) { // init log file this.LogFile = new LogFileManager(logPath); // init monitor - this.GetMonitorImpl = name => new Monitor(name, LogManager.IgnoreChar, this.LogFile, colorConfig, isVerbose, getScreenIdForLog) + this.GetMonitorImpl = (id, name) => new Monitor(name, LogManager.IgnoreChar, this.LogFile, colorConfig, verboseLogging.Contains("*") || verboseLogging.Contains(id), getScreenIdForLog) { WriteToConsole = writeToConsole, ShowTraceInConsole = isDeveloperMode, ShowFullStampInConsole = isDeveloperMode }; - this.Monitor = this.GetMonitor("SMAPI"); - this.MonitorForGame = this.GetMonitor("game"); + this.Monitor = this.GetMonitor("SMAPI", "SMAPI"); + this.MonitorForGame = this.GetMonitor("game", "game"); // redirect direct console output this.ConsoleInterceptor = new InterceptingTextWriter( @@ -124,10 +124,11 @@ namespace StardewModdingAPI.Framework.Logging } /// Get a monitor instance derived from SMAPI's current settings. + /// The unique ID for the mod context. /// The name of the module which will log messages with this instance. - public Monitor GetMonitor(string name) + public Monitor GetMonitor(string id, string name) { - return this.GetMonitorImpl(name); + return this.GetMonitorImpl(id, name); } /// Set the title of the SMAPI console window. diff --git a/src/SMAPI/Framework/Models/SConfig.cs b/src/SMAPI/Framework/Models/SConfig.cs index 316f7ac3..240af002 100644 --- a/src/SMAPI/Framework/Models/SConfig.cs +++ b/src/SMAPI/Framework/Models/SConfig.cs @@ -20,7 +20,6 @@ namespace StardewModdingAPI.Framework.Models [nameof(UseBetaChannel)] = Constants.ApiVersion.IsPrerelease(), [nameof(GitHubProjectName)] = "Pathoschild/SMAPI", [nameof(WebApiBaseUrl)] = "https://smapi.io/api/", - [nameof(VerboseLogging)] = false, [nameof(LogNetworkTraffic)] = false, [nameof(RewriteMods)] = true, [nameof(UsePintail)] = true, @@ -57,8 +56,9 @@ namespace StardewModdingAPI.Framework.Models /// The base URL for SMAPI's web API, used to perform update checks. public string WebApiBaseUrl { get; } - /// Whether SMAPI should log more information about the game context. - public bool VerboseLogging { get; } + /// The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting. + /// The possible values are "*" (everything is verbose), "SMAPI", (SMAPI itself), or mod IDs. + public HashSet VerboseLogging { get; } /// Whether SMAPI should rewrite mods for compatibility. public bool RewriteMods { get; } @@ -89,14 +89,14 @@ namespace StardewModdingAPI.Framework.Models /// Whether to show beta versions as valid updates. /// SMAPI's GitHub project name, used to perform update checks. /// The base URL for SMAPI's web API, used to perform update checks. - /// Whether SMAPI should log more information about the game context. + /// The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting. /// Whether SMAPI should rewrite mods for compatibility. /// Whether to use the experimental Pintail API proxying library, instead of the original proxying built into SMAPI itself. /// >Whether to make SMAPI file APIs case-insensitive, even on Linux. /// Whether SMAPI should log network traffic. /// The colors to use for text written to the SMAPI console. /// The mod IDs SMAPI should ignore when performing update checks or validating update keys. - public SConfig(bool developerMode, bool? checkForUpdates, bool? paranoidWarnings, bool? useBetaChannel, string gitHubProjectName, string webApiBaseUrl, bool? verboseLogging, bool? rewriteMods, bool? usePintail, bool? useCaseInsensitivePaths, bool? logNetworkTraffic, ColorSchemeConfig consoleColors, string[]? suppressUpdateChecks) + public SConfig(bool developerMode, bool? checkForUpdates, bool? paranoidWarnings, bool? useBetaChannel, string gitHubProjectName, string webApiBaseUrl, string[]? verboseLogging, bool? rewriteMods, bool? usePintail, bool? useCaseInsensitivePaths, bool? logNetworkTraffic, ColorSchemeConfig consoleColors, string[]? suppressUpdateChecks) { this.DeveloperMode = developerMode; this.CheckForUpdates = checkForUpdates ?? (bool)SConfig.DefaultValues[nameof(this.CheckForUpdates)]; @@ -104,7 +104,7 @@ namespace StardewModdingAPI.Framework.Models this.UseBetaChannel = useBetaChannel ?? (bool)SConfig.DefaultValues[nameof(this.UseBetaChannel)]; this.GitHubProjectName = gitHubProjectName; this.WebApiBaseUrl = webApiBaseUrl; - this.VerboseLogging = verboseLogging ?? (bool)SConfig.DefaultValues[nameof(this.VerboseLogging)]; + this.VerboseLogging = new HashSet(verboseLogging ?? Array.Empty(), StringComparer.OrdinalIgnoreCase); this.RewriteMods = rewriteMods ?? (bool)SConfig.DefaultValues[nameof(this.RewriteMods)]; this.UsePintail = usePintail ?? (bool)SConfig.DefaultValues[nameof(this.UsePintail)]; this.UseCaseInsensitivePaths = useCaseInsensitivePaths ?? (bool)SConfig.DefaultValues[nameof(this.UseCaseInsensitivePaths)]; @@ -133,7 +133,10 @@ namespace StardewModdingAPI.Framework.Models } if (!this.SuppressUpdateChecks.SetEquals(SConfig.DefaultSuppressUpdateChecks)) - custom[nameof(this.SuppressUpdateChecks)] = "[" + string.Join(", ", this.SuppressUpdateChecks) + "]"; + custom[nameof(this.SuppressUpdateChecks)] = $"[{string.Join(", ", this.SuppressUpdateChecks)}]"; + + if (this.VerboseLogging.Any()) + custom[nameof(this.VerboseLogging)] = $"[{string.Join(", ", this.VerboseLogging)}]"; return custom; } diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index fa217f20..4f4212dc 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -194,7 +194,7 @@ namespace StardewModdingAPI.Framework if (developerMode.HasValue) this.Settings.OverrideDeveloperMode(developerMode.Value); - this.LogManager = new LogManager(logPath: logPath, colorConfig: this.Settings.ConsoleColors, writeToConsole: writeToConsole, isVerbose: this.Settings.VerboseLogging, isDeveloperMode: this.Settings.DeveloperMode, getScreenIdForLog: this.GetScreenIdForLog); + this.LogManager = new LogManager(logPath: logPath, colorConfig: this.Settings.ConsoleColors, writeToConsole: writeToConsole, verboseLogging: this.Settings.VerboseLogging, isDeveloperMode: this.Settings.DeveloperMode, getScreenIdForLog: this.GetScreenIdForLog); this.CommandManager = new CommandManager(this.Monitor); this.EventManager = new EventManager(this.ModRegistry); SCore.DeprecationManager = new DeprecationManager(this.Monitor, this.ModRegistry); @@ -1827,7 +1827,7 @@ namespace StardewModdingAPI.Framework // load as content pack if (mod.IsContentPack) { - IMonitor monitor = this.LogManager.GetMonitor(mod.DisplayName); + IMonitor monitor = this.LogManager.GetMonitor(manifest.UniqueID, mod.DisplayName); IFileLookup fileLookup = this.GetFileLookup(mod.DirectoryPath); GameContentHelper gameContentHelper = new(this.ContentCore, mod, mod.DisplayName, monitor, this.Reflection); IModContentHelper modContentHelper = new ModContentHelper(this.ContentCore, mod.DirectoryPath, mod, mod.DisplayName, gameContentHelper.GetUnderlyingContentManager(), this.Reflection); @@ -1902,7 +1902,7 @@ namespace StardewModdingAPI.Framework } // init mod helpers - IMonitor monitor = this.LogManager.GetMonitor(mod.DisplayName); + IMonitor monitor = this.LogManager.GetMonitor(manifest.UniqueID, mod.DisplayName); TranslationHelper translationHelper = new(mod, contentCore.GetLocale(), contentCore.Language); IModHelper modHelper; { @@ -1965,7 +1965,7 @@ namespace StardewModdingAPI.Framework ); // create mod helpers - IMonitor packMonitor = this.LogManager.GetMonitor(packManifest.Name); + IMonitor packMonitor = this.LogManager.GetMonitor(packManifest.UniqueID, packManifest.Name); GameContentHelper gameContentHelper = new(contentCore, fakeMod, packManifest.Name, packMonitor, this.Reflection); IModContentHelper packContentHelper = new ModContentHelper(contentCore, packDirPath, fakeMod, packManifest.Name, gameContentHelper.GetUnderlyingContentManager(), this.Reflection); TranslationHelper packTranslationHelper = new(fakeMod, contentCore.GetLocale(), contentCore.Language); diff --git a/src/SMAPI/SMAPI.config.json b/src/SMAPI/SMAPI.config.json index 8324f45b..a6ec42d3 100644 --- a/src/SMAPI/SMAPI.config.json +++ b/src/SMAPI/SMAPI.config.json @@ -16,9 +16,17 @@ copy all the settings, or you may cause bugs due to overridden changes in future */ { /** - * Whether SMAPI should log more information about the game context. + * The logs for which to enable verbose logging, which may show a lot more information to + * simplify troubleshooting. + * + * The possible values are: + * - "*" for everything (not recommended); + * - "SMAPI" for messages from SMAPI itself; + * - mod IDs from their manifest.json files. + * + * For example: [ "SMAPI", "Pathoschild.ContentPatcher" ] */ - "VerboseLogging": false, + "VerboseLogging": [], /** * Whether SMAPI should check for newer versions of SMAPI and mods when you load the game. If new -- cgit