1using System; 2using System.IO; 3using System.Diagnostics; 4using System.Runtime.CompilerServices; 5 6namespace WindowCapture.App 7{ 8 public static class PerformanceLogger 9 { 10 private static readonly string LogPath = Path.Combine( 11 Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 12 "WindowCapture", "performance.log"); 13 14 private static readonly object LockObj = new object(); 15 private static Stopwatch sessionStopwatch = Stopwatch.StartNew(); 16 17 static PerformanceLogger() 18 { 19 try 20 { 21 string dir = Path.GetDirectoryName(LogPath); 22 if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); 23 24 // Clear log on startup or keep it? Let's append with a separator 25 File.AppendAllText(LogPath, "\n--- New Session: " + DateTime.Now.ToString() + " ---\n"); 26 } 27 catch { } 28 } 29 30 public static void Log(string action, long elapsedMs = -1, string details = "") 31 { 32 try 33 { 34 string timestamp = DateTime.Now.ToString("HH:mm:ss.fff"); 35 string sessionTime = sessionStopwatch.Elapsed.TotalMilliseconds.ToString("F1"); 36 string message = string.Format("[{0}] [{1}ms] {2}", timestamp, sessionTime, action); 37 38 if (elapsedMs >= 0) 39 message += string.Format(" | Latency: {0}ms", elapsedMs); 40 41 if (!string.IsNullOrEmpty(details)) 42 message += string.Format(" | {0}", details); 43 44 lock (LockObj) 45 { 46 File.AppendAllText(LogPath, message + "\n"); 47 } 48 } 49 catch { } 50 } 51 52 public static IDisposable Measure(string action, string details = "") 53 { 54 return new MeasureScope(action, details); 55 } 56 57 private class MeasureScope : IDisposable 58 { 59 private readonly string action; 60 private readonly string details; 61 private readonly Stopwatch sw; 62 63 public MeasureScope(string action, string details) 64 { 65 this.action = action; 66 this.details = details; 67 this.sw = Stopwatch.StartNew(); 68 } 69 70 public void Dispose() 71 { 72 sw.Stop(); 73 Log(action, sw.ElapsedMilliseconds, details); 74 } 75 } 76 } 77}