summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/release-notes.md1
-rw-r--r--src/SMAPI/Framework/Logging/LogManager.cs19
-rw-r--r--src/SMAPI/Framework/Models/SConfig.cs17
-rw-r--r--src/SMAPI/Framework/SCore.cs8
-rw-r--r--src/SMAPI/SMAPI.config.json12
5 files changed, 35 insertions, 22 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md
index b7605bf6..e1aa47ab 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -4,6 +4,7 @@
## Upcoming release
* For mod authors:
* Fixed map edits which change warps sometimes rebuilding the NPC pathfinding cache unnecessarily, which could cause a noticeable delay for players.
+ * In `smapi-internal/config.json`, you can now enable verbose logging for specific mods (instead of all or nothing).
## 3.14.7
Released 01 June 2022 for Stardew Valley 1.5.6 or later.
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
/// <summary>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.)</summary>
private const char IgnoreChar = InterceptingTextWriter.IgnoreChar;
- /// <summary>Get a named monitor instance.</summary>
- private readonly Func<string, Monitor> GetMonitorImpl;
+ /// <summary>Create a monitor instance given the ID and name.</summary>
+ private readonly Func<string, string, Monitor> GetMonitorImpl;
/// <summary>Regex patterns which match console non-error messages to suppress from the console and log.</summary>
private readonly Regex[] SuppressConsolePatterns =
@@ -88,23 +88,23 @@ namespace StardewModdingAPI.Framework.Logging
/// <param name="logPath">The log file path to write.</param>
/// <param name="colorConfig">The colors to use for text written to the SMAPI console.</param>
/// <param name="writeToConsole">Whether to output log messages to the console.</param>
- /// <param name="isVerbose">Whether verbose logging is enabled. This enables more detailed diagnostic messages than are normally needed.</param>
+ /// <param name="verboseLogging">The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting.</param>
/// <param name="isDeveloperMode">Whether to enable full console output for developers.</param>
/// <param name="getScreenIdForLog">Get the screen ID that should be logged to distinguish between players in split-screen mode, if any.</param>
- public LogManager(string logPath, ColorSchemeConfig colorConfig, bool writeToConsole, bool isVerbose, bool isDeveloperMode, Func<int?> getScreenIdForLog)
+ public LogManager(string logPath, ColorSchemeConfig colorConfig, bool writeToConsole, HashSet<string> verboseLogging, bool isDeveloperMode, Func<int?> 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
}
/// <summary>Get a monitor instance derived from SMAPI's current settings.</summary>
+ /// <param name="id">The unique ID for the mod context.</param>
/// <param name="name">The name of the module which will log messages with this instance.</param>
- public Monitor GetMonitor(string name)
+ public Monitor GetMonitor(string id, string name)
{
- return this.GetMonitorImpl(name);
+ return this.GetMonitorImpl(id, name);
}
/// <summary>Set the title of the SMAPI console window.</summary>
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
/// <summary>The base URL for SMAPI's web API, used to perform update checks.</summary>
public string WebApiBaseUrl { get; }
- /// <summary>Whether SMAPI should log more information about the game context.</summary>
- public bool VerboseLogging { get; }
+ /// <summary>The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting.</summary>
+ /// <remarks>The possible values are "*" (everything is verbose), "SMAPI", (SMAPI itself), or mod IDs.</remarks>
+ public HashSet<string> VerboseLogging { get; }
/// <summary>Whether SMAPI should rewrite mods for compatibility.</summary>
public bool RewriteMods { get; }
@@ -89,14 +89,14 @@ namespace StardewModdingAPI.Framework.Models
/// <param name="useBetaChannel">Whether to show beta versions as valid updates.</param>
/// <param name="gitHubProjectName">SMAPI's GitHub project name, used to perform update checks.</param>
/// <param name="webApiBaseUrl">The base URL for SMAPI's web API, used to perform update checks.</param>
- /// <param name="verboseLogging">Whether SMAPI should log more information about the game context.</param>
+ /// <param name="verboseLogging">The log contexts for which to enable verbose logging, which may show a lot more information to simplify troubleshooting.</param>
/// <param name="rewriteMods">Whether SMAPI should rewrite mods for compatibility.</param>
/// <param name="usePintail">Whether to use the experimental Pintail API proxying library, instead of the original proxying built into SMAPI itself.</param>
/// <param name="useCaseInsensitivePaths">>Whether to make SMAPI file APIs case-insensitive, even on Linux.</param>
/// <param name="logNetworkTraffic">Whether SMAPI should log network traffic.</param>
/// <param name="consoleColors">The colors to use for text written to the SMAPI console.</param>
/// <param name="suppressUpdateChecks">The mod IDs SMAPI should ignore when performing update checks or validating update keys.</param>
- 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<string>(verboseLogging ?? Array.Empty<string>(), 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