diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-11-04 19:52:12 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2016-11-04 19:52:12 -0400 |
commit | 5fd708e43f6576cc71b80406de602adbdef98f56 (patch) | |
tree | f9e2c9476d18bde3738e91e33f0334d9a1e3ed37 /src | |
parent | cd27873afbfde0a3c6d5fd97aa12ffac60b9b5c2 (diff) | |
download | SMAPI-5fd708e43f6576cc71b80406de602adbdef98f56.tar.gz SMAPI-5fd708e43f6576cc71b80406de602adbdef98f56.tar.bz2 SMAPI-5fd708e43f6576cc71b80406de602adbdef98f56.zip |
format & document logging code
Diffstat (limited to 'src')
-rw-r--r-- | src/StardewModdingAPI.sln.DotSettings | 1 | ||||
-rw-r--r-- | src/StardewModdingAPI/Log.cs | 159 | ||||
-rw-r--r-- | src/StardewModdingAPI/LogWriter.cs | 96 | ||||
-rw-r--r-- | src/StardewModdingAPI/Logger.cs | 35 |
4 files changed, 168 insertions, 123 deletions
diff --git a/src/StardewModdingAPI.sln.DotSettings b/src/StardewModdingAPI.sln.DotSettings index 84c0029d..4c195c13 100644 --- a/src/StardewModdingAPI.sln.DotSettings +++ b/src/StardewModdingAPI.sln.DotSettings @@ -7,6 +7,7 @@ <s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseExplicitType</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> + <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean> diff --git a/src/StardewModdingAPI/Log.cs b/src/StardewModdingAPI/Log.cs index abf6e36a..ddd82579 100644 --- a/src/StardewModdingAPI/Log.cs +++ b/src/StardewModdingAPI/Log.cs @@ -5,198 +5,227 @@ using System.Threading.Tasks; namespace StardewModdingAPI { + /// <summary>A singleton which logs messages to the SMAPI console and log file.</summary> public static class Log { + /********* + ** Properties + *********/ /// <summary>A pseudorandom number generator used to generate log files.</summary> private static readonly Random Random = new Random(); - private static readonly LogWriter _writer; + /// <summary>The underlying log writer.</summary> + private static readonly LogWriter Writer = LogWriter.Instance; - static Log() - { - _writer = LogWriter.Instance; - } - private static void PrintLog(LogInfo li) - { - _writer.WriteToLog(li); - } - - #region Exception Logging - - /// <summary> - /// Catch unhandled exception from the application - /// </summary> - /// <remarks>Should be moved out of here if we do more than just log the exception.</remarks> + /********* + ** Public methods + *********/ + /**** + ** Exceptions + ****/ + /// <summary>Log an exception event.</summary> + /// <param name="sender">The event sender.</param> + /// <param name="e">The event arguments.</param> public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine("An exception has been caught"); File.WriteAllText(Path.Combine(Constants.LogDir, $"MODDED_ErrorLog.Log_{DateTime.UtcNow.Ticks}.txt"), e.ExceptionObject.ToString()); } - /// <summary> - /// Catch thread exception from the application - /// </summary> - /// <remarks>Should be moved out of here if we do more than just log the exception.</remarks> + /// <summary>Log a thread exception event.</summary> + /// <param name="sender">The event sender.</param> + /// <param name="e">The event arguments.</param> public static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { Console.WriteLine("A thread exception has been caught"); File.WriteAllText(Path.Combine(Constants.LogDir, $"MODDED_ErrorLog.Log_{Log.Random.Next(100000000, 999999999)}.txt"), e.Exception.ToString()); } - #endregion - - #region Sync Logging - /// <summary> - /// NOTICE: Sync logging is discouraged. Please use Async instead. - /// </summary> - /// <param name="message">Message to log</param> - /// <param name="colour">Colour of message</param> - public static void SyncColour(object message, ConsoleColor colour) + /**** + ** Synchronous logging + ****/ + /// <summary>Synchronously log a message to the console. NOTE: synchronous logging is discouraged; use asynchronous methods instead.</summary> + /// <param name="message">The message to log.</param> + /// <param name="color">The message color.</param> + public static void SyncColour(object message, ConsoleColor color) { - PrintLog(new LogInfo(message?.ToString(), colour)); + Log.PrintLog(new LogInfo(message?.ToString(), color)); } - #endregion - - #region Async Logging - - public static void AsyncColour(object message, ConsoleColor colour) + /**** + ** Asynchronous logging + ****/ + /// <summary>Asynchronously log a message to the console with the specified color.</summary> + /// <param name="message">The message to log.</param> + /// <param name="color">The message color.</param> + public static void AsyncColour(object message, ConsoleColor color) { - Task.Run(() => { PrintLog(new LogInfo(message?.ToString(), colour)); }); + Task.Run(() => { Log.PrintLog(new LogInfo(message?.ToString(), color)); }); } + /// <summary>Asynchronously log a message to the console.</summary> + /// <param name="message">The message to log.</param> public static void Async(object message) { - AsyncColour(message?.ToString(), ConsoleColor.Gray); + Log.AsyncColour(message?.ToString(), ConsoleColor.Gray); } + /// <summary>Asynchronously log a red message to the console.</summary> + /// <param name="message">The message to log.</param> public static void AsyncR(object message) { - AsyncColour(message?.ToString(), ConsoleColor.Red); + Log.AsyncColour(message?.ToString(), ConsoleColor.Red); } + /// <summary>Asynchronously log an orange message to the console.</summary> + /// <param name="message">The message to log.</param> public static void AsyncO(object message) { - AsyncColour(message.ToString(), ConsoleColor.DarkYellow); + Log.AsyncColour(message.ToString(), ConsoleColor.DarkYellow); } + /// <summary>Asynchronously log a yellow message to the console.</summary> + /// <param name="message">The message to log.</param> public static void AsyncY(object message) { - AsyncColour(message?.ToString(), ConsoleColor.Yellow); + Log.AsyncColour(message?.ToString(), ConsoleColor.Yellow); } + /// <summary>Asynchronously log a green message to the console.</summary> + /// <param name="message">The message to log.</param> public static void AsyncG(object message) { - AsyncColour(message?.ToString(), ConsoleColor.Green); + Log.AsyncColour(message?.ToString(), ConsoleColor.Green); } + /// <summary>Asynchronously log a cyan message to the console.</summary> + /// <param name="message">The message to log.</param> public static void AsyncC(object message) { - AsyncColour(message?.ToString(), ConsoleColor.Cyan); + Log.AsyncColour(message?.ToString(), ConsoleColor.Cyan); } + /// <summary>Asynchronously log a magenta message to the console.</summary> + /// <param name="message">The message to log.</param> public static void AsyncM(object message) { - AsyncColour(message?.ToString(), ConsoleColor.Magenta); + Log.AsyncColour(message?.ToString(), ConsoleColor.Magenta); } + /// <summary>Asynchronously log an error to the console.</summary> + /// <param name="message">The message to log.</param> public static void Error(object message) { - AsyncR("[ERROR] " + message); + Log.AsyncR("[ERROR] " + message); } + /// <summary>Asynchronously log a success message to the console.</summary> + /// <param name="message">The message to log.</param> public static void Success(object message) { - AsyncG("[SUCCESS] " + message); + Log.AsyncG("[SUCCESS] " + message); } + /// <summary>Asynchronously log an info message to the console.</summary> + /// <param name="message">The message to log.</param> public static void Info(object message) { - AsyncY("[INFO] " + message); + Log.AsyncY("[INFO] " + message); } + // unused? public static void Out(object message) { - Async("[OUT] " + message); + Log.Async("[OUT] " + message); } + /// <summary>Asynchronously log a debug message to the console.</summary> + /// <param name="message">The message to log.</param> public static void Debug(object message) { - AsyncO("[DEBUG] " + message); + Log.AsyncO("[DEBUG] " + message); } - #endregion - - #region ToRemove - + /**** + ** Obsolete + ****/ public static void LogValueNotSpecified() { - AsyncR("<value> must be specified"); + Log.AsyncR("<value> must be specified"); } public static void LogObjectValueNotSpecified() { - AsyncR("<object> and <value> must be specified"); + Log.AsyncR("<object> and <value> must be specified"); } public static void LogValueInvalid() { - AsyncR("<value> is invalid"); + Log.AsyncR("<value> is invalid"); } public static void LogObjectInvalid() { - AsyncR("<object> is invalid"); + Log.AsyncR("<object> is invalid"); } public static void LogValueNotInt32() { - AsyncR("<value> must be a whole number (Int32)"); + Log.AsyncR("<value> must be a whole number (Int32)"); } [Obsolete("Parameter 'values' is no longer supported. Format before logging.")] private static void PrintLog(object message, bool disableLogging, params object[] values) { - PrintLog(new LogInfo(message?.ToString())); + Log.PrintLog(new LogInfo(message?.ToString())); } [Obsolete("Parameter 'values' is no longer supported. Format before logging.")] public static void Success(object message, params object[] values) { - Success(message); + Log.Success(message); } [Obsolete("Parameter 'values' is no longer supported. Format before logging.")] public static void Verbose(object message, params object[] values) { - Out(message); + Log.Out(message); } [Obsolete("Parameter 'values' is no longer supported. Format before logging.")] public static void Comment(object message, params object[] values) { - AsyncC(message); + Log.AsyncC(message); } [Obsolete("Parameter 'values' is no longer supported. Format before logging.")] public static void Info(object message, params object[] values) { - Info(message); + Log.Info(message); } [Obsolete("Parameter 'values' is no longer supported. Format before logging.")] public static void Error(object message, params object[] values) { - Error(message); + Log.Error(message); } [Obsolete("Parameter 'values' is no longer supported. Format before logging.")] public static void Debug(object message, params object[] values) { - Debug(message); + Log.Debug(message); } - #endregion + + /********* + ** Private methods + *********/ + /// <summary>Write a message to the log.</summary> + /// <param name="message">The message to write.</param> + private static void PrintLog(LogInfo message) + { + Log.Writer.WriteToLog(message); + } } }
\ No newline at end of file diff --git a/src/StardewModdingAPI/LogWriter.cs b/src/StardewModdingAPI/LogWriter.cs index 18c940c8..139d89bf 100644 --- a/src/StardewModdingAPI/LogWriter.cs +++ b/src/StardewModdingAPI/LogWriter.cs @@ -5,35 +5,36 @@ using System.Linq; namespace StardewModdingAPI { - /// <summary> - /// A Logging class implementing the Singleton pattern and an internal Queue to be flushed perdiodically - /// </summary> + /// <summary>A log writer which queues messages for output, and periodically flushes them to the console and log file.</summary> public class LogWriter { + /********* + ** Properties + *********/ + /// <summary>The singleton instance.</summary> private static LogWriter _instance; - private static ConcurrentQueue<LogInfo> _logQueue; - private static StreamWriter _stream; - /// <summary> - /// Private to prevent creation of other instances - /// </summary> - private LogWriter() - { - } + /// <summary>The queued messages to flush.</summary> + private static ConcurrentQueue<LogInfo> Queue; + + /// <summary>The underlying file stream.</summary> + private static StreamWriter FileStream; - /// <summary> - /// Exposes _instace and creates a new one if it is null - /// </summary> + + /********* + ** Accessors + *********/ + /// <summary>The singleton instance.</summary> internal static LogWriter Instance { get { - if (_instance == null) + if (LogWriter._instance == null) { - _instance = new LogWriter(); + LogWriter._instance = new LogWriter(); // Field cannot be used by anything else regardless, do not surround with lock { } // ReSharper disable once InconsistentlySynchronizedField - _logQueue = new ConcurrentQueue<LogInfo>(); + LogWriter.Queue = new ConcurrentQueue<LogInfo>(); Console.WriteLine(Constants.LogPath); // If the ErrorLogs dir doesn't exist StreamWriter will throw an exception. @@ -42,57 +43,56 @@ namespace StardewModdingAPI Directory.CreateDirectory(Constants.LogDir); } - _stream = new StreamWriter(Constants.LogPath, false); + LogWriter.FileStream = new StreamWriter(Constants.LogPath, false); Console.WriteLine("Created log instance"); } - return _instance; + return LogWriter._instance; } } - /// <summary> - /// Writes into the ConcurrentQueue the Message specified - /// </summary> - /// <param name="message">The message to write to the log</param> + + /********* + ** Public methods + *********/ + /// <summary>Queue a message for output.</summary> + /// <param name="message">The message to log.</param> public void WriteToLog(string message) { - lock (_logQueue) + lock (LogWriter.Queue) { var logEntry = new LogInfo(message); - _logQueue.Enqueue(logEntry); + LogWriter.Queue.Enqueue(logEntry); - if (_logQueue.Any()) - { - FlushLog(); - } + if (LogWriter.Queue.Any()) + this.FlushLog(); } } - /// <summary> - /// Writes into the ConcurrentQueue the Entry specified - /// </summary> - /// <param name="logEntry">The logEntry to write to the log</param> - public void WriteToLog(LogInfo logEntry) + /// <summary>Queue a message for output.</summary> + /// <param name="message">The message to log.</param> + public void WriteToLog(LogInfo message) { - lock (_logQueue) + lock (LogWriter.Queue) { - _logQueue.Enqueue(logEntry); - - if (_logQueue.Any()) - { - FlushLog(); - } + LogWriter.Queue.Enqueue(message); + if (LogWriter.Queue.Any()) + this.FlushLog(); } } - /// <summary> - /// Flushes the ConcurrentQueue to the log file specified in Constants - /// </summary> + /********* + ** Private methods + *********/ + /// <summary>Construct an instance.</summary> + private LogWriter() { } + + /// <summary>Flush the underlying queue to the console and file.</summary> private void FlushLog() { - lock (_stream) + lock (LogWriter.FileStream) { LogInfo entry; - while (_logQueue.TryDequeue(out entry)) + while (LogWriter.Queue.TryDequeue(out entry)) { string m = $"[{entry.LogTime}] {entry.Message}"; @@ -100,9 +100,9 @@ namespace StardewModdingAPI Console.WriteLine(m); Console.ForegroundColor = ConsoleColor.Gray; - _stream.WriteLine(m); + LogWriter.FileStream.WriteLine(m); } - _stream.Flush(); + LogWriter.FileStream.Flush(); } } } diff --git a/src/StardewModdingAPI/Logger.cs b/src/StardewModdingAPI/Logger.cs index 0f40cd25..f0f08e4f 100644 --- a/src/StardewModdingAPI/Logger.cs +++ b/src/StardewModdingAPI/Logger.cs @@ -2,24 +2,39 @@ namespace StardewModdingAPI { - /// <summary> - /// A struct to store the message and the Date and Time the log entry was created - /// </summary> + /// <summary>A message queued for log output.</summary> public struct LogInfo { + /********* + ** Accessors + *********/ + /// <summary>The message to log.</summary> public string Message { get; set; } - public string LogTime { get; set; } + + /// <summary>The log date.</summary> public string LogDate { get; set; } + + /// <summary>The log time.</summary> + public string LogTime { get; set; } + + /// <summary>The message color.</summary> public ConsoleColor Colour { get; set; } - public LogInfo(string message, ConsoleColor colour = ConsoleColor.Gray) + + /********* + ** Public methods + *********/ + /// <summary>Construct an instance.</summary> + /// <param name="message">The message to log.</param> + /// <param name="color">The message color.</param> + public LogInfo(string message, ConsoleColor color = ConsoleColor.Gray) { if (string.IsNullOrEmpty(message)) message = "[null]"; - Message = message; - LogDate = DateTime.Now.ToString("yyyy-MM-dd"); - LogTime = DateTime.Now.ToString("hh:mm:ss.fff tt"); - Colour = colour; + this.Message = message; + this.LogDate = DateTime.Now.ToString("yyyy-MM-dd"); + this.LogTime = DateTime.Now.ToString("hh:mm:ss.fff tt"); + this.Colour = color; } } -}
\ No newline at end of file +} |