diff --git a/DiscordBotCore.Logging/ILogger.cs b/DiscordBotCore.Logging/ILogger.cs index 05de5e6..4fa4444 100644 --- a/DiscordBotCore.Logging/ILogger.cs +++ b/DiscordBotCore.Logging/ILogger.cs @@ -2,21 +2,13 @@ public interface ILogger { - public struct FormattedMessage { - public string Message; - public LogType Type; - } - - string LogMessageFormat { get; set; } + event Action? OnLogReceived; void Log(string message); void Log(string message, LogType logType); void Log(string message, LogType logType, string format); - void Log(string message, object Sender); - void Log(string message, object Sender, LogType type); - void LogException(Exception exception, object Sender, bool logFullStack = false); - - void SetOutFunction(Action outFunction); - - string GetLogsHistory(); + void Log(string message, object sender); + void Log(string message, object sender, LogType type); + void LogException(Exception exception, object sender, bool logFullStack = false); + } \ No newline at end of file diff --git a/DiscordBotCore.Logging/Logger.cs b/DiscordBotCore.Logging/Logger.cs index 13e8b7e..cf1d51b 100644 --- a/DiscordBotCore.Logging/Logger.cs +++ b/DiscordBotCore.Logging/Logger.cs @@ -2,23 +2,15 @@ public sealed class Logger : ILogger { - private FileStream _logFileStream; - - private readonly List _logMessageProperties = typeof(ILogMessage).GetProperties().Select(p => p.Name).ToList(); - private Action? _outFunction; + private readonly string _LogFile; + private readonly List _logMessageProperties = typeof(ILogMessage).GetProperties().Select(p => p.Name).ToList(); + public event Action? OnLogReceived; public string LogMessageFormat { get ; set; } - public Logger(string logFolder, string logMessageFormat, Action? outFunction = null) + public Logger(string logFolder, string logMessageFormat) { this.LogMessageFormat = logMessageFormat; - var logFile = Path.Combine(logFolder, $"{DateTime.Now:yyyy-MM-dd}.log"); - _logFileStream = File.Open(logFile, FileMode.Append, FileAccess.Write, FileShare.Read); - this._outFunction = outFunction ?? DefaultLogFunction; - } - - private void DefaultLogFunction(string message, LogType logType) - { - Console.WriteLine($"[{logType}] {message}"); + this._LogFile = Path.Combine(logFolder, $"{DateTime.Now:yyyy-MM-dd}.log"); } /// @@ -38,15 +30,10 @@ public sealed class Logger : ILogger return messageAsString; } - private async void LogToFile(string message) + private async Task LogToFile(string message) { - byte[] messageAsBytes = System.Text.Encoding.ASCII.GetBytes(message); - await _logFileStream.WriteAsync(messageAsBytes, 0, messageAsBytes.Length); - - byte[] newLine = System.Text.Encoding.ASCII.GetBytes(Environment.NewLine); - await _logFileStream.WriteAsync(newLine, 0, newLine.Length); - - await _logFileStream.FlushAsync(); + await using var streamWriter = new StreamWriter(_LogFile, true); + await streamWriter.WriteLineAsync(message); } private string GenerateLogMessage(ILogMessage message, string customFormat) @@ -61,17 +48,17 @@ public sealed class Logger : ILogger return messageAsString; } - public void Log(ILogMessage message, string format) + private void Log(ILogMessage message, string format) { string messageAsString = GenerateLogMessage(message, format); - _outFunction?.Invoke(messageAsString, message.LogMessageType); + OnLogReceived?.Invoke(message); LogToFile(messageAsString); } - public void Log(ILogMessage message) + private void Log(ILogMessage message) { string messageAsString = GenerateLogMessage(message); - _outFunction?.Invoke(messageAsString, message.LogMessageType); + OnLogReceived?.Invoke(message); LogToFile(messageAsString); } @@ -82,22 +69,4 @@ public sealed class Logger : ILogger public void Log(string message, object sender) => Log(new LogMessage(message, sender)); public void Log(string message, object sender, LogType type) => Log(new LogMessage(message, sender, type)); public void LogException(Exception exception, object sender, bool logFullStack = false) => Log(LogMessage.CreateFromException(exception, sender, logFullStack)); - - public void SetOutFunction(Action outFunction) - { - this._outFunction = outFunction; - } - public string GetLogsHistory() - { - string fileName = _logFileStream.Name; - - //_logFileStream.Flush(); - _logFileStream.Close(); - - string[] logs = File.ReadAllLines(fileName); - _logFileStream = File.Open(fileName, FileMode.Append, FileAccess.Write, FileShare.Read); - - return string.Join(Environment.NewLine, logs); - - } } diff --git a/DiscordBotCore.WebApplication/Initializer.cs b/DiscordBotCore.WebApplication/Initializer.cs index 25a5eb1..407b921 100644 --- a/DiscordBotCore.WebApplication/Initializer.cs +++ b/DiscordBotCore.WebApplication/Initializer.cs @@ -29,7 +29,10 @@ public static class Initializer Directory.CreateDirectory(logFolder); ILogger logger = new Logger(logFolder, logFormat); - logger.SetOutFunction((s, type) => { Console.WriteLine($"[{type}] {s}"); }); + logger.OnLogReceived += (logMessage) => + { + Console.WriteLine(logMessage.Message); + }; return logger; }); diff --git a/WebUI/Components/Pages/Home.razor b/WebUI/Components/Pages/Home.razor index d283581..46c873a 100644 --- a/WebUI/Components/Pages/Home.razor +++ b/WebUI/Components/Pages/Home.razor @@ -1,13 +1,16 @@ @page "/" @using DiscordBotCore.Bot +@using DiscordBotCore.Logging @using DiscordBotCore.PluginManagement.Loading @using WebUI.Models @using WebUI.Services + @inject IDiscordBotApplication DiscordBotApplication @inject IPluginLoader PluginLoader -@inject DiscordBotCore.Logging.ILogger Logger +@inject ILogger Logger @inject IJSRuntime JS @inject NotificationService NotificationService + @rendermode InteractiveServer

Console Log Viewer

@@ -16,9 +19,9 @@

Console Log

- @foreach (var line in Logs) + @foreach (var line in _Logs) { -
@line
+
@line.Message
}
@@ -44,16 +47,22 @@ @code { private bool IsRunning { get; set; } - private List Logs { get; set; } = new(); - private Timer? _logTimer; - private int _lastLogCount = 0; - private readonly object _logLock = new(); + private List _Logs { get; set; } = new(); protected override void OnInitialized() { IsRunning = DiscordBotApplication.IsReady; - - _logTimer = new Timer(async _ => await RefreshLogsAsync(), null, 0, 2000); + Logger.OnLogReceived += LoggerOnLogReceived; + } + + private void LoggerOnLogReceived(ILogMessage obj) + { + InvokeAsync(async () => + { + _Logs.Add(obj); + StateHasChanged(); + await JS.InvokeVoidAsync("scrollToBottom", "consoleLog"); + }); } private async Task StartApplication() @@ -62,7 +71,9 @@ { await DiscordBotApplication.StartAsync(); Logger.Log("Application started", this); + NotificationService.Notify("Bot Started !", NotificationType.Success); } + IsRunning = DiscordBotApplication.IsReady; } @@ -72,7 +83,9 @@ { await DiscordBotApplication.StopAsync(); Logger.Log("Application stopped", this); + NotificationService.Notify("Bot Stopped !", NotificationType.Success); } + IsRunning = DiscordBotApplication.IsReady; } @@ -85,43 +98,15 @@ } - private string GetLogStyle(string line) + private string GetLogStyle(ILogMessage logMessage) { - if (line.Contains("[Error]")) return "color: #ff4d4d;"; - if (line.Contains("[Warning]")) return "color: #ffa500;"; - if (line.Contains("[Debug]")) return "color: #88f;"; - return ""; - } - - private async Task RefreshLogsAsync() - { - try + return logMessage.LogMessageType switch { - var logText = Logger.GetLogsHistory(); - var newLogs = logText.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); - - if (newLogs.Length != _lastLogCount) - { - lock (_logLock) - { - Logs = newLogs.ToList(); - _lastLogCount = newLogs.Length; - } - await InvokeAsync(async () => - { - StateHasChanged(); - await JS.InvokeVoidAsync("scrollToBottom", "consoleLog"); - }); - } - } - catch (Exception ex) - { - - } - } - - public void Dispose() - { - _logTimer?.Dispose(); + LogType.Info => "color: white;", + LogType.Warning => "color: yellow;", + LogType.Error => "color: red;", + LogType.Critical => "color: purple;", + _ => "" + }; } } diff --git a/WebUI/Components/Pages/Plugins/AddLocal.razor b/WebUI/Components/Pages/Plugins/AddLocal.razor index 418ada1..21c2250 100644 --- a/WebUI/Components/Pages/Plugins/AddLocal.razor +++ b/WebUI/Components/Pages/Plugins/AddLocal.razor @@ -5,8 +5,11 @@ @using DiscordBotCore.Logging @using DiscordBotCore.PluginManagement @using DiscordBotCore.PluginManagement.Models +@using WebUI.Models +@using WebUI.Services @inject NavigationManager Navigation +@inject NotificationService NotificationService @inject IPluginManager PluginManager @inject IConfiguration Configuration @@ -67,6 +70,7 @@ { if (!IsValidVersion || selectedFile is null || string.IsNullOrEmpty(selectedFileName)) { + NotificationService.Notify("Invalid field values. Please check the form.", NotificationType.Error); return; } @@ -75,6 +79,7 @@ if (string.IsNullOrEmpty(pluginsFolder)) { Logger.Log("Plugins folder is not set in the configuration.", this, LogType.Error); + NotificationService.Notify("Plugins folder is not set in the configuration.", NotificationType.Error); return; } @@ -86,6 +91,8 @@ LocalPlugin plugin = new LocalPlugin(pluginModel.Name, pluginModel.Version, filePath, new(), true, pluginModel.IsEnabled); await PluginManager.AppendPluginToDatabase(plugin); + + NotificationService.Notify($"Plugin {pluginModel.Name} uploaded successfully!", NotificationType.Success); Navigation.NavigateTo("/"); } diff --git a/WebUI/Components/Pages/Plugins/Online.razor b/WebUI/Components/Pages/Plugins/Online.razor index 2351276..28a2af3 100644 --- a/WebUI/Components/Pages/Plugins/Online.razor +++ b/WebUI/Components/Pages/Plugins/Online.razor @@ -130,6 +130,7 @@ else if (pluginData is null) { Logger.Log("Plugin data is null.", this, LogType.Error); + NotificationService.Notify("Plugin data is null.", NotificationType.Error); return; }