using Spectre.Console; using System.Text; using System.Text.RegularExpressions; namespace N_m3u8DL_RE.Common.Log; public static partial class Logger { [GeneratedRegex("{}")] private static partial Regex VarsRepRegex(); /// /// 日志级别,默认为INFO /// public static LogLevel LogLevel { get; set; } = LogLevel.INFO; /// /// 是否写出日志文件 /// public static bool IsWriteFile { get; set; } = true; /// /// 本次运行日志文件所在位置 /// private static string? LogFilePath { get; set; } // 读写锁 static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim(); public static void InitLogFile() { if (!IsWriteFile) return; try { var logDir = Path.GetDirectoryName(Environment.ProcessPath) + "/Logs"; if (!Directory.Exists(logDir)) { Directory.CreateDirectory(logDir); } var now = DateTime.Now; LogFilePath = Path.Combine(logDir, now.ToString("yyyy-MM-dd_HH-mm-ss-fff") + ".log"); int index = 1; var fileName = Path.GetFileNameWithoutExtension(LogFilePath); string init = "LOG " + now.ToString("yyyy/MM/dd") + Environment.NewLine + "Save Path: " + Path.GetDirectoryName(LogFilePath) + Environment.NewLine + "Task Start: " + now.ToString("yyyy/MM/dd HH:mm:ss") + Environment.NewLine + "Task CommandLine: " + Environment.CommandLine; init += $"{Environment.NewLine}{Environment.NewLine}"; // 若文件存在则加序号 while (File.Exists(LogFilePath)) { LogFilePath = Path.Combine(Path.GetDirectoryName(LogFilePath)!, $"{fileName}-{index++}.log"); } File.WriteAllText(LogFilePath, init, Encoding.UTF8); } catch (Exception ex) { Error($"Init log failed! {ex.Message.RemoveMarkup()}"); } } private static string GetCurrTime() { return DateTime.Now.ToString("HH:mm:ss.fff"); } private static void HandleLog(string write, string subWrite = "") { try { if (subWrite == "") { CustomAnsiConsole.MarkupLine(write); } else { CustomAnsiConsole.Markup(write); Console.WriteLine(subWrite); } if (!IsWriteFile || !File.Exists(LogFilePath)) return; var plain = write.RemoveMarkup() + subWrite.RemoveMarkup(); try { // 进入写入 LogWriteLock.EnterWriteLock(); using (StreamWriter sw = File.AppendText(LogFilePath)) { sw.WriteLine(plain); } } finally { // 释放占用 LogWriteLock.ExitWriteLock(); } } catch (Exception) { Console.WriteLine("Failed to write: " + write); } } private static string ReplaceVars(string data, params object[] ps) { for (int i = 0; i < ps.Length; i++) { data = VarsRepRegex().Replace(data, $"{ps[i]}", 1); } return data; } public static void Info(string data, params object[] ps) { if (LogLevel < LogLevel.INFO) return; data = ReplaceVars(data, ps); var write = GetCurrTime() + " " + "[underline #548c26]INFO[/] : "; HandleLog(write, data); } public static void InfoMarkUp(string data, params object[] ps) { if (LogLevel < LogLevel.INFO) return; data = ReplaceVars(data, ps); var write = GetCurrTime() + " " + "[underline #548c26]INFO[/] : " + data; HandleLog(write); } public static void Debug(string data, params object[] ps) { if (LogLevel < LogLevel.DEBUG) return; data = ReplaceVars(data, ps); var write = GetCurrTime() + " " + "[underline grey]DEBUG[/]: "; HandleLog(write, data); } public static void DebugMarkUp(string data, params object[] ps) { if (LogLevel < LogLevel.DEBUG) return; data = ReplaceVars(data, ps); var write = GetCurrTime() + " " + "[underline grey]DEBUG[/]: " + data; HandleLog(write); } public static void Warn(string data, params object[] ps) { if (LogLevel < LogLevel.WARN) return; data = ReplaceVars(data, ps); var write = GetCurrTime() + " " + "[underline #a89022]WARN[/] : "; HandleLog(write, data); } public static void WarnMarkUp(string data, params object[] ps) { if (LogLevel < LogLevel.WARN) return; data = ReplaceVars(data, ps); var write = GetCurrTime() + " " + "[underline #a89022]WARN[/] : " + data; HandleLog(write); } public static void Error(string data, params object[] ps) { if (LogLevel < LogLevel.ERROR) return; data = ReplaceVars(data, ps); var write = GetCurrTime() + " " + "[underline red1]ERROR[/]: "; HandleLog(write, data); } public static void ErrorMarkUp(string data, params object[] ps) { if (LogLevel < LogLevel.ERROR) return; data = ReplaceVars(data, ps); var write = GetCurrTime() + " " + "[underline red1]ERROR[/]: " + data; HandleLog(write); } public static void ErrorMarkUp(Exception exception) { string data = exception.Message.EscapeMarkup(); if (LogLevel >= LogLevel.ERROR) { data = exception.ToString().EscapeMarkup(); } ErrorMarkUp(data); } /// /// This thing will only write to the log file. /// /// /// public static void Extra(string data, params object[] ps) { if (!IsWriteFile || !File.Exists(LogFilePath)) return; data = ReplaceVars(data, ps); var plain = GetCurrTime() + " " + "EXTRA: " + data.RemoveMarkup(); try { // 进入写入 LogWriteLock.EnterWriteLock(); using (StreamWriter sw = File.AppendText(LogFilePath)) { sw.WriteLine(plain, Encoding.UTF8); } } finally { // 释放占用 LogWriteLock.ExitWriteLock(); } } }