Abstract Class
namespace Delaney
{
public abstract class LogBase
{
protected readonly object lockObj = new object();
public abstract void Information(string message);
public abstract void Warning(string message);
public abstract void Error(string message);
}
}
Class
using System;
using System.IO;
using System.Threading;
namespace Delaney
{
public class HTMLLog : LogBase
{
bool _errorOpeningFile = false;
string _fullname = "";
string _dateFormat = "yyyy-MM-dd HH:mm:ss";
public HTMLLog(string fullname = "")
{
// Guard Clause
if(string.IsNullOrWhiteSpace(fullname))
{
var path = AppDomain.CurrentDomain.BaseDirectory;
fullname = System.IO.Path.Combine(path, "Log.html");
}
_fullname = fullname;
try
{
if (!File.Exists(_fullname))
using (var stream = File.CreateText(_fullname))
{
stream.WriteLine("<style>body { margin-top: 0; }</style>");
stream.WriteLine($"<div style=\"position: sticky; top:0px; padding-top:8px; background: white; display:flex; flex-wrap: nowrap; gap: 1rem; font-family: monospace; font-weight:bold;\"><span style=\"white-space: nowrap; padding-right: 5ch\">Date and Time</span><span>Thread Id</span><span style=\"flex: 0 1 auto; padding-right: 6ch;\">Level</span><span>Description</span></div>");
}
}
catch
{
var s = _fullname;
if (string.IsNullOrWhiteSpace(_fullname))
s = "No fullname present";
Console.WriteLine($"Error creating or loading HTML logger file. Fullname: {s}");
Console.ReadLine();
_errorOpeningFile = true;
}
}
public bool IsVerbose { get; set; }
public override void Information(string message, bool isVerboseLogging = true)
{
var colorStyle = "blue";
var datestring = DateTime.Now.ToString(_dateFormat ) + " ";
if (!isVerboseLogging)
return;
if (_errorOpeningFile)
return;
lock (lockObj)
{
var threadId = Thread.CurrentThread.ManagedThreadId;
Console.Write(datestring);
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write("Information");
Console.ResetColor();
Console.Write(" " + threadId);
Console.WriteLine(" " + message);
if (_errorOpeningFile)
return;
using (var stream = File.AppendText(_fullname))
{
WriteLine(stream, datestring, "Information", message, colorStyle, threadId);
}
}
}
public override void Warning(string message)
{
var colorStyle = "orange";
var datestring = DateTime.Now.ToString(_dateFormat) + " ";
if (_errorOpeningFile)
return;
lock (lockObj)
{
var threadId = Thread.CurrentThread.ManagedThreadId;
Console.Write(datestring);
Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.Write("Warning ");
Console.ResetColor();
Console.Write(" " + threadId);
Console.WriteLine(" " + message);
if (_errorOpeningFile)
return;
using (var stream = File.AppendText(_fullname))
{
WriteLine(stream, datestring, "Warning ", message, colorStyle, threadId);
}
}
}
public override void Error(string message)
{
var colorStyle = "red";
var datestring = DateTime.Now.ToString(_dateFormat) + " ";
if (_errorOpeningFile)
return;
lock (lockObj)
{
var threadId = Thread.CurrentThread.ManagedThreadId;
Console.Write(datestring);
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("Error ");
Console.ResetColor();
Console.Write(" " + threadId);
Console.WriteLine(" " + message);
if (_errorOpeningFile)
return;
using (var stream = File.AppendText(_fullname))
{
WriteLine(stream, datestring, "Error ", message, colorStyle, threadId);
}
}
}
private void WriteLine(StreamWriter stream, string dateString, string status, string message, string color, int threadId)
{
stream.WriteLine($"<div style=\"display:flex; flex-wrap: nowrap; gap: 1rem; font-family: monospace\"><span style=\"white-space: nowrap;\">{dateString}</span><span style=\"padding-left: 7ch\">{threadId}</span><span style=\"flex: 0 1 auto;color: {color}\">{status}</span><span>{message}</span></div>");
}
}
}