Rewrite some Logger bits, remove last Global throw

This commit is contained in:
Matt Nadareski
2020-09-15 17:26:57 -07:00
parent 044d70da6e
commit 66136b5d79
4 changed files with 85 additions and 62 deletions

View File

@@ -26,7 +26,7 @@ namespace RombaSharp
public static void Main(string[] args) public static void Main(string[] args)
{ {
// Perform initial setup and verification // 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 // Create a new Help object for this program
_help = RetrieveHelp(); _help = RetrieveHelp();

View File

@@ -68,11 +68,6 @@ namespace SabreTools.Library.Data
/// </summary> /// </summary>
public static string TempDir { get; set; } = Path.GetTempPath(); public static string TempDir { get; set; } = Path.GetTempPath();
/// <summary>
/// Whether to throw an exception from the library if an error is found
/// </summary>
public static bool ThrowOnError { get; set; } = false;
#endregion #endregion
} }
} }

View File

@@ -12,49 +12,87 @@ namespace SabreTools.Library.Logging
/// </summary> /// </summary>
public class Logger public class Logger
{ {
// Private instance variables #region Fields
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
// Private required variables /// <summary>
private readonly string _basepath = Path.Combine(Globals.ExeDir, "logs") + Path.DirectorySeparatorChar; /// Optional output filename for logs
/// </summary>
public string Filename { get; set; } = null;
/// <summary>
/// Determines if we're logging to file or not
/// </summary>
public bool LogToFile { get { return !string.IsNullOrWhiteSpace(Filename); } }
/// <summary>
/// Optional output log directory
/// </summary>
/// TODO: Make this either passed in or optional
public string LogDirectory { get; set; } = Path.Combine(Globals.ExeDir, "logs") + Path.DirectorySeparatorChar;
/// <summary>
/// Determines the lowest log level to output
/// </summary>
public LogLevel LowestLogLevel { get; set; } = LogLevel.VERBOSE;
/// <summary>
/// Determines whether to throw if an exception is logged
/// </summary>
public bool ThrowOnError { get; set; } = false;
/// <summary>
/// Logging start time for metrics
/// </summary>
public DateTime StartTime { get; private set; }
/// <summary>
/// Determines if there were errors logged
/// </summary>
public bool LoggedErrors { get; private set; } = false;
/// <summary>
/// Determines if there were warnings logged
/// </summary>
public bool LoggedWarnings { get; private set; } = false;
#endregion
#region Private instance variables
/// <summary>
/// StreamWriter representing the output log file
/// </summary>
private StreamWriter _log;
/// <summary>
/// Object lock for multithreaded logging
/// </summary>
private readonly object _lock = new object();
#endregion
/// <summary> /// <summary>
/// Initialize a console-only logger object /// Initialize a console-only logger object
/// </summary> /// </summary>
public Logger() public Logger()
{ {
_tofile = false;
_warnings = false;
_errors = false;
_filename = null;
_filter = LogLevel.VERBOSE;
Start(); Start();
} }
/// <summary> /// <summary>
/// Initialize a Logger object with the given information /// Initialize a Logger object with the given information
/// </summary> /// </summary>
/// <param name="tofile">True if file should be written to instead of console</param>
/// <param name="filename">Filename representing log location</param> /// <param name="filename">Filename representing log location</param>
/// <param name="filter">Highest filtering level to be kept, default VERBOSE</param> /// <param name="addDate">True to add a date string to the filename (default), false otherwise</param>
public Logger(bool tofile, string filename, LogLevel filter = LogLevel.VERBOSE) public Logger(string filename, bool addDate = true)
{ {
_tofile = tofile; if (addDate)
_warnings = false; Filename = $"{Path.GetFileNameWithoutExtension(filename)} ({DateTime.Now:yyyy-MM-dd HH-mm-ss}).{PathExtensions.GetNormalizedExtension(filename)}";
_errors = false; else
_filename = $"{Path.GetFileNameWithoutExtension(filename)} ({DateTime.Now:yyyy-MM-dd HH-mm-ss}).{PathExtensions.GetNormalizedExtension(filename)}"; Filename = filename;
_filter = filter;
if (!Directory.Exists(_basepath)) if (!string.IsNullOrEmpty(LogDirectory) && !Directory.Exists(LogDirectory))
Directory.CreateDirectory(_basepath); Directory.CreateDirectory(LogDirectory);
Start(); Start();
} }
@@ -65,19 +103,19 @@ namespace SabreTools.Library.Logging
/// <returns>True if the logging was started correctly, false otherwise</returns> /// <returns>True if the logging was started correctly, false otherwise</returns>
public bool Start() public bool Start()
{ {
_start = DateTime.Now; StartTime = DateTime.Now;
if (!_tofile) if (!LogToFile)
return true; return true;
try 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) _log = new StreamWriter(logfile, Encoding.UTF8, (int)(4 * Constants.KibiByte), true)
{ {
AutoFlush = 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}"); _log.WriteLine($"Command run: {Globals.CommandLineArgs}");
} }
catch catch
@@ -97,13 +135,13 @@ namespace SabreTools.Library.Logging
{ {
if (!suppress) if (!suppress)
{ {
if (_warnings) if (LoggedWarnings)
Console.WriteLine("There were warnings in the last run! Check the log for more details"); 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"); 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 // Special case for multi-day runs
string total; string total;
@@ -112,7 +150,7 @@ namespace SabreTools.Library.Logging
else else
total = span.ToString(@"hh\:mm\:ss"); total = span.ToString(@"hh\:mm\:ss");
if (!_tofile) if (!LogToFile)
{ {
Console.WriteLine($"Total runtime: {total}"); Console.WriteLine($"Total runtime: {total}");
return true; return true;
@@ -155,7 +193,7 @@ namespace SabreTools.Library.Logging
private bool Log(string output, LogLevel loglevel, bool appendPrefix) 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 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; return true;
// USER and ERROR writes to console // 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); Console.WriteLine((loglevel == LogLevel.ERROR && appendPrefix ? loglevel.ToString() + " " : string.Empty) + output);
// If we're writing to file, use the existing stream // If we're writing to file, use the existing stream
if (_tofile) if (LogToFile)
{ {
try try
{ {
@@ -176,9 +214,7 @@ namespace SabreTools.Library.Logging
{ {
Console.WriteLine(ex); Console.WriteLine(ex);
Console.WriteLine("Could not write to log file!"); Console.WriteLine("Could not write to log file!");
if (Globals.ThrowOnError) if (ThrowOnError) throw ex;
throw ex;
return false; return false;
} }
} }
@@ -206,7 +242,7 @@ namespace SabreTools.Library.Logging
Console.Write(output); Console.Write(output);
// If we're writing to file, use the existing stream // If we're writing to file, use the existing stream
if (_tofile) if (LogToFile)
{ {
try try
{ {
@@ -234,9 +270,7 @@ namespace SabreTools.Library.Logging
/// <returns>True if the output could be written, false otherwise</returns> /// <returns>True if the output could be written, false otherwise</returns>
public bool Verbose(Exception ex, string output = null, bool appendPrefix = true) public bool Verbose(Exception ex, string output = null, bool appendPrefix = true)
{ {
if (Globals.ThrowOnError) if (ThrowOnError) throw ex;
throw ex;
return Verbose($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix); return Verbose($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix);
} }
@@ -260,9 +294,7 @@ namespace SabreTools.Library.Logging
/// <returns>True if the output could be written, false otherwise</returns> /// <returns>True if the output could be written, false otherwise</returns>
public bool User(Exception ex, string output = null, bool appendPrefix = true) public bool User(Exception ex, string output = null, bool appendPrefix = true)
{ {
if (Globals.ThrowOnError) if (ThrowOnError) throw ex;
throw ex;
return User($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix); return User($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix);
} }
@@ -286,9 +318,7 @@ namespace SabreTools.Library.Logging
/// <returns>True if the output could be written, false otherwise</returns> /// <returns>True if the output could be written, false otherwise</returns>
public bool Warning(Exception ex, string output = null, bool appendPrefix = true) public bool Warning(Exception ex, string output = null, bool appendPrefix = true)
{ {
if (Globals.ThrowOnError) if (ThrowOnError) throw ex;
throw ex;
return Warning($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix); return Warning($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix);
} }
@@ -300,7 +330,7 @@ namespace SabreTools.Library.Logging
/// <returns>True if the output could be written, false otherwise</returns> /// <returns>True if the output could be written, false otherwise</returns>
public bool Warning(string output, bool appendPrefix = true) public bool Warning(string output, bool appendPrefix = true)
{ {
_warnings = true; LoggedWarnings = true;
return Log(output, LogLevel.WARNING, appendPrefix); return Log(output, LogLevel.WARNING, appendPrefix);
} }
@@ -313,9 +343,7 @@ namespace SabreTools.Library.Logging
/// <returns>True if the output could be written, false otherwise</returns> /// <returns>True if the output could be written, false otherwise</returns>
public bool Error(Exception ex, string output = null, bool appendPrefix = true) public bool Error(Exception ex, string output = null, bool appendPrefix = true)
{ {
if (Globals.ThrowOnError) if (ThrowOnError) throw ex;
throw ex;
return Error($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix); return Error($"{(output != null ? output + ": " : string.Empty)}{ex}", appendPrefix);
} }
@@ -327,7 +355,7 @@ namespace SabreTools.Library.Logging
/// <returns>True if the output could be written, false otherwise</returns> /// <returns>True if the output could be written, false otherwise</returns>
public bool Error(string output, bool appendPrefix = true) public bool Error(string output, bool appendPrefix = true)
{ {
_errors = true; LoggedErrors = true;
return Log(output, LogLevel.ERROR, appendPrefix); return Log(output, LogLevel.ERROR, appendPrefix);
} }

View File

@@ -20,7 +20,7 @@ namespace SabreTools
public static void Main(string[] args) public static void Main(string[] args)
{ {
// Perform initial setup and verification // 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 // Create a new Help object for this program
_help = RetrieveHelp(); _help = RetrieveHelp();