Improved logging.

This commit is contained in:
2023-09-26 21:46:54 +03:00
parent d00ebfd7ed
commit f58a57c6cd
25 changed files with 429 additions and 633 deletions

View File

@@ -48,7 +48,7 @@ public class InternalActionManager
{
if (!Actions.ContainsKey(actionName))
{
Config.Logger.Log($"Action {actionName} not found", "InternalActionManager", LogLevel.WARNING, true);
Config.Logger.Log($"Action {actionName} not found", type: LogType.ERROR, source: typeof(InternalActionManager));
return "Action not found";
}
@@ -59,7 +59,7 @@ public class InternalActionManager
}
catch (Exception e)
{
Config.Logger.Log(e.Message, "InternalActionManager", LogLevel.ERROR);
Config.Logger.Log(e.Message , type: LogType.ERROR, source: typeof(InternalActionManager));
return e.Message;
}
}

View File

@@ -2,7 +2,6 @@
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading.Tasks;
namespace PluginManager.Others;
@@ -94,7 +93,7 @@ public static class ArchiveManager
}
catch (Exception ex)
{
Config.Logger.Log(ex.Message, "Archive Manager", LogLevel.ERROR); // Write the error to a file
Config.Logger.Log(message: ex.Message, source: typeof(ArchiveManager), type: LogType.ERROR); // Write the error to a file
await Task.Delay(100);
return await ReadFromPakAsync(FileName, archFile);
}
@@ -132,8 +131,7 @@ public static class ArchiveManager
}
catch (Exception ex)
{
Config.Logger.Log($"Failed to extract {entry.Name}. Exception: {ex.Message}",
"Archive Manager", LogLevel.ERROR);
Config.Logger.Log(ex.Message, source: typeof(ArchiveManager), type: LogType.ERROR);
}
currentZIPFile++;
@@ -165,8 +163,7 @@ public static class ArchiveManager
}
catch (Exception ex)
{
Config.Logger.Log($"Failed to extract {entry.Name}. Exception: {ex.Message}",
"Archive Manager", LogLevel.ERROR);
Config.Logger.Log(ex.Message, source: typeof(ArchiveManager), type: LogType.ERROR);
}
await Task.Delay(10);

View File

