using System.IO; namespace SpdUp.Core; /// /// Application-wide logging service with live event for UI consumption. /// public static class Logger { private static readonly object _lock = new(); private static readonly string _logDir = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "SpdUp", "Logs"); /// Fired on every log write – subscribers receive the formatted line. public static event Action? LogWritten; static Logger() { Directory.CreateDirectory(_logDir); } private static string LogFile => Path.Combine(_logDir, $"SpdUp_{DateTime.Now:yyyy-MM-dd}.log"); public static void Info(string message) => Write("INFO", message); public static void Warn(string message) => Write("WARN", message); public static void Error(string message, Exception? ex = null) { var msg = ex is null ? message : $"{message} | {ex.GetType().Name}: {ex.Message}\n{ex.StackTrace}"; Write("ERROR", msg); } private static void Write(string level, string message) { var line = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{level}] {message}"; lock (_lock) { try { File.AppendAllText(LogFile, line + Environment.NewLine); } catch { // Swallow – logging must never crash the app. } } // Notify UI subscribers try { LogWritten?.Invoke(line); } catch { } #if DEBUG System.Diagnostics.Debug.WriteLine(line); #endif } /// /// Removes log files older than the specified number of days. /// public static void PurgeOldLogs(int keepDays = 14) { try { var cutoff = DateTime.Now.AddDays(-keepDays); foreach (var file in Directory.GetFiles(_logDir, "SpdUp_*.log")) { if (File.GetCreationTime(file) < cutoff) File.Delete(file); } } catch { /* best-effort */ } } }