using Ionic.Zip; using System; using System.Collections.Generic; using System.IO; namespace Cryville.Common { public abstract class Logger { static readonly Dictionary Instances = new Dictionary(); static readonly Dictionary Files = new Dictionary(); static string logPath = null; public static void SetLogPath(string path) { logPath = path; var dir = new DirectoryInfo(path); if (!dir.Exists) Directory.CreateDirectory(dir.FullName); } public static void Log(string key, int level, string module, string format, params object[] args) { if (!Instances.ContainsKey(key)) return; Instances[key].Log(level, module, string.Format(format, args)); if (Files.ContainsKey(key)) Files[key].WriteLine("[{0:O}] [{1}] <{2}> {3}", DateTime.UtcNow, level, module, string.Format(format, args)); } public static void Create(string key, Logger logger) { Instances[key] = logger; if (logPath != null) { Files[key] = new StreamWriter(logPath + "/" + ((int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds).ToString() + "-" + key + ".log"); Files[key].AutoFlush = true; } } public static void Close() { Instances.Clear(); foreach (var f in Files) f.Value.Dispose(); Files.Clear(); } public virtual void Log(int level, string module, string msg) { } } public class InstantLogger : Logger { readonly Action callback; public InstantLogger(Action callback) { if (callback == null) throw new ArgumentNullException("callback"); this.callback = callback; } public override void Log(int level, string module, string msg) { base.Log(level, module, msg); callback(level, module, msg); } } public class BufferedLogger : Logger { readonly List buffer = new List(); public BufferedLogger() { } public override void Log(int level, string module, string msg) { base.Log(level, module, msg); lock (buffer) { buffer.Add(new LogEntry(level, module, msg)); } } public void Enumerate(Action callback) { lock (buffer) { foreach (var i in buffer) { callback(i.level, i.module, i.msg); } } buffer.Clear(); } } public struct LogEntry { public int level; public string module; public string msg; public LogEntry(int level, string module, string msg) { this.level = level; this.module = module; this.msg = msg; } } }