using System.IO; namespace ytLive.Helpers; /// /// Minimal file logger used to diagnose startup/shutdown crashes on Windows, /// where the WPF app has no visible console. Writes to /// %APPDATA%\ytLlive\startup.log (or a per-instance subfolder in DEBUG — see /// InstanceProfile), appending synchronously so entries survive a hard crash. /// public static class AppLog { /// The cap for the live log file. Past this, it rolls to startup.1.log. private const long DefaultMaxBytes = 5 * 1024 * 1024; /// How many rolled copies to keep (startup.1.log, startup.2.log, …). private const int RetainedFiles = 1; private static readonly string DefaultLogPath = Path.Combine( InstanceProfile.DataRoot, "startup.log"); private static readonly object Gate = new(); /// Test seam: point the log somewhere else. Null = the real profile's log. internal static string? PathOverride { get; set; } /// Test seam: the cap that triggers a roll. internal static long MaxBytes { get; set; } = DefaultMaxBytes; private static string LogPath => PathOverride ?? DefaultLogPath; public static void Write(string message) { try { lock (Gate) { var path = LogPath; Directory.CreateDirectory(Path.GetDirectoryName(path)!); LogRotation.RollIfNeeded(path, MaxBytes, RetainedFiles); File.AppendAllText(path, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} {message}{Environment.NewLine}"); } } catch { // Never let logging itself crash the app. } } public static void Write(Exception exception, string message) { Write($"{message}: {exception}"); } }