@@ -14,7 +14,7 @@ public enum OperatingSystem
/// <summary>
/// The output log type
/// </summary>
public enum LogLevel
public enum LogType
{
INFO,
WARNING,

View File

@@ -1,91 +0,0 @@
using System;
using System.Collections.Generic;
using PluginManager.Interfaces.Exceptions;
namespace PluginManager.Others.Exceptions;
public class ConfigFailedToLoad : IException
{
public List<string>? Messages { get; set; }
public bool isFatal { get; private set; }
public string? File { get; }
public ConfigFailedToLoad(string message, bool isFatal, string file)
{
this.isFatal = isFatal;
Messages = new List<string>() {message};
this.File = file;
}
public ConfigFailedToLoad(string message, bool isFatal)
{
this.isFatal = isFatal;
Messages = new List<string>() {message};
this.File = null;
}
public ConfigFailedToLoad(string message)
{
this.isFatal = false;
Messages = new List<string>() {message};
this.File = null;
}
public string GenerateFullMessage()
{
string messages = "";
foreach (var message in Messages)
{
messages += message + "\n";
}
return $"\nMessage: {messages}\nIsFatal: {isFatal}\nFile: {File ?? "null"}";
}
public void HandleException()
{
if (isFatal)
{
Config.Logger.Log(GenerateFullMessage(), LogLevel.CRITICAL, true);
Environment.Exit((int)ExceptionExitCode.CONFIG_FAILED_TO_LOAD);
}
Config.Logger.Log(GenerateFullMessage(), LogLevel.WARNING);
}
public IException AppendError(string message)
{
Messages.Add(message);
return this;
}
public IException AppendError(List<string> messages)
{
Messages.AddRange(messages);
return this;
}
public IException IsFatal(bool isFatal = true)
{
this.isFatal = isFatal;
return this;
}
public static ConfigFailedToLoad CreateError(string message, bool isFatal, string? file = null)
{
if (file is not null)
return new ConfigFailedToLoad(message, isFatal, file);
return new ConfigFailedToLoad(message, isFatal);
}
public static ConfigFailedToLoad CreateError(string message)
{
return new ConfigFailedToLoad(message);
}
}

View File

@@ -1,75 +0,0 @@
using System;
using System.Collections.Generic;
using PluginManager.Interfaces.Exceptions;
namespace PluginManager.Others.Exceptions;
public class ConfigNoKeyWasPresent: IException
{
public List<string> Messages { get; set; }
public bool isFatal { get; private set; }
public ConfigNoKeyWasPresent(string message, bool isFatal)
{
this.Messages = new List<string>() { message };
this.isFatal = isFatal;
}
public ConfigNoKeyWasPresent(string message)
{
this.Messages = new List<string>() { message };
this.isFatal = false;
}
public string GenerateFullMessage()
{
string messages = "";
foreach (var message in Messages)
{
messages += message + "\n";
}
return $"\nMessage: {messages}\nIsFatal: {isFatal}";
}
public void HandleException()
{
if (isFatal)
{
Config.Logger.Log(GenerateFullMessage(), LogLevel.CRITICAL, true);
Environment.Exit((int)ExceptionExitCode.CONFIG_KEY_NOT_FOUND);
}
Config.Logger.Log(GenerateFullMessage(), LogLevel.WARNING);
}
public IException AppendError(string message)
{
Messages.Add(message);
return this;
}
public IException AppendError(List<string> messages)
{
Messages.AddRange(messages);
return this;
}
public IException IsFatal(bool isFatal = true)
{
this.isFatal = isFatal;
return this;
}
public static ConfigNoKeyWasPresent CreateError(string message)
{
return new ConfigNoKeyWasPresent(message);
}
public static ConfigNoKeyWasPresent CreateError(string message, bool isFatal)
{
return new ConfigNoKeyWasPresent(message, isFatal);
}
}

View File

@@ -1,95 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace PluginManager.Others.Logger;
public class DBLogger
{
public delegate void LogHandler(string message, LogLevel logType, bool isInternal = false);
private readonly string _errFolder;
private readonly string _logFolder;
private readonly List<LogMessage> ErrorHistory = new();
private readonly List<LogMessage> LogHistory = new();
private readonly bool _continuousSave;
private readonly bool _LogErrorsOnly;
public DBLogger(bool continuousSave = true, bool logErrorsOnly = true)
{
_logFolder = Config.AppSettings["LogFolder"];
_errFolder = Config.AppSettings["ErrorFolder"];
_continuousSave = continuousSave;
_LogErrorsOnly = logErrorsOnly;
}
public IReadOnlyList<LogMessage> Logs => LogHistory;
public IReadOnlyList<LogMessage> Errors => ErrorHistory;
public event LogHandler? LogEvent;
public void Log(string message, LogLevel type = LogLevel.INFO)
{
Log(new LogMessage(message, type));
}
public void Log(string message, LogLevel type= LogLevel.INFO, bool isInternal = false)
{
Log(new LogMessage(message, type,"unknown", isInternal));
}
public void Log(string message, string sender = "unknown", LogLevel type = LogLevel.INFO, bool isInternal = false)
{
Log(new LogMessage(message, type,sender,isInternal));
}
public void Log(string message, string sender = "unknown", LogLevel type = LogLevel.INFO)
{
Log(new LogMessage(message, type, sender));
}
public void Error(Exception? e)
{
Log(e.Message, e.Source, LogLevel.ERROR);
}
private async void Log(LogMessage message)
{
LogEvent?.Invoke(message.Message, message.Type);
if (message.Type != LogLevel.ERROR && message.Type != LogLevel.CRITICAL)
LogHistory.Add(message);
else
ErrorHistory.Add(message);
if (_continuousSave)
await SaveToFile();
}
public void Log(string message, object sender, LogLevel type = LogLevel.INFO)
{
Log(message, sender.GetType().Name, type);
}
public async Task SaveToFile()
{
await SaveToTxt();
}
private async Task SaveToTxt()
{
if (!_LogErrorsOnly)
{
var logFile = new LogFile(_logFolder + $"/{DateTime.Today.ToShortDateString().Replace('/', '_')}_log.txt");
foreach (var logMessage in LogHistory)
logFile.Write(logMessage);
}
var errFile = new LogFile(_errFolder + $"/{DateTime.Today.ToShortDateString().Replace('/', '_')}_err.txt");
foreach (var logMessage in ErrorHistory)
errFile.Write(logMessage);
}
}

View File

@@ -0,0 +1,78 @@
using System;
using System.Linq;
using PluginManager.Interfaces.Logger;
namespace PluginManager.Others.Logger;
public class Log : ILog
{
public string Message { get; set; }
public string OutputFile { get; set; }
public Type? Source { get; set; }
public LogType Type { get; set; }
public DateTime ThrowTime { get; set; }
public Log(string message, string outputFile, Type? source, LogType type, DateTime throwTime)
{
Message = message;
OutputFile = outputFile;
Source = source;
Type = type;
ThrowTime = throwTime;
}
public Log(string message, string outputFile, Type? source, LogType type)
{
Message = message;
OutputFile = outputFile;
Source = source;
Type = type;
ThrowTime = DateTime.Now;
}
public Log(string message, string outputFile, Type? source)
{
Message = message;
OutputFile = outputFile;
Source = source;
Type = LogType.INFO;
ThrowTime = DateTime.Now;
}
public Log(string message, string outputFile)
{
Message = message;
OutputFile = outputFile;
Source = typeof(Log);
Type = LogType.INFO;
ThrowTime = DateTime.Now;
}
public Log(string message)
{
Message = message;
OutputFile = "";
Source = typeof(Log);
Type = LogType.INFO;
ThrowTime = DateTime.Now;
}
public static implicit operator Log(string message) => new (message);
public static implicit operator string(Log log) => $"[{log.ThrowTime}] {log.Message}";
public string AsLongString()
{
return $"[{ThrowTime}] [{Source}] [{Type}] {Message}";
}
public string AsShortString()
{
return this;
}
public string FormatedLongString()
{
return $"[{ThrowTime}]\t[{Source}]\t\t\t[{Type}]\t{Message}";
}
}

View File

@@ -1,36 +0,0 @@
using System.IO;
namespace PluginManager.Others.Logger;
public class LogFile
{
public FileInfo File { get; set; }
public LogFile(string path)
{
File = new FileInfo(path);
}
public void Write(string message)
{
using var sw = File.AppendText();
sw.WriteLine(message);
}
public void Write(string message, LogLevel type)
{
using var sw = File.AppendText();
sw.WriteLine($"[{type}] {message}");
}
public void Write(string message, string sender, LogLevel type)
{
using var sw = File.AppendText();
sw.WriteLine($"[{type}] [{sender}] {message}");
}
public void Write(LogMessage logMessage)
{
using var sw = File.AppendText();
sw.WriteLine(logMessage.ToString());
}
}

View File

@@ -1,51 +0,0 @@
using System;
namespace PluginManager.Others.Logger;
public class LogMessage
{
public LogMessage(string message, LogLevel type)
{
Message = message;
Type = type;
Time = DateTime.Now.ToString("HH:mm:ss");
isInternal = false;
}
public LogMessage(string message, LogLevel type, string sender, bool isInternal) : this(message, type)
{
Sender = sender;
this.isInternal = isInternal;
}
public LogMessage(string message, LogLevel type, string sender) : this (message, type, sender, false)
{
}
public string Message { get; set; }
public LogLevel Type { get; set; }
public string Time { get; set; }
public string Sender { get; set; }
public bool isInternal { get; set; }
public override string ToString()
{
return $"[{Time}] {Message}";
}
public static explicit operator LogMessage(string message)
{
return new LogMessage(message, LogLevel.INFO);
}
public static explicit operator LogMessage((string message, LogLevel type) tuple)
{
return new LogMessage(tuple.message, tuple.type);
}
public static explicit operator LogMessage((string message, LogLevel type, string sender) tuple)
{
return new LogMessage(tuple.message, tuple.type, tuple.sender);
}
}

View File

@@ -0,0 +1,57 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using PluginManager.Interfaces.Logger;
namespace PluginManager.Others.Logger;
public sealed class Logger : ILogger
{
public bool IsEnabled { get; init; }
public bool OutputToFile { get; init; }
public LogType LowestLogLevel { get; set; }
private bool UseShortVersion { get; }
public Logger(bool useShortVersion, bool outputToFile, LogType lowestLogLevel = LogType.INFO)
{
UseShortVersion = useShortVersion;
OutputToFile = outputToFile;
IsEnabled = true;
LowestLogLevel = lowestLogLevel;
}
public event EventHandler<Log>? OnLog;
private async Task Log(Log logMessage)
{
if (!IsEnabled) return;
OnLog?.Invoke(this, logMessage);
if (logMessage.Type < LowestLogLevel) return;
if (OutputToFile)
await File.AppendAllTextAsync(
logMessage.OutputFile,
(UseShortVersion ? logMessage : logMessage.AsLongString()) + "\n");
}
public async Task Log(string message = "", string outputFile = "", Type? source = default, LogType type = LogType.INFO, DateTime throwTime = default)
{
if (!IsEnabled) return;
if (type < LowestLogLevel) return;
if (string.IsNullOrEmpty(message)) return;
if (string.IsNullOrEmpty(outputFile)) outputFile = Config.AppSettings["LogFolder"] + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
if(throwTime == default) throwTime = DateTime.Now;
if (source == default) source = typeof(Log);
await Log(new Log(message, outputFile, source, type, throwTime));
}
}

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using PluginManager.Others.Exceptions;
namespace PluginManager.Others;
@@ -16,10 +15,8 @@ public class SettingsDictionary<TKey, TValue> : IDictionary<TKey, TValue>
_file = file;
if (!LoadFromFile())
{
ConfigFailedToLoad.CreateError("Failed to load config")
.AppendError("The file is empty or does not exist")
.IsFatal()
.HandleException();
_dictionary = new Dictionary<TKey, TValue>();
SaveToFile();
}
}
@@ -50,10 +47,6 @@ public class SettingsDictionary<TKey, TValue> : IDictionary<TKey, TValue>
}
catch
{
ConfigFailedToLoad
.CreateError("Failed to load config")
.IsFatal()
.HandleException();
return false;
}
@@ -126,11 +119,6 @@ public class SettingsDictionary<TKey, TValue> : IDictionary<TKey, TValue>
if(this._dictionary[key] is string s && !string.IsNullOrEmpty(s) && !string.IsNullOrWhiteSpace(s))
return this._dictionary[key];
ConfigNoKeyWasPresent.CreateError($"Key {(key is string ? key : typeof(TKey).Name)} was not present in {_file ?? "config"}")
.AppendError("Deleting the file may fix this issue")
.IsFatal()
.HandleException();
return default!;
}
set => this._dictionary![key] = value;