From 66136b5d792aa2d21c236a47f7f6fa8e947de99d Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 15 Sep 2020 17:26:57 -0700 Subject: [PATCH] Rewrite some Logger bits, remove last Global throw --- RombaSharp/Program.cs | 2 +- SabreTools.Library/Data/Globals.cs | 5 - SabreTools.Library/Logging/Logger.cs | 138 ++++++++++++++++----------- SabreTools/Program.cs | 2 +- 4 files changed, 85 insertions(+), 62 deletions(-) diff --git a/RombaSharp/Program.cs b/RombaSharp/Program.cs index 973263fb..de791ff8 100644 --- a/RombaSharp/Program.cs +++ b/RombaSharp/Program.cs @@ -26,7 +26,7 @@ namespace RombaSharp public static void Main(string[] args) { // Perform initial setup and verification - Globals.Logger = new Logger(true, "romba.log"); + Globals.Logger = new Logger("romba.log"); // Create a new Help object for this program _help = RetrieveHelp(); diff --git a/SabreTools.Library/Data/Globals.cs b/SabreTools.Library/Data/Globals.cs index 550c5edb..09fb72a0 100644 --- a/SabreTools.Library/Data/Globals.cs +++ b/SabreTools.Library/Data/Globals.cs @@ -68,11 +68,6 @@ namespace SabreTools.Library.Data /// public static string TempDir { get; set; } = Path.GetTempPath(); - /// - /// Whether to throw an exception from the library if an error is found - /// - public static bool ThrowOnError { get; set; } = false; - #endregion } } diff --git a/SabreTools.Library/Logging/Logger.cs b/SabreTools.Library/Logging/Logger.cs index ff258b87..376ebf4c 100644 --- a/SabreTools.Library/Logging/Logger.cs +++ b/SabreTools.Library/Logging/Logger.cs @@ -12,49 +12,87 @@ namespace SabreTools.Library.Logging /// public class Logger { - // Private instance variables - private readonly bool _tofile; - private bool _warnings; - private bool _errors; - private readonly string _filename; - private readonly LogLevel _filter; - private DateTime _start; - private StreamWriter _log; - private readonly object _lock = new object(); // This is used during multithreaded logging + #region Fields - // Private required variables - private readonly string _basepath = Path.Combine(Globals.ExeDir, "logs") + Path.DirectorySeparatorChar; + /// + /// Optional output filename for logs + /// + public string Filename { get; set; } = null; + + /// + /// Determines if we're logging to file or not + /// + public bool LogToFile { get { return !string.IsNullOrWhiteSpace(Filename); } } + + /// + /// Optional output log directory + /// + /// TODO: Make this either passed in or optional + public string LogDirectory { get; set; } = Path.Combine(Globals.ExeDir, "logs") + Path.DirectorySeparatorChar; + + /// + /// Determines the lowest log level to output + /// + public LogLevel LowestLogLevel { get; set; } = LogLevel.VERBOSE; + + /// + /// Determines whether to throw if an exception is logged + /// + public bool ThrowOnError { get; set; } = false; + + /// + /// Logging start time for metrics + /// + public DateTime StartTime { get; private set; } + + /// + /// Determines if there were errors logged + /// + public bool LoggedErrors { get; private set; } = false; + + /// + /// Determines if there were warnings logged + /// + public bool LoggedWarnings { get; private set; } = false; + + #endregion + + #region Private instance variables + + /// + /// StreamWriter representing the output log file + /// + private StreamWriter _log; + + /// + /// Object lock for multithreaded logging + /// + private readonly object _lock = new object(); + + #endregion /// /// Initialize a console-only logger object /// public Logger() { - _tofile = false; - _warnings = false; - _errors = false; - _filename = null; - _filter = LogLevel.VERBOSE; - Start(); } /// /// Initialize a Logger object with the given information /// - /// True if file should be written to instead of console /// Filename representing log location - /// Highest filtering level to be kept, default VERBOSE - public Logger(bool tofile, string filename, LogLevel filter = LogLevel.VERBOSE) + /// True to add a date string to the filename (default), false otherwise + public Logger(string filename, bool addDate = true) { - _tofile = tofile; - _warnings = false; - _errors = false; - _filename = $"{Path.GetFileNameWithoutExtension(filename)} ({DateTime.Now:yyyy-MM-dd HH-mm-ss}).{PathExtensions.GetNormalizedExtension(filename)}"; - _filter = filter; + if (addDate) + Filename = $"{Path.GetFileNameWithoutExtension(filename)} ({DateTime.Now:yyyy-MM-dd HH-mm-ss}).{PathExtensions.GetNormalizedExtension(filename)}"; + else + Filename = filename; - if (!Directory.Exists(_basepath)) - Directory.CreateDirectory(_basepath); + if (!string.IsNullOrEmpty(LogDirectory) && !Directory.Exists(LogDirectory)) + Directory.CreateDirectory(LogDirectory); Start(); } @@ -65,19 +103,19 @@ namespace SabreTools.Library.Logging /// True if the logging was started correctly, false otherwise public bool Start() { - _start = DateTime.Now; - if (!_tofile) + StartTime = DateTime.Now; + if (!LogToFile) return true; try { - FileStream logfile = FileExtensions.TryCreate(Path.Combine(_basepath, _filename)); + FileStream logfile = FileExtensions.TryCreate(Path.Combine(LogDirectory, Filename)); _log = new StreamWriter(logfile, Encoding.UTF8, (int)(4 * Constants.KibiByte), true) { AutoFlush = true }; - _log.WriteLine($"Logging started {DateTime.Now:yyyy-MM-dd HH:mm:ss}"); + _log.WriteLine($"Logging started {StartTime:yyyy-MM-dd HH:mm:ss}"); _log.WriteLine($"Command run: {Globals.CommandLineArgs}"); } catch @@ -97,13 +135,13 @@ namespace SabreTools.Library.Logging { if (!suppress) { - if (_warnings) + if (LoggedWarnings) Console.WriteLine("There were warnings in the last run! Check the log for more details"); - if (_errors) + if (LoggedErrors) Console.WriteLine("There were errors in the last run! Check the log for more details"); - TimeSpan span = DateTime.Now.Subtract(_start); + TimeSpan span = DateTime.Now.Subtract(StartTime); // Special case for multi-day runs string total; @@ -112,7 +150,7 @@ namespace SabreTools.Library.Logging else total = span.ToString(@"hh\:mm\:ss"); - if (!_tofile) + if (!LogToFile) { Console.WriteLine($"Total runtime: {total}"); return true; @@ -155,7 +193,7 @@ namespace SabreTools.Library.Logging private bool Log(string output, LogLevel loglevel, bool appendPrefix) { // If the log level is less than the filter level, we skip it but claim we didn't - if (loglevel < _filter) + if (loglevel < LowestLogLevel) return true; // USER and ERROR writes to console @@ -163,7 +201,7 @@ namespace SabreTools.Library.Logging Console.WriteLine((loglevel == LogLevel.ERROR && appendPrefix ? loglevel.ToString() + " " : string.Empty) + output); // If we're writing to file, use the existing stream - if (_tofile) + if (LogToFile) { try { @@ -176,9 +214,7 @@ namespace SabreTools.Library.Logging { Console.WriteLine(ex); Console.WriteLine("Could not write to log file!"); - if (Globals.ThrowOnError) - throw ex; - + if (ThrowOnError) throw ex; return false; } } @@ -206,7 +242,7 @@ namespace SabreTools.Library.Logging Console.Write(output); // If we're writing to file, use the existing stream - if (_tofile) + if (LogToFile) { try { @@ -234,9 +270,7 @@ namespace SabreTools.Library.Logging /// True if the output could be written, false otherwise public bool Verbose(Exception ex, string output = null, bool appendPrefix = true) { - if (Globals.ThrowOnError) - throw ex; - + if (ThrowOnError) throw ex; return Verbose($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix); } @@ -260,9 +294,7 @@ namespace SabreTools.Library.Logging /// True if the output could be written, false otherwise public bool User(Exception ex, string output = null, bool appendPrefix = true) { - if (Globals.ThrowOnError) - throw ex; - + if (ThrowOnError) throw ex; return User($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix); } @@ -286,9 +318,7 @@ namespace SabreTools.Library.Logging /// True if the output could be written, false otherwise public bool Warning(Exception ex, string output = null, bool appendPrefix = true) { - if (Globals.ThrowOnError) - throw ex; - + if (ThrowOnError) throw ex; return Warning($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix); } @@ -300,7 +330,7 @@ namespace SabreTools.Library.Logging /// True if the output could be written, false otherwise public bool Warning(string output, bool appendPrefix = true) { - _warnings = true; + LoggedWarnings = true; return Log(output, LogLevel.WARNING, appendPrefix); } @@ -313,9 +343,7 @@ namespace SabreTools.Library.Logging /// True if the output could be written, false otherwise public bool Error(Exception ex, string output = null, bool appendPrefix = true) { - if (Globals.ThrowOnError) - throw ex; - + if (ThrowOnError) throw ex; return Error($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix); } @@ -327,7 +355,7 @@ namespace SabreTools.Library.Logging /// True if the output could be written, false otherwise public bool Error(string output, bool appendPrefix = true) { - _errors = true; + LoggedErrors = true; return Log(output, LogLevel.ERROR, appendPrefix); } diff --git a/SabreTools/Program.cs b/SabreTools/Program.cs index 634a57dc..9ba94502 100644 --- a/SabreTools/Program.cs +++ b/SabreTools/Program.cs @@ -20,7 +20,7 @@ namespace SabreTools public static void Main(string[] args) { // Perform initial setup and verification - Globals.Logger = new Logger(true, "sabretools.log"); + Globals.Logger = new Logger("sabretools.log"); // Create a new Help object for this program _help = RetrieveHelp();