diff --git a/Logger.cs b/Logger.cs index 35c92ce..d780585 100644 --- a/Logger.cs +++ b/Logger.cs @@ -1,9 +1,11 @@ using System.Text; using System.IO; +using static Xorog.Logger.LoggerObjects; +using Microsoft.Extensions.Logging; namespace Xorog.Logger; -public class Logger +public class Logger : ILogger { private static bool loggerStarted = false; private static LoggerObjects.LogLevel maxLogLevel = LoggerObjects.LogLevel.DEBUG; @@ -25,7 +27,7 @@ public class Logger /// The loglevel that should be displayed in the console, does not affect whats written to file /// Clean up old logs before a datetime /// A bool stating if the logger was started - public static void StartLogger(string filePath = "", LoggerObjects.LogLevel level = LoggerObjects.LogLevel.DEBUG, DateTime cleanUpBefore = new DateTime(), bool ThrowOnFailedDeletion = false) + public static ILogger StartLogger(string filePath = "", LoggerObjects.LogLevel level = LoggerObjects.LogLevel.DEBUG, DateTime cleanUpBefore = new DateTime(), bool ThrowOnFailedDeletion = false) { if (loggerStarted) throw new Exception($"The logger is already started"); @@ -85,8 +87,8 @@ public class Logger string LogLevelText = b.LogLevel.ToString(); - if (LogLevelText.Length != 5) - LogLevelText += " "; + if (LogLevelText.Length < 6) + LogLevelText += new string(' ', 6 - LogLevelText.Length); ConsoleColor LogLevelColor = ConsoleColor.Gray; @@ -100,57 +102,104 @@ public class Logger _ => ConsoleColor.Gray }; - if (b.LogLevel == LoggerObjects.LogLevel.DEBUG) + string LogMessage = b.Message; + + foreach (var blacklistobject in _loggerObjects.Blacklist) + LogMessage = LogMessage.Replace(blacklistobject, new String('*', blacklistobject.Length), StringComparison.CurrentCultureIgnoreCase); + + if (b.LogLevel == LoggerObjects.LogLevel.TRACE) { - if (maxLogLevel == LoggerObjects.LogLevel.DEBUG) + if (maxLogLevel == LoggerObjects.LogLevel.TRACE) { Console.ResetColor(); Console.Write($"[{b.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] "); Console.ForegroundColor = LogLevelColor; Console.Write($"[{LogLevelText}] "); - Console.ResetColor(); Console.WriteLine(b.Message); + Console.ResetColor(); Console.WriteLine(LogMessage); + + if (b.Exception is not null) + Console.WriteLine(b.Exception.ToString()); + } + } + else if (b.LogLevel == LoggerObjects.LogLevel.DEBUG2) + { + if (maxLogLevel is LoggerObjects.LogLevel.DEBUG2 or LoggerObjects.LogLevel.TRACE) + { + Console.ResetColor(); Console.Write($"[{b.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] "); + Console.ForegroundColor = LogLevelColor; Console.Write($"[{LogLevelText}] "); + Console.ResetColor(); Console.WriteLine(LogMessage); + + if (b.Exception is not null) + Console.WriteLine(b.Exception.ToString()); + } + } + else if (b.LogLevel == LoggerObjects.LogLevel.DEBUG) + { + if (maxLogLevel is LoggerObjects.LogLevel.DEBUG or LoggerObjects.LogLevel.DEBUG2 or LoggerObjects.LogLevel.TRACE) + { + Console.ResetColor(); Console.Write($"[{b.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] "); + Console.ForegroundColor = LogLevelColor; Console.Write($"[{LogLevelText}] "); + Console.ResetColor(); Console.WriteLine(LogMessage); + + if (b.Exception is not null) + Console.WriteLine(b.Exception.ToString()); } } else if (b.LogLevel == LoggerObjects.LogLevel.INFO) { - if (maxLogLevel is LoggerObjects.LogLevel.DEBUG or LoggerObjects.LogLevel.INFO) + if (maxLogLevel is LoggerObjects.LogLevel.DEBUG or LoggerObjects.LogLevel.INFO or LoggerObjects.LogLevel.DEBUG2 or LoggerObjects.LogLevel.TRACE) { Console.ResetColor(); Console.Write($"[{b.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] "); Console.ForegroundColor = LogLevelColor; Console.Write($"[{LogLevelText}] "); - Console.ResetColor(); Console.WriteLine(b.Message); + Console.ResetColor(); Console.WriteLine(LogMessage); + + if (b.Exception is not null) + Console.WriteLine(b.Exception.ToString()); } } else if (b.LogLevel == LoggerObjects.LogLevel.WARN) { - if (maxLogLevel is LoggerObjects.LogLevel.DEBUG or LoggerObjects.LogLevel.INFO or LoggerObjects.LogLevel.WARN) + if (maxLogLevel is LoggerObjects.LogLevel.DEBUG or LoggerObjects.LogLevel.INFO or LoggerObjects.LogLevel.WARN or LoggerObjects.LogLevel.DEBUG2 or LoggerObjects.LogLevel.TRACE) { Console.ResetColor(); Console.Write($"[{b.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] "); Console.ForegroundColor = LogLevelColor; Console.Write($"[{LogLevelText}] "); - Console.ResetColor(); Console.WriteLine(b.Message); + Console.ResetColor(); Console.WriteLine(LogMessage); + + if (b.Exception is not null) + Console.WriteLine(b.Exception.ToString()); } } else if (b.LogLevel == LoggerObjects.LogLevel.ERROR) { - if (maxLogLevel is LoggerObjects.LogLevel.DEBUG or LoggerObjects.LogLevel.INFO or LoggerObjects.LogLevel.WARN or LoggerObjects.LogLevel.ERROR) + if (maxLogLevel is LoggerObjects.LogLevel.DEBUG or LoggerObjects.LogLevel.INFO or LoggerObjects.LogLevel.WARN or LoggerObjects.LogLevel.ERROR or LoggerObjects.LogLevel.DEBUG2 or LoggerObjects.LogLevel.TRACE) { Console.ResetColor(); Console.Write($"[{b.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] "); Console.ForegroundColor = LogLevelColor; Console.Write($"[{LogLevelText}] "); - Console.ResetColor(); Console.WriteLine(b.Message); + Console.ResetColor(); Console.WriteLine(LogMessage); + + if (b.Exception is not null) + Console.WriteLine(b.Exception.ToString()); } } else if (b.LogLevel == LoggerObjects.LogLevel.FATAL && maxLogLevel >= LoggerObjects.LogLevel.FATAL) { - if (maxLogLevel is LoggerObjects.LogLevel.DEBUG or LoggerObjects.LogLevel.INFO or LoggerObjects.LogLevel.WARN or LoggerObjects.LogLevel.ERROR or LoggerObjects.LogLevel.FATAL) + if (maxLogLevel is LoggerObjects.LogLevel.DEBUG or LoggerObjects.LogLevel.INFO or LoggerObjects.LogLevel.WARN or LoggerObjects.LogLevel.ERROR or LoggerObjects.LogLevel.FATAL or LoggerObjects.LogLevel.DEBUG2 or LoggerObjects.LogLevel.TRACE) { Console.ResetColor(); Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = LogLevelColor; Console.Write($"[{b.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] "); Console.Write($"[{LogLevelText}]"); - Console.ResetColor(); Console.WriteLine($" {b.Message}"); + Console.ResetColor(); Console.WriteLine($" {LogMessage}"); + + if (b.Exception is not null) + Console.WriteLine(b.Exception.ToString()); } } else { Console.ResetColor(); Console.Write($"[{b.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] "); Console.ForegroundColor = LogLevelColor; Console.Write($"[{LogLevelText}] "); - Console.ResetColor(); Console.WriteLine(b.Message); + Console.ResetColor(); Console.WriteLine(LogMessage); + + if (b.Exception is not null) + Console.WriteLine(b.Exception.ToString()); } _ = Task.Run(() => @@ -162,7 +211,7 @@ public class Logger try { - Byte[] FileWrite = Encoding.UTF8.GetBytes($"[{b.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] [{LogLevelText}] {b.Message}\n"); + Byte[] FileWrite = Encoding.UTF8.GetBytes($"[{b.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] [{LogLevelText}] {LogMessage}\n"); if (OpenedFile != null) { await OpenedFile.WriteAsync(FileWrite.AsMemory(0, FileWrite.Length)); @@ -192,6 +241,7 @@ public class Logger }); GC.KeepAlive(_loggerObjects.LogsToPost); + return new Logger(); } @@ -218,6 +268,17 @@ public class Logger + /// + /// Add blacklisted string to censor automatically + /// + /// + public static void AddBlacklist(string blacklist) + { + _loggerObjects.Blacklist.Add(blacklist); + } + + + /// /// Changes the log level /// @@ -229,35 +290,19 @@ public class Logger - /// - /// Log without any LogLevel - /// - /// - /// - public static void Log(string message) - { - _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry - { - TimeOfEvent = DateTime.Now, - LogLevel = LoggerObjects.LogLevel.NONE, - Message = message - }); - } - - - /// /// Log with debug log level /// /// /// - public static void LogDebug(string message) + public static void LogDebug(string message, Exception? exception = null) { _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry { TimeOfEvent = DateTime.Now, LogLevel = LoggerObjects.LogLevel.DEBUG, - Message = message + Message = message, + Exception = exception }); } @@ -268,13 +313,14 @@ public class Logger /// /// /// - public static void LogInfo(string message) + public static void LogInfo(string message, Exception? exception = null) { _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry { TimeOfEvent = DateTime.Now, LogLevel = LoggerObjects.LogLevel.INFO, - Message = message + Message = message, + Exception = exception }); } @@ -285,13 +331,14 @@ public class Logger /// /// /// - public static void LogWarn(string message) + public static void LogWarn(string message, Exception? exception = null) { _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry { TimeOfEvent = DateTime.Now, LogLevel = LoggerObjects.LogLevel.WARN, - Message = message + Message = message, + Exception = exception }); } @@ -302,13 +349,14 @@ public class Logger /// /// /// - public static void LogError(string message) + public static void LogError(string message, Exception? exception = null) { _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry { TimeOfEvent = DateTime.Now, LogLevel = LoggerObjects.LogLevel.ERROR, - Message = message + Message = message, + Exception = exception }); } @@ -319,13 +367,55 @@ public class Logger /// /// /// - public static void LogFatal(string message) + public static void LogFatal(string message, Exception? exception = null) { _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry { TimeOfEvent = DateTime.Now, LogLevel = LoggerObjects.LogLevel.FATAL, - Message = message + Message = message, + Exception = exception }); } + + + /// + /// Log with standard Microsoft.Extensions.Logging format + /// + /// + /// + /// + /// + /// + /// + public void Log(Microsoft.Extensions.Logging.LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) + { + _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry + { + TimeOfEvent = DateTime.Now, + LogLevel = logLevel switch + { + Microsoft.Extensions.Logging.LogLevel.Debug => LoggerObjects.LogLevel.DEBUG2, + Microsoft.Extensions.Logging.LogLevel.Trace => LoggerObjects.LogLevel.TRACE, + Microsoft.Extensions.Logging.LogLevel.Information => LoggerObjects.LogLevel.INFO, + Microsoft.Extensions.Logging.LogLevel.Warning => LoggerObjects.LogLevel.WARN, + Microsoft.Extensions.Logging.LogLevel.Error => LoggerObjects.LogLevel.ERROR, + Microsoft.Extensions.Logging.LogLevel.Critical => LoggerObjects.LogLevel.FATAL, + Microsoft.Extensions.Logging.LogLevel.None => LoggerObjects.LogLevel.NONE, + _ => throw new NotImplementedException() + }, + Message = $"[{eventId.Id,2}] {formatter(state, exception)}", + Exception = exception + }); + } + + public bool IsEnabled(Microsoft.Extensions.Logging.LogLevel logLevel) + { + return loggerStarted; + } + + public IDisposable BeginScope(TState state) + { + return default!; + } } diff --git a/LoggerObjects.cs b/LoggerObjects.cs index 8a12e6d..264f37c 100644 --- a/LoggerObjects.cs +++ b/LoggerObjects.cs @@ -3,12 +3,14 @@ public class LoggerObjects { internal List LogsToPost = new(); + internal List Blacklist = new(); public class LogEntry { public DateTime TimeOfEvent { get; set; } public LogLevel LogLevel { get; set; } public string Message { get; set; } + public Exception? Exception { get; set; } } public enum LogLevel @@ -18,6 +20,8 @@ public class LoggerObjects WARN, INFO, DEBUG, + DEBUG2, + TRACE, NONE } } diff --git a/LoggerProvider.cs b/LoggerProvider.cs new file mode 100644 index 0000000..dbfbd7e --- /dev/null +++ b/LoggerProvider.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Xorog.Logger; +public class LoggerProvider : ILoggerProvider +{ + private readonly ConcurrentDictionary _loggers = new(StringComparer.OrdinalIgnoreCase); + + public ILogger CreateLogger(string categoryName) + { + return _loggers.GetOrAdd(categoryName, name => new Logger()); + } + + public void Dispose() => _loggers.Clear(); +} diff --git a/Xorog.Logger.csproj b/Xorog.Logger.csproj index 9b938d8..6570da9 100644 --- a/Xorog.Logger.csproj +++ b/Xorog.Logger.csproj @@ -3,9 +3,13 @@ net6.0 enable - disable + annotations Debug;Release;x64 AnyCPU;x64 + + + +