using System.Drawing; using Microsoft.Extensions.Logging; using Pastel; namespace Yuanshen.Common.Console; public sealed class ThemedLoggerProvider : ILoggerProvider { private readonly LogLevel _minimum; public ThemedLoggerProvider(LogLevel minimum = LogLevel.Information) { ConsoleTheme.Enable(); _minimum = minimum; } public ILogger CreateLogger(string categoryName) => new ThemedLogger(categoryName, _minimum); public void Dispose() { } private sealed class ThemedLogger : ILogger { private static readonly Color Timestamp = Color.FromArgb(0x5A, 0x4E, 0x68); private static readonly Color Category = Color.FromArgb(0x9A, 0x7F, 0xC0); private readonly string _category; private readonly LogLevel _minimum; public ThemedLogger(string category, LogLevel minimum) { int lastDot = category.LastIndexOf('.'); _category = lastDot >= 0 ? category[(lastDot + 1)..] : category; _minimum = minimum; } public IDisposable? BeginScope(TState state) where TState : notnull => null; public bool IsEnabled(LogLevel logLevel) => logLevel >= _minimum; public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) { if (!IsEnabled(logLevel)) return; string message = formatter(state, exception); if (string.IsNullOrEmpty(message) && exception is null) return; (Color color, string label) = logLevel switch { LogLevel.Trace => (Color.FromArgb(0x5A, 0x4E, 0x68), "trc"), LogLevel.Debug => (Color.FromArgb(0x8B, 0x7D, 0x9B), "dbg"), LogLevel.Information => (ConsoleTheme.Accent, "inf"), LogLevel.Warning => (Color.FromArgb(0xFF, 0xB3, 0x4D), "wrn"), LogLevel.Error => (Color.FromArgb(0xFF, 0x5C, 0x7A), "err"), LogLevel.Critical => (Color.FromArgb(0xFF, 0x2D, 0x95), "crt"), _ => (ConsoleTheme.Text, "log") }; string line = $"{DateTime.Now:HH:mm:ss}".Pastel(Timestamp) + " " + label.Pastel(color) + " " + _category.Pastel(Category) + " " + message.Pastel(ConsoleTheme.Text); ConsolePrompt.Write(line); if (exception is not null) ConsolePrompt.Write(exception.ToString().Pastel(Color.FromArgb(0xFF, 0x5C, 0x7A))); } } }