Added custom logger

This commit is contained in:
Toastie 2024-12-26 18:41:36 +13:00
parent 5c75e1fa7d
commit d70c2ae0d2
Signed by: toastie_t0ast
GPG key ID: 27F3B6855AFD40A4
3 changed files with 119 additions and 54 deletions

View file

@ -12,7 +12,6 @@ internal static class Config
internal static string token = "";
internal static ulong logChannel;
internal static string welcomeMessage = "";
internal static LogLevel logLevel = LogLevel.Information;
internal static TimestampFormat timestampFormat = TimestampFormat.RelativeTime;
internal static bool randomAssignment = false;
internal static bool randomAssignRoleOverride = false;
@ -32,8 +31,6 @@ internal static class Config
internal static string username = "supportchild";
internal static string password = "";
internal static JToken interviews;
private static string configPath = "./config.yml";
public static void LoadConfig()
@ -68,11 +65,12 @@ internal static class Config
welcomeMessage = json.SelectToken("bot.welcome-message")?.Value<string>() ?? "";
string stringLogLevel = json.SelectToken("bot.console-log-level")?.Value<string>() ?? "";
if (!Enum.TryParse(stringLogLevel, true, out logLevel))
if (!Enum.TryParse(stringLogLevel, true, out LogLevel logLevel))
{
logLevel = LogLevel.Information;
Logger.Warn("Log level '" + stringLogLevel + "' invalid, using 'Information' instead.");
}
Logger.SetLogLevel(logLevel);
string stringTimestampFormat = json.SelectToken("bot.timestamp-format")?.Value<string>() ?? "RelativeTime";
@ -100,8 +98,5 @@ internal static class Config
database = json.SelectToken("database.name")?.Value<string>() ?? "supportchild";
username = json.SelectToken("database.user")?.Value<string>() ?? "supportchild";
password = json.SelectToken("database.password")?.Value<string>() ?? "";
// Set up interviewer
interviews = json.SelectToken("interviews");
}
}

157
Logger.cs
View file

@ -1,68 +1,137 @@
using Microsoft.Extensions.Logging;
using System;
using System.Reflection;
namespace SupportChild;
public static class Logger
internal class LogTestFactory : ILoggerProvider
{
public static void Debug(string message)
public void Dispose() { }
public ILogger CreateLogger(string categoryName)
{
try
{
SupportChild.client.Logger.Log(LogLevel.Debug, new EventId(420, Assembly.GetEntryAssembly()?.GetName().Name), message);
}
catch (NullReferenceException)
{
Console.WriteLine("[DEBUG] " + message);
}
return Logger.instance;
}
}
public class Logger : ILogger
{
public static Logger instance { get; } = new Logger();
private static LogLevel minimumLogLevel = LogLevel.Trace;
private readonly object @lock = new();
internal static void SetLogLevel(LogLevel level)
{
minimumLogLevel = level;
}
public static void Log(string message)
internal static void Debug(string message, Exception exception = null)
{
try
{
SupportChild.client.Logger.Log(LogLevel.Information, new EventId(420, Assembly.GetEntryAssembly()?.GetName().Name), message);
}
catch (NullReferenceException)
{
Console.WriteLine("[INFO] " + message);
}
instance.Log(LogLevel.Debug, new EventId(420, "BOT"), exception, message);
}
public static void Warn(string message)
internal static void Log(string message, Exception exception = null)
{
try
{
SupportChild.client.Logger.Log(LogLevel.Warning, new EventId(420, Assembly.GetEntryAssembly()?.GetName().Name), message);
}
catch (NullReferenceException)
{
Console.WriteLine("[WARNING] " + message);
}
instance.Log(LogLevel.Information, new EventId(420, "BOT"), exception, message);
}
public static void Error(string message)
internal static void Warn(string message, Exception exception = null)
{
try
{
SupportChild.client.Logger.Log(LogLevel.Error, new EventId(420, Assembly.GetEntryAssembly()?.GetName().Name), message);
}
catch (NullReferenceException)
{
Console.WriteLine("[ERROR] " + message);
}
instance.Log(LogLevel.Warning, new EventId(420, "BOT"), exception, message);
}
public static void Fatal(string message)
internal static void Error(string message, Exception exception = null)
{
try
instance.Log(LogLevel.Error, new EventId(420, "BOT"), exception, message);
}
internal static void Fatal(string message, Exception exception = null)
{
instance.Log(LogLevel.Critical, new EventId(420, "BOT"), exception, message);
}
public bool IsEnabled(LogLevel logLevel)
{
return logLevel >= minimumLogLevel && logLevel != LogLevel.None;
}
public IDisposable BeginScope<TState>(TState state) where TState : notnull => default;
private static ConsoleColor GetLogLevelColour(LogLevel logLevel)
{
return logLevel switch
{
SupportChild.client.Logger.Log(LogLevel.Critical, new EventId(420, Assembly.GetEntryAssembly()?.GetName().Name), message);
}
catch (NullReferenceException)
LogLevel.Trace => ConsoleColor.White,
LogLevel.Debug => ConsoleColor.DarkGray,
LogLevel.Information => ConsoleColor.DarkBlue,
LogLevel.Warning => ConsoleColor.Yellow,
LogLevel.Error => ConsoleColor.Red,
_ => ConsoleColor.White
};
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
return;
string[] logLevelParts = logLevel switch
{
Console.WriteLine("[CRITICAL] " + message);
LogLevel.Trace => ["[", "Trace", "] "],
LogLevel.Debug => ["[", "Debug", "] "],
LogLevel.Information => ["[", "Info", "] "],
LogLevel.Warning => ["[", "Warn", "] "],
LogLevel.Error => ["[", "Error", "] "],
LogLevel.Critical => ["[", "\u001b[1mCrit\u001b[0m", "] "],
_ => ["[", "None", "] "],
};
lock (@lock)
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write("[");
Console.ResetColor();
Console.ForegroundColor = GetLogLevelColour(logLevel);
Console.Write($"{DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")}");
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write("] ");
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write("[");
Console.ForegroundColor = eventId == 420 ? ConsoleColor.Green : ConsoleColor.DarkGreen;
Console.Write(eventId == 420 ? "BOT" : "API");
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write("] ");
Console.Write(logLevelParts[0]);
Console.ForegroundColor = GetLogLevelColour(logLevel);
if (logLevel == LogLevel.Critical)
{
Console.BackgroundColor = ConsoleColor.DarkRed;
}
Console.Write(logLevelParts[1]);
Console.ResetColor();
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write(logLevelParts[2]);
Console.ResetColor();
if (logLevel is LogLevel.Trace or LogLevel.Debug)
{
Console.ForegroundColor = ConsoleColor.Gray;
}
Console.WriteLine(formatter(state, exception));
if (exception != null)
{
Console.WriteLine($"{exception} : {exception.Message}\n{exception.StackTrace}");
}
Console.ResetColor();
}
}
}

View file

@ -148,7 +148,6 @@ internal static class SupportChild
Logger.Log("Setting up Discord client...");
DiscordClientBuilder clientBuilder = DiscordClientBuilder.CreateDefault(Config.token, DiscordIntents.All)
.SetReconnectOnFatalGatewayErrors()
.SetLogLevel(Config.logLevel)
.ConfigureServices(configure =>
{
configure.AddSingleton<IClientErrorHandler>(new ErrorHandler());
@ -212,6 +211,10 @@ internal static class SupportChild
{
clientConfig.LogUnknownEvents = false;
clientConfig.LogUnknownAuditlogs = false;
})
.ConfigureLogging(config =>
{
config.AddProvider(new LogTestFactory());
});
client = clientBuilder.Build();
@ -221,8 +224,6 @@ internal static class SupportChild
}
}
internal class ErrorHandler : IClientErrorHandler
{
public ValueTask HandleEventHandlerError(string name, Exception exception, Delegate invokedDelegate, object sender, object args)