diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..e4ca311
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "nuget" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "daily"
diff --git a/Entities/LogEntry.cs b/Entities/LogEntry.cs
new file mode 100644
index 0000000..081bae6
--- /dev/null
+++ b/Entities/LogEntry.cs
@@ -0,0 +1,33 @@
+namespace Xorog.Logger;
+
+public class LogEntry
+{
+ internal LogEntry() { }
+
+ internal string RawMessage { get; set; }
+
+ ///
+ /// The time of the event.
+ ///
+ public DateTime TimeOfEvent { get; internal set; }
+
+ ///
+ /// The severity of the event.
+ ///
+ public CustomLogLevel LogLevel { get; internal set; }
+
+ ///
+ /// The message describing the event.
+ ///
+ public string Message { get; internal set; }
+
+ ///
+ /// Any objects involved in creating the event message.
+ ///
+ public object[] Args { get; internal set; } = Array.Empty();
+
+ ///
+ /// The exception that's been caused.
+ ///
+ public Exception? Exception { get; internal set; }
+}
\ No newline at end of file
diff --git a/Entities/StringPart.cs b/Entities/StringPart.cs
new file mode 100644
index 0000000..6f8cc23
--- /dev/null
+++ b/Entities/StringPart.cs
@@ -0,0 +1,13 @@
+namespace Xorog.Logger;
+
+internal class StringPart : IDisposable
+{
+ internal string String { get; set; }
+ internal ConsoleColor? Color { get; set; }
+
+ public void Dispose()
+ {
+ String = "";
+ Color = null;
+ }
+}
diff --git a/Enums/CustomLogLevel.cs b/Enums/CustomLogLevel.cs
new file mode 100644
index 0000000..42fc1e8
--- /dev/null
+++ b/Enums/CustomLogLevel.cs
@@ -0,0 +1,14 @@
+namespace Xorog.Logger;
+
+public enum CustomLogLevel
+{
+ None,
+ Fatal,
+ Error,
+ Warn,
+ Info,
+ Debug,
+ Debug2,
+ Trace,
+ Trace2
+}
\ No newline at end of file
diff --git a/Events/LogMessageEventArgs.cs b/Events/LogMessageEventArgs.cs
index 15dac8e..30fe8fd 100644
--- a/Events/LogMessageEventArgs.cs
+++ b/Events/LogMessageEventArgs.cs
@@ -1,7 +1,6 @@
-namespace Xorog.Logger;
+namespace Xorog.Logger.EventArgs;
-public class LogMessageEventArgs : EventArgs
+public class LogMessageEventArgs : System.EventArgs
{
- public LoggerObjects.LogEntry LogEntry { get; set; }
-
+ public LogEntry LogEntry { get; set; }
}
\ No newline at end of file
diff --git a/Global.cs b/Global.cs
new file mode 100644
index 0000000..e2658b3
--- /dev/null
+++ b/Global.cs
@@ -0,0 +1,7 @@
+global using Microsoft.Extensions.Logging;
+global using System;
+global using System.Collections.Generic;
+global using System.IO;
+global using System.Linq;
+global using System.Text;
+global using System.Threading.Tasks;
\ No newline at end of file
diff --git a/GlobalSuppressions.cs b/GlobalSuppressions.cs
new file mode 100644
index 0000000..67e20ae
--- /dev/null
+++ b/GlobalSuppressions.cs
@@ -0,0 +1,8 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "member", Target = "~P:Xorog.Logger.LoggerProvider._logger")]
diff --git a/Logger.cs b/Logger.cs
deleted file mode 100644
index 79a44ad..0000000
--- a/Logger.cs
+++ /dev/null
@@ -1,406 +0,0 @@
-using System.Text;
-using System.IO;
-using static Xorog.Logger.LoggerObjects;
-using Microsoft.Extensions.Logging;
-
-namespace Xorog.Logger;
-
-public class Logger : ILogger
-{
- private static bool loggerStarted = false;
- private static LoggerObjects.LogLevel maxLogLevel = LoggerObjects.LogLevel.DEBUG;
-
- private static string FileName = "";
- private static FileStream OpenedFile { get; set; }
-
- private readonly static LoggerObjects _loggerObjects = new();
-
- private static Task RunningLogger = null;
-
- public static event EventHandler LogRaised;
-
-
- ///
- /// Starts the logger with specified settings
- ///
- /// Where the current logs should be saved to, leave blank if logs shouldnt be saved
- /// 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 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");
-
- if (filePath is not "")
- {
- FileName = filePath;
- OpenedFile = File.Open(FileName, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read);
- }
-
- loggerStarted = true;
- maxLogLevel = level;
-
- if (cleanUpBefore != new DateTime())
- {
- foreach (var b in Directory.GetFiles(new FileInfo(filePath).Directory.FullName))
- {
- try
- {
- FileInfo fi = new(b);
- if (fi.CreationTimeUtc < cleanUpBefore)
- {
- fi.Delete();
- LogDebug($"{fi.Name} deleted");
- }
- }
- catch (Exception ex)
- {
- if (!ThrowOnFailedDeletion)
- LogError( $"Couldn't delete log file {b}", ex);
- else
- throw new Exception($"Failed to delete {b}: {ex}");
- }
- }
- }
-
- RunningLogger = Task.Run(async () =>
- {
- while (loggerStarted)
- {
- try
- {
- while (_loggerObjects.LogsToPost.Count == 0)
- {
- Thread.Sleep(10);
- }
-
- for (int i = 0; i < _loggerObjects.LogsToPost.Count; i++)
- {
- var currentLog = _loggerObjects.LogsToPost[0];
- _loggerObjects.LogsToPost.Remove(currentLog);
-
-
- if (currentLog is null)
- {
- continue;
- }
-
- string LogLevelText = currentLog.LogLevel.ToString();
-
- if (LogLevelText.Length < 6)
- LogLevelText += new string(' ', 6 - LogLevelText.Length);
-
- ConsoleColor LogLevelColor;
- ConsoleColor BackgroundColor;
-
- LogLevelColor = currentLog.LogLevel switch
- {
- LoggerObjects.LogLevel.TRACE => ConsoleColor.Gray,
- LoggerObjects.LogLevel.DEBUG2 => ConsoleColor.Gray,
- LoggerObjects.LogLevel.DEBUG => ConsoleColor.Gray,
- LoggerObjects.LogLevel.INFO => ConsoleColor.Green,
- LoggerObjects.LogLevel.WARN => ConsoleColor.Yellow,
- LoggerObjects.LogLevel.ERROR => ConsoleColor.Red,
- LoggerObjects.LogLevel.FATAL => ConsoleColor.Black,
- _ => ConsoleColor.Gray
- };
-
- BackgroundColor = currentLog.LogLevel switch
- {
- LoggerObjects.LogLevel.FATAL => ConsoleColor.DarkRed,
- _ => ConsoleColor.Black
- };
-
- string LogMessage = currentLog.Message;
-
- foreach (var blacklistobject in _loggerObjects.Blacklist)
- LogMessage = LogMessage.Replace(blacklistobject, new String('*', blacklistobject.Length), StringComparison.CurrentCultureIgnoreCase);
-
- if (maxLogLevel >= currentLog.LogLevel)
- {
- Console.ResetColor(); Console.Write($"[{currentLog.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] ");
- Console.ForegroundColor = LogLevelColor; Console.BackgroundColor = BackgroundColor; Console.Write($"[{LogLevelText}]");
- Console.ResetColor(); Console.WriteLine($" {LogMessage}");
-
- if (currentLog.Exception is not null)
- Console.WriteLine(currentLog.Exception.ToString());
- }
-
- _ = Task.Run(() =>
- {
- LogRaised?.Invoke(null, new LogMessageEventArgs() { LogEntry = currentLog });
- });
-
- try
- {
- if (!_loggerObjects.FileBlackList.Contains(currentLog.LogLevel))
- {
- Byte[] FileWrite = Encoding.UTF8.GetBytes($"[{currentLog.TimeOfEvent:dd.MM.yyyy HH:mm:ss}] [{LogLevelText}] {LogMessage}\n{(currentLog.Exception is not null ? $"{currentLog.Exception}\n" : "")}");
- if (OpenedFile != null)
- {
- await OpenedFile.WriteAsync(FileWrite.AsMemory(0, FileWrite.Length));
- OpenedFile.Flush();
- }
- }
- }
- catch (Exception ex)
- {
- LogFatal($"Couldn't write log to file: {ex}");
- }
- }
- }
- catch (Exception ex)
- {
- LogError("An exception occured while trying to display a log message", ex);
- await Task.Delay(1000);
- continue;
- }
- }
- });
-
- return new Logger();
- }
-
-
-
- ///
- /// Stops the logger
- ///
- public static void StopLogger()
- {
- loggerStarted = false;
- maxLogLevel = LoggerObjects.LogLevel.DEBUG;
- FileName = "";
-
- Thread.Sleep(500);
-
- if (RunningLogger is not null)
- RunningLogger.Dispose();
-
- RunningLogger = null;
-
- if (OpenedFile is not null)
- OpenedFile.Close();
- }
-
-
-
- ///
- /// Add blacklisted string to censor automatically
- ///
- ///
- public static void AddBlacklist(string blacklist)
- {
- _loggerObjects.Blacklist.Add(blacklist);
- }
-
- ///
- /// Add blacklisted log level to not save
- ///
- ///
- public static void AddLogLevelBlacklist(LoggerObjects.LogLevel level)
- {
- _loggerObjects.FileBlackList.Add(level);
- }
-
-
-
- ///
- /// Changes the log level
- ///
- ///
- public static void ChangeLogLevel(LoggerObjects.LogLevel level)
- {
- maxLogLevel = level;
- }
-
-
-
- ///
- /// Log with none log level
- ///
- ///
- ///
- public static void LogNone(string message, Exception? exception = null)
- {
- _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry
- {
- TimeOfEvent = DateTime.Now,
- LogLevel = LoggerObjects.LogLevel.NONE,
- Message = message,
- Exception = exception
- });
- }
-
-
-
- ///
- /// Log with trace log level
- ///
- ///
- ///
- public static void LogTrace(string message, Exception? exception = null)
- {
- _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry
- {
- TimeOfEvent = DateTime.Now,
- LogLevel = LoggerObjects.LogLevel.TRACE,
- Message = message,
- Exception = exception
- });
- }
-
-
-
- ///
- /// Log with debug2 log level
- ///
- ///
- ///
- public static void LogDebug2(string message, Exception? exception = null)
- {
- _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry
- {
- TimeOfEvent = DateTime.Now,
- LogLevel = LoggerObjects.LogLevel.DEBUG2,
- Message = message,
- Exception = exception
- });
- }
-
-
-
- ///
- /// Log with debug log level
- ///
- ///
- ///
- public static void LogDebug(string message, Exception? exception = null)
- {
- _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry
- {
- TimeOfEvent = DateTime.Now,
- LogLevel = LoggerObjects.LogLevel.DEBUG,
- Message = message,
- Exception = exception
- });
- }
-
-
-
- ///
- /// Log with info log level
- ///
- ///
- ///
- public static void LogInfo(string message, Exception? exception = null)
- {
- _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry
- {
- TimeOfEvent = DateTime.Now,
- LogLevel = LoggerObjects.LogLevel.INFO,
- Message = message,
- Exception = exception
- });
- }
-
-
-
- ///
- /// Log with warn log level
- ///
- ///
- ///
- public static void LogWarn(string message, Exception? exception = null)
- {
- _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry
- {
- TimeOfEvent = DateTime.Now,
- LogLevel = LoggerObjects.LogLevel.WARN,
- Message = message,
- Exception = exception
- });
- }
-
-
-
- ///
- /// Log with error log level
- ///
- ///
- ///
- public static void LogError(string message, Exception? exception = null)
- {
- _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry
- {
- TimeOfEvent = DateTime.Now,
- LogLevel = LoggerObjects.LogLevel.ERROR,
- Message = message,
- Exception = exception
- });
- }
-
-
-
- ///
- /// Log with fatal log level
- ///
- ///
- ///
- public static void LogFatal(string message, Exception? exception = null)
- {
- _loggerObjects.LogsToPost.Add(new LoggerObjects.LogEntry
- {
- TimeOfEvent = DateTime.Now,
- LogLevel = LoggerObjects.LogLevel.FATAL,
- 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.TRACE2,
- 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/LoggerClient.cs b/LoggerClient.cs
new file mode 100644
index 0000000..6b1a463
--- /dev/null
+++ b/LoggerClient.cs
@@ -0,0 +1,696 @@
+using Newtonsoft.Json;
+using Xorog.Logger.EventArgs;
+
+namespace Xorog.Logger;
+
+public sealed class LoggerClient : ILogger
+{
+ internal LoggerClient() { }
+
+ ///
+ /// The .
+ ///
+ public LoggerProvider Provider { get; internal set; }
+
+ private bool LoggerStarted = false;
+ private CustomLogLevel MaxLogLevel = CustomLogLevel.Debug;
+
+ private string FileName = "";
+ private FileStream OpenedFile { get; set; }
+
+ internal List LogsToPost = new();
+ internal List Blacklist = new();
+ internal List FileBlackList = new();
+
+ private Task RunningLogger = null;
+
+ ///
+ /// Fired when a log message has been sent.
+ ///
+ public event EventHandler LogRaised;
+
+
+ ///
+ /// Starts the logger with specified settings
+ ///
+ /// Where the current logs should be saved to, leave blank if logs shouldnt be saved
+ /// 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 LoggerClient StartLogger(string filePath = "", CustomLogLevel level = CustomLogLevel.Debug, DateTime cleanUpBefore = new DateTime(), bool ThrowOnFailedDeletion = false)
+ {
+ DirectoryInfo directoryInfo = new(new FileInfo(filePath).DirectoryName);
+
+ if (!directoryInfo.Exists)
+ directoryInfo.Create();
+
+ filePath = filePath.Replace("\\", "/");
+
+ var handler = new LoggerClient();
+ handler.Provider = new(handler);
+
+ if (handler.LoggerStarted)
+ throw new Exception($"The logger is already started");
+
+ if (filePath is not "")
+ {
+ if (filePath.Contains('/'))
+ {
+ var dirPath = filePath[..filePath.LastIndexOf('/')];
+
+ if (!Directory.Exists(dirPath))
+ _ = Directory.CreateDirectory(dirPath);
+ }
+
+ handler.FileName = filePath;
+ handler.OpenedFile = File.Open(handler.FileName, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read);
+ }
+
+ handler.LoggerStarted = true;
+ handler.MaxLogLevel = level;
+
+ if (cleanUpBefore != new DateTime())
+ {
+ foreach (var b in Directory.GetFiles(new FileInfo(filePath).Directory.FullName))
+ {
+ try
+ {
+ FileInfo fi = new(b);
+ if (fi.CreationTimeUtc < cleanUpBefore)
+ {
+ fi.Delete();
+ handler.LogDebug($"{fi.Name} deleted");
+ }
+ }
+ catch (Exception ex)
+ {
+ if (!ThrowOnFailedDeletion)
+ handler.LogError( $"Couldn't delete log file {b}", ex);
+ else
+ throw new Exception($"Failed to delete {b}: {ex}");
+ }
+ }
+ }
+
+ handler.RunningLogger = Task.Run(async () =>
+ {
+ while (handler.LoggerStarted)
+ {
+ try
+ {
+ while (handler.LogsToPost.Count == 0)
+ {
+ Thread.Sleep(10);
+ }
+
+ for (var i = 0; i < handler.LogsToPost.Count; i++)
+ {
+ var currentLog = handler.LogsToPost[0];
+ _ = handler.LogsToPost.Remove(currentLog);
+
+
+ if (currentLog is null || currentLog.RawMessage is null)
+ {
+ continue;
+ }
+
+ var LogLevelText = $"{currentLog.LogLevel,-6}";
+
+ ConsoleColor LogLevelColor;
+ ConsoleColor BackgroundColor;
+
+ LogLevelColor = currentLog.LogLevel switch
+ {
+ CustomLogLevel.Trace => ConsoleColor.Gray,
+ CustomLogLevel.Debug2 => ConsoleColor.Gray,
+ CustomLogLevel.Debug => ConsoleColor.Gray,
+ CustomLogLevel.Info => ConsoleColor.Cyan,
+ CustomLogLevel.Warn => ConsoleColor.Yellow,
+ CustomLogLevel.Error => ConsoleColor.Red,
+ CustomLogLevel.Fatal => ConsoleColor.Black,
+ _ => ConsoleColor.Gray
+ };
+
+ BackgroundColor = currentLog.LogLevel switch
+ {
+ CustomLogLevel.Fatal => ConsoleColor.DarkRed,
+ _ => ConsoleColor.Black
+ };
+
+ var leftOver = currentLog.RawMessage;
+
+ foreach (var blacklistobject in handler.Blacklist)
+ leftOver = leftOver.Replace(blacklistobject, new String('*', blacklistobject.Length), StringComparison.CurrentCultureIgnoreCase);
+
+ var currentArg = 0;
+ var inTemplate = false;
+ var attemptedParsing = false;
+ List builder = new();
+
+ while (leftOver.Length > 0)
+ {
+ if (inTemplate)
+ {
+ attemptedParsing = true;
+ if (currentLog.Args?.Length >= currentArg && currentLog.Args?.Length != 0)
+ {
+ try
+ {
+ var endIndex = leftOver.IndexOf('}');
+
+ if (currentArg > currentLog.Args.Length)
+ continue;
+
+ var objectToAdd = currentLog.Args[currentArg];
+ currentArg++;
+
+ if (objectToAdd is null)
+ continue;
+
+ if (objectToAdd.GetType() == typeof(int))
+ builder.Add(new StringPart { String = objectToAdd.ToString(), Color = ConsoleColor.Magenta });
+ else if (objectToAdd.GetType() == typeof(long))
+ builder.Add(new StringPart { String = objectToAdd.ToString(), Color = ConsoleColor.Magenta });
+ else if (objectToAdd.GetType() == typeof(uint))
+ builder.Add(new StringPart { String = objectToAdd.ToString(), Color = ConsoleColor.Magenta });
+ else if (objectToAdd.GetType() == typeof(ulong))
+ builder.Add(new StringPart { String = objectToAdd.ToString(), Color = ConsoleColor.Magenta });
+ else
+ builder.Add(new StringPart { String = objectToAdd.ToString(), Color = ConsoleColor.Cyan });
+
+ inTemplate = false;
+
+ leftOver = leftOver[(endIndex + 1)..];
+ attemptedParsing = false;
+ }
+ catch (Exception)
+ {
+ currentArg++;
+ continue;
+ }
+ continue;
+ }
+ }
+
+ inTemplate = false;
+
+ var placeholderIndex = leftOver.IndexOf('{');
+
+ if (placeholderIndex != -1)
+ inTemplate = true;
+
+ if (placeholderIndex == -1 || placeholderIndex > leftOver.Length)
+ placeholderIndex = leftOver.Length;
+
+ if (placeholderIndex == 0 && attemptedParsing)
+ placeholderIndex = leftOver.Length;
+
+ var str = leftOver[..placeholderIndex];
+ if (!string.IsNullOrEmpty(str))
+ builder.Add(new StringPart { String = str });
+
+ leftOver = leftOver[placeholderIndex..];
+ attemptedParsing = false;
+ }
+
+ if (handler.MaxLogLevel >= currentLog.LogLevel)
+ {
+ Console.ResetColor(); Console.Write($"[{currentLog.TimeOfEvent:dd.MM.yyyy HH:mm:ss:fff}] ");
+ Console.ForegroundColor = LogLevelColor; Console.BackgroundColor = BackgroundColor; Console.Write($"[{LogLevelText}]"); Console.ResetColor(); Console.Write(" ");
+
+ foreach (var part in builder)
+ {
+ Console.ForegroundColor = part.Color ?? ConsoleColor.White;
+ Console.BackgroundColor = ConsoleColor.Black;
+
+ Console.Write($"{part.String}");
+ }
+ Console.ResetColor();
+ Console.WriteLine();
+
+ if (currentLog.Exception is not null)
+ try
+ {
+ Console.WriteLine(JsonConvert.SerializeObject(currentLog.Exception, Formatting.Indented, new JsonSerializerSettings()
+ {
+ NullValueHandling = NullValueHandling.Ignore,
+ ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
+ Error = (serializer, err) => err.ErrorContext.Handled = true
+ }));
+ }
+ catch (Exception)
+ {
+ Console.WriteLine(currentLog.Exception);
+ }
+ }
+
+ currentLog.Message = string.Join("", builder.Select(x => x.String));
+
+ for (var i1 = 0; i1 < builder.Count; i1++)
+ {
+ builder[i1].Dispose();
+ }
+ builder.Clear();
+
+ _ = Task.Run(() => handler.LogRaised?.Invoke(null, new LogMessageEventArgs() { LogEntry = currentLog }));
+
+ try
+ {
+ if (!handler.FileBlackList.Contains(currentLog.LogLevel))
+ {
+ var FileWrite = Encoding.UTF8.GetBytes($"[{currentLog.TimeOfEvent:dd.MM.yyyy HH:mm:ss:fff}] [{LogLevelText}] {currentLog.Message}\n{(currentLog.Exception is not null ? $"{currentLog.Exception}\n" : "")}");
+ if (handler.OpenedFile != null)
+ {
+ await handler.OpenedFile.WriteAsync(FileWrite.AsMemory(0, FileWrite.Length));
+ handler.OpenedFile.Flush();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ handler.LogFatal($"Couldn't write log to file: {ex}");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ handler.LogError("An exception occurred while trying to display a log message", ex);
+ await Task.Delay(1000);
+ continue;
+ }
+ }
+ });
+
+ return handler;
+ }
+
+ ///
+ /// Stops the logger
+ ///
+ public void StopLogger()
+ {
+ LoggerStarted = false;
+ MaxLogLevel = CustomLogLevel.Debug;
+ FileName = "";
+
+ Thread.Sleep(500);
+
+ RunningLogger?.Dispose();
+
+ RunningLogger = null;
+
+ this.OpenedFile?.Close();
+ }
+
+ ///
+ /// Add strings automatically censor on output to console and file.
+ ///
+ /// The strings to censor
+ public void AddBlacklist(params string[] blacklist)
+ {
+ for (var i = 0; i < blacklist.Length; i++)
+ {
+ if (!string.IsNullOrWhiteSpace(blacklist[i]))
+ Blacklist.Add(blacklist[i]);
+ }
+ }
+
+ ///
+ /// Add blacklisted log level to not save
+ ///
+ /// The log levels not to save to the log file
+ public void AddLogLevelBlacklist(params CustomLogLevel[] levels)
+ {
+ for (var i = 0; i < levels.Length; i++)
+ {
+ FileBlackList.Add(levels[i]);
+ }
+ }
+
+ ///
+ /// Changes the log level
+ ///
+ /// The new log level to apply
+ public void ChangeLogLevel(CustomLogLevel level) => MaxLogLevel = level;
+
+ ///
+ /// Log with none log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ /// The objects involved in the event
+ public void LogNone(string message, Exception? exception = null, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.None,
+ RawMessage = message,
+ Args = args,
+ Exception = exception
+ });
+
+ ///
+ /// Log with none log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ public void LogNone(string message, Exception? exception = null) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.None,
+ RawMessage = message,
+ Exception = exception
+ });
+
+ ///
+ /// Log with none log level
+ ///
+ /// The message to display
+ /// The objects involved in the event
+ public void LogNone(string message, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.None,
+ RawMessage = message,
+ Args = args
+ });
+
+ ///
+ /// Log with trace log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ /// The objects involved in the event
+ public void LogTrace(string message, Exception? exception = null, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Trace,
+ RawMessage = message,
+ Args = args,
+ Exception = exception
+ });
+
+ ///
+ /// Log with trace log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ public void LogTrace(string message, Exception? exception = null) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Trace,
+ RawMessage = message,
+ Exception = exception
+ });
+
+ ///
+ /// Log with trace log level
+ ///
+ /// The message to display
+ /// The objects involved in the event
+ public void LogTrace(string message, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Trace,
+ RawMessage = message,
+ Args = args,
+ });
+
+ ///
+ /// Log with debug2 log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ /// The objects involved in the event
+ public void LogDebug2(string message, Exception? exception = null, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Debug2,
+ RawMessage = message,
+ Args = args,
+ Exception = exception
+ });
+
+ ///
+ /// Log with debug2 log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ public void LogDebug2(string message, Exception? exception = null) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Debug2,
+ RawMessage = message,
+ Exception = exception
+ });
+
+ ///
+ /// Log with debug2 log level
+ ///
+ /// The message to display
+ /// The objects involved in the event
+ public void LogDebug2(string message, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Debug2,
+ RawMessage = message,
+ Args = args
+ });
+
+ ///
+ /// Log with debug log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ /// The objects involved in the event
+ public void LogDebug(string message, Exception? exception = null, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Debug,
+ RawMessage = message,
+ Args = args,
+ Exception = exception
+ });
+
+ ///
+ /// Log with debug log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ public void LogDebug(string message, Exception? exception = null) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Debug,
+ RawMessage = message,
+ Exception = exception
+ });
+
+ ///
+ /// Log with debug log level
+ ///
+ /// The message to display
+ /// The objects involved in the event
+ public void LogDebug(string message, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Debug,
+ RawMessage = message,
+ Args = args
+ });
+
+ ///
+ /// Log with info log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ /// The objects involved in the event
+ public void LogInfo(string message, Exception? exception = null, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Info,
+ RawMessage = message,
+ Args = args,
+ Exception = exception
+ });
+
+ ///
+ /// Log with info log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ public void LogInfo(string message, Exception? exception = null) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Info,
+ RawMessage = message,
+ Exception = exception
+ });
+
+ ///
+ /// Log with info log level
+ ///
+ /// The message to display
+ /// The objects involved in the event
+ public void LogInfo(string message, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Info,
+ RawMessage = message,
+ Args = args
+ });
+
+ ///
+ /// Log with warn log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ /// The objects involved in the event
+ public void LogWarn(string message, Exception? exception = null, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Warn,
+ RawMessage = message,
+ Args = args,
+ Exception = exception
+ });
+
+ ///
+ /// Log with warn log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ public void LogWarn(string message, Exception? exception = null) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Warn,
+ RawMessage = message,
+ Exception = exception
+ });
+
+ ///
+ /// Log with warn log level
+ ///
+ /// The message to display
+ /// The objects involved in the event
+ public void LogWarn(string message, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Warn,
+ RawMessage = message,
+ Args = args
+ });
+
+ ///
+ /// Log with error log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ /// The objects involved in the event
+ public void LogError(string message, Exception? exception = null, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Error,
+ RawMessage = message,
+ Args = args,
+ Exception = exception
+ });
+
+ ///
+ /// Log with error log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ public void LogError(string message, Exception? exception = null) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Error,
+ RawMessage = message,
+ Exception = exception
+ });
+
+ ///
+ /// Log with error log level
+ ///
+ /// The message to display
+ /// The objects involved in the event
+ public void LogError(string message, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Error,
+ RawMessage = message,
+ Args = args
+ });
+
+ ///
+ /// Log with fatal log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ /// The objects involved in the event
+ public void LogFatal(string message, Exception? exception = null, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Fatal,
+ RawMessage = message,
+ Args = args,
+ Exception = exception
+ });
+
+ ///
+ /// Log with fatal log level
+ ///
+ /// The message to display
+ /// The exception that was caused
+ public void LogFatal(string message, Exception? exception = null) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Fatal,
+ RawMessage = message,
+ Exception = exception
+ });
+
+ ///
+ /// Log with fatal log level
+ ///
+ /// The message to display
+ /// The objects involved in the event
+ public void LogFatal(string message, params object[] args) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = CustomLogLevel.Fatal,
+ RawMessage = message,
+ Args = args
+ });
+
+ ///
+ /// Log with standard Microsoft.Extensions.Logging format
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void Log(Microsoft.Extensions.Logging.LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) => LogsToPost.Add(new LogEntry
+ {
+ TimeOfEvent = DateTime.Now,
+ LogLevel = logLevel switch
+ {
+ Microsoft.Extensions.Logging.LogLevel.Debug => CustomLogLevel.Debug2,
+ Microsoft.Extensions.Logging.LogLevel.Trace => CustomLogLevel.Trace2,
+ Microsoft.Extensions.Logging.LogLevel.Information => CustomLogLevel.Info,
+ Microsoft.Extensions.Logging.LogLevel.Warning => CustomLogLevel.Warn,
+ Microsoft.Extensions.Logging.LogLevel.Error => CustomLogLevel.Error,
+ Microsoft.Extensions.Logging.LogLevel.Critical => CustomLogLevel.Fatal,
+ Microsoft.Extensions.Logging.LogLevel.None => CustomLogLevel.None,
+ _ => CustomLogLevel.None,
+ },
+ RawMessage = $"[{eventId.Id}] {formatter(state, exception)}",
+ Exception = exception
+ });
+
+ public bool IsEnabled(Microsoft.Extensions.Logging.LogLevel logLevel)
+ => LoggerStarted;
+
+ public IDisposable BeginScope(TState state)
+ => default!;
+}
diff --git a/LoggerObjects.cs b/LoggerObjects.cs
deleted file mode 100644
index 08a26c6..0000000
--- a/LoggerObjects.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-namespace Xorog.Logger;
-
-public class LoggerObjects
-{
- internal List LogsToPost = new();
- internal List Blacklist = new();
- internal List FileBlackList = 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
- {
- NONE,
- FATAL,
- ERROR,
- WARN,
- INFO,
- DEBUG,
- DEBUG2,
- TRACE,
- TRACE2
- }
-}
diff --git a/LoggerProvider.cs b/LoggerProvider.cs
index ac8a673..b8d02be 100644
--- a/LoggerProvider.cs
+++ b/LoggerProvider.cs
@@ -1,24 +1,16 @@
-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;
-namespace Xorog.Logger;
-public class LoggerProvider : ILoggerProvider
+public sealed class LoggerProvider : ILoggerProvider
{
- private readonly ConcurrentDictionary _loggers = new(StringComparer.OrdinalIgnoreCase);
+ internal LoggerProvider(LoggerClient logger)
+ => this._logger = logger;
- public ILogger CreateLogger(string categoryName)
- {
- return _loggers.GetOrAdd(categoryName, name => new Logger());
- }
- public void Dispose()
- {
- _loggers.Clear();
- GC.SuppressFinalize(this);
- }
+ private LoggerClient _logger { get; set; }
+
+ public ILogger CreateLogger(string categoryName)
+ => this._logger;
+
+ public void Dispose()
+ => GC.SuppressFinalize(this);
}
diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json
new file mode 100644
index 0000000..e91e38b
--- /dev/null
+++ b/Properties/launchSettings.json
@@ -0,0 +1,7 @@
+{
+ "profiles": {
+ "Xorog.Logger": {
+ "commandName": "Project"
+ }
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index bb7f291..f1e54bb 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,9 @@
# Xorog.Logger
-This legacy branch is meant to prevent having to update way too many applications because of a few breaking changes to main.
+The logger used in projects of Fortunevale.
+
+## Used in
+
+- [BeatRecorder](https://github.com/TheXorog/BeatRecorder)
+
+
diff --git a/Xorog.Logger.csproj b/Xorog.Logger.csproj
index 590a571..c16daaa 100644
--- a/Xorog.Logger.csproj
+++ b/Xorog.Logger.csproj
@@ -1,11 +1,12 @@
- net6.0
+ net8.0
enable
annotations
Debug;Release;x64
- AnyCPU;x64
+ x64
+ False
@@ -14,10 +15,12 @@
embedded
+ True
embedded
+ False
@@ -26,14 +29,17 @@
embedded
+ True
embedded
+ False
-
+
+