Files
SabreTools/SabreTools.Helper/Logger.cs

288 lines
7.8 KiB
C#
Raw Normal View History

2016-03-28 17:54:24 -07:00
using System;
using System.IO;
namespace SabreTools.Helper
2016-03-28 17:54:24 -07:00
{
/// <summary>
/// Log either to file or to the console
/// </summary>
2016-05-22 23:57:44 -07:00
/// <remarks>
/// Things to do:
/// - Allow for "triggerable" logging done on an interval (async)
/// - Log filtering? (#if debug?)
2016-05-22 23:57:44 -07:00
/// </remarks>
2016-03-28 18:40:35 -07:00
public class Logger
2016-03-28 17:54:24 -07:00
{
/// <summary>
/// Severity of the logging statement
/// </summary>
private enum LogLevel
{
VERBOSE = 0,
USER,
WARNING,
ERROR,
}
2016-03-28 17:54:24 -07:00
// Private instance variables
private bool _tofile;
private bool _warnings;
2016-10-11 22:10:28 -07:00
private bool _errors;
2016-03-28 17:54:24 -07:00
private string _filename;
2016-04-27 22:17:19 -07:00
private DateTime _start;
2016-03-28 17:54:24 -07:00
private StreamWriter _log;
2016-05-10 16:01:32 -07:00
// Private required variables
private string _basepath = "logs" + Path.DirectorySeparatorChar;
2016-05-10 16:01:32 -07:00
/// <summary>
/// Initialize a console-only logger object
/// </summary>
public Logger()
{
_tofile = false;
_warnings = false;
_errors = false;
_filename = null;
Start();
}
/// <summary>
/// Initialize a Logger object with the given information
/// </summary>
/// <param name="tofile">True if file should be written to instead of console</param>
/// <param name="filename">Filename representing log location</param>
public Logger(bool tofile, string filename)
2016-03-28 17:54:24 -07:00
{
_tofile = tofile;
_warnings = false;
_errors = false;
_filename = Path.GetFileNameWithoutExtension(filename) + " (" + DateTime.Now.ToString("yyyy-MM-dd HHmmss") + ")" + Path.GetExtension(filename);
2016-05-10 16:01:32 -07:00
if (!Directory.Exists(_basepath))
{
Directory.CreateDirectory(_basepath);
}
Start();
2016-03-28 17:54:24 -07:00
}
/// <summary>
/// Start logging by opening output file (if necessary)
/// </summary>
/// <returns>True if the logging was started correctly, false otherwise</returns>
2016-03-28 17:54:24 -07:00
public bool Start()
{
2016-04-28 17:39:10 -07:00
_start = DateTime.Now;
2016-03-28 17:54:24 -07:00
if (!_tofile)
{
return true;
}
try
{
_log = new StreamWriter(File.Open(_basepath + _filename, FileMode.OpenOrCreate | FileMode.Append));
2016-03-28 17:54:24 -07:00
_log.WriteLine("Logging started " + DateTime.Now);
_log.WriteLine(Environment.CommandLine);
_log.Flush();
2016-03-28 17:54:24 -07:00
}
catch
{
return false;
}
return true;
}
/// <summary>
/// End logging by closing output file (if necessary)
/// </summary>
/// <param name="suppress">True if all ending output is to be suppressed, false otherwise (default)</param>
/// <returns>True if the logging was ended correctly, false otherwise</returns>
public bool Close(bool suppress = false)
2016-03-28 17:54:24 -07:00
{
if (!suppress)
2016-03-28 17:54:24 -07:00
{
if (_warnings)
{
Console.WriteLine("There were warnings in the last run! Check the log for more details");
}
if (_errors)
{
Console.WriteLine("There were errors in the last run! Check the log for more details");
}
TimeSpan span = DateTime.Now.Subtract(_start);
string total = span.ToString(@"hh\:mm\:ss");
if (!_tofile)
{
Console.WriteLine("Total runtime: " + total);
return true;
}
2016-03-28 17:54:24 -07:00
try
{
_log.WriteLine("Logging ended " + DateTime.Now);
_log.WriteLine("Total runtime: " + total);
Console.WriteLine("Total runtime: " + total);
_log.Close();
}
catch
{
return false;
}
2016-03-28 17:54:24 -07:00
}
else
2016-03-28 17:54:24 -07:00
{
try
{
_log.Close();
}
catch
{
return false;
}
2016-03-28 17:54:24 -07:00
}
return true;
}
/// <summary>
/// Write the given string to the log output
/// </summary>
/// <param name="output">String to be written log</param>
2016-03-30 13:53:14 -07:00
/// <param name="loglevel">Severity of the information being logged</param>
/// <param name="appendPrefix">True if the level and datetime should be prepended to each statement, false otherwise</param>
/// <returns>True if the output could be written, false otherwise</returns>
private bool Log(string output, LogLevel loglevel, bool appendPrefix)
2016-03-28 17:54:24 -07:00
{
// USER and ERROR writes to console
if (loglevel == LogLevel.USER || loglevel == LogLevel.ERROR)
{
Console.WriteLine((loglevel == LogLevel.ERROR && appendPrefix ? loglevel.ToString() + " " : "") + output);
}
2016-03-30 12:18:56 -07:00
2016-03-28 17:54:24 -07:00
// If we're writing to file, use the existing stream
2016-03-30 12:18:56 -07:00
if (_tofile)
2016-03-28 17:54:24 -07:00
{
2016-03-30 12:18:56 -07:00
try
{
_log.WriteLine((appendPrefix ? loglevel.ToString() + " - " + DateTime.Now + " - " : "" ) + output);
_log.Flush();
2016-03-30 12:18:56 -07:00
}
catch
{
Console.WriteLine("Could not write to log file!");
2016-06-22 20:57:53 -07:00
return false;
}
}
return true;
}
/// <summary>
/// Write the given exact string to the log output
/// </summary>
/// <param name="output">String to be written log</param>
/// <param name="line">Line number to write out to</param>
/// <param name="column">Column number to write out to</param>
2016-06-22 20:57:53 -07:00
/// <returns>True if the output could be written, false otherwise</returns>
public bool WriteExact(string output, int line, int column)
2016-06-22 20:57:53 -07:00
{
// Set the cursor position (if not being redirected)
if (!Console.IsOutputRedirected)
{
Console.CursorTop = line;
Console.CursorLeft = column;
}
// Write out to the console
2016-06-29 13:44:41 -07:00
Console.Write(output);
2016-06-22 20:57:53 -07:00
// If we're writing to file, use the existing stream
if (_tofile)
{
try
{
_log.Write(DateTime.Now + " - " + output);
_log.Flush();
}
catch
{
Console.WriteLine("Could not write to log file!");
2016-03-30 12:18:56 -07:00
return false;
}
2016-03-28 17:54:24 -07:00
}
return true;
}
2016-03-30 13:36:52 -07:00
/// <summary>
/// Write the given string as a verbose message to the log output
/// </summary>
/// <param name="output">String to be written log</param>
/// <param name="appendPrefix">True if the level and datetime should be prepended to each statement (default), false otherwise</param>
/// <returns>True if the output could be written, false otherwise</returns>s
public bool Verbose(string output, bool appendPrefix = true)
{
return Log(output, LogLevel.VERBOSE, appendPrefix);
}
2016-05-22 23:57:44 -07:00
/// <summary>
/// Write the given string as a user message to the log output
/// </summary>
/// <param name="output">String to be written log</param>
/// <param name="appendPrefix">True if the level and datetime should be prepended to each statement (default), false otherwise</param>
2016-05-22 23:57:44 -07:00
/// <returns>True if the output could be written, false otherwise</returns>
public bool User(string output, bool appendPrefix = true)
{
return Log(output, LogLevel.USER, appendPrefix);
}
2016-03-30 13:53:14 -07:00
/// <summary>
/// Write the given string as a warning to the log output
/// </summary>
/// <param name="output">String to be written log</param>
/// <param name="appendPrefix">True if the level and datetime should be prepended to each statement (default), false otherwise</param>
2016-03-30 13:53:14 -07:00
/// <returns>True if the output could be written, false otherwise</returns>
public bool Warning(string output, bool appendPrefix = true)
2016-03-30 13:53:14 -07:00
{
_warnings = true;
return Log(output, LogLevel.WARNING, appendPrefix);
2016-03-30 13:53:14 -07:00
}
2016-03-30 13:36:52 -07:00
/// <summary>
/// Writes the given string as an error in the log
/// </summary>
/// <param name="output">String to be written log</param>
/// <param name="appendPrefix">True if the level and datetime should be prepended to each statement (default), false otherwise</param>
2016-03-30 13:36:52 -07:00
/// <returns>True if the output could be written, false otherwise</returns>
public bool Error(string output, bool appendPrefix = true)
2016-03-30 13:36:52 -07:00
{
2016-10-11 22:10:28 -07:00
_errors = true;
return Log(output, LogLevel.ERROR, appendPrefix);
2016-03-30 13:36:52 -07:00
}
/// <summary>
/// Clear lines beneath the given line in the console
/// </summary>
/// <param name="line">Line number to clear beneath</param>
/// <returns>True</returns>
public bool ClearBeneath(int line)
{
if (!Console.IsOutputRedirected)
{
for (int i = line; i < Console.WindowHeight; i++)
{
// http://stackoverflow.com/questions/8946808/can-console-clear-be-used-to-only-clear-a-line-instead-of-whole-console
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, i);
}
}
return true;
}
2016-03-28 17:54:24 -07:00
}
}