using Microsoft.Extensions.Logging; using System; using DSharpPlus; using DSharpPlus.Exceptions; namespace SupportChild; internal class LogTestFactory : ILoggerProvider { public void Dispose() { } public ILogger CreateLogger(string categoryName) { 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; } internal static void Debug(string message, Exception exception = null) { instance.Log(LogLevel.Debug, new EventId(420, "BOT"), exception, message); } internal static void Log(string message, Exception exception = null) { instance.Log(LogLevel.Information, new EventId(420, "BOT"), exception, message); } internal static void Warn(string message, Exception exception = null) { instance.Log(LogLevel.Warning, new EventId(420, "BOT"), exception, message); } internal static void Error(string message, Exception exception = null) { 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 state) where TState : notnull => default; private static ConsoleColor GetLogLevelColour(LogLevel logLevel) { return logLevel switch { 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(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { if (!IsEnabled(logLevel)) return; // Ratelimit messages are usually warnings, but they are unimportant in this case so downgrade them to debug. if (formatter(state, exception).StartsWith("Hit Discord ratelimit on route ") && logLevel == LogLevel.Warning) { logLevel = LogLevel.Debug; } // The bot will handle NotFoundExceptions on its own, downgrade to debug else if (exception is NotFoundException && eventId == LoggerEvents.RestError) { logLevel = LogLevel.Debug; } string[] logLevelParts = logLevel switch { 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); if (logLevel == LogLevel.Critical) { Console.BackgroundColor = ConsoleColor.DarkRed; } Console.Write($"{DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")}"); Console.ResetColor(); 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; } else if (logLevel is LogLevel.Critical or LogLevel.Error) { Console.ForegroundColor = ConsoleColor.Red; } Console.WriteLine(formatter(state, exception)); if (exception != null) { Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine($"{exception} : {exception.Message}\n{exception.StackTrace}"); } Console.ResetColor(); } } }