diff --git a/.gitignore b/.gitignore
index 1ee5385..4b0547a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,7 +29,7 @@ x86/
bld/
[Bb]in/
[Oo]bj/
-[Ll]og/
+#[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
diff --git a/src/N_m3u8DL-RE.Common/Log/LogLevel.cs b/src/N_m3u8DL-RE.Common/Log/LogLevel.cs
new file mode 100644
index 0000000..e971658
--- /dev/null
+++ b/src/N_m3u8DL-RE.Common/Log/LogLevel.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace N_m3u8DL_RE.Common.Log
+{
+ public enum LogLevel
+ {
+ OFF,
+ ERROR,
+ WARN,
+ INFO,
+ DEBUG,
+ }
+}
diff --git a/src/N_m3u8DL-RE.Common/Log/Logger.cs b/src/N_m3u8DL-RE.Common/Log/Logger.cs
new file mode 100644
index 0000000..03aa7a0
--- /dev/null
+++ b/src/N_m3u8DL-RE.Common/Log/Logger.cs
@@ -0,0 +1,134 @@
+using Spectre.Console;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace N_m3u8DL_RE.Common.Log
+{
+ public class Logger
+ {
+ ///
+ /// 日志级别,默认为INFO
+ ///
+ public static LogLevel LogLevel { get; set; } = LogLevel.INFO;
+
+ ///
+ /// 是否写出日志文件
+ ///
+ public static bool IsWriteFile { get; set; } = true;
+
+ private static string GetCurrTime()
+ {
+ return DateTime.Now.ToString("HH:mm:ss.fff");
+ }
+
+ private static void HandleLog(string write, string subWrite = "")
+ {
+ if (subWrite == "")
+ {
+ AnsiConsole.MarkupLine(write);
+ }
+ else
+ {
+ AnsiConsole.Markup(write);
+ Console.WriteLine(subWrite);
+ }
+ if (IsWriteFile)
+ {
+ var plain = write.RemoveMarkup();
+ }
+ }
+
+ private static string ReplaceVars(string data, params object[] ps)
+ {
+ for (int i = 0; i < ps.Length; i++)
+ {
+ data = new Regex("{}").Replace(data, $"{ps[i]}", 1);
+ }
+ return data;
+ }
+
+ public static void Info(string data, params object[] ps)
+ {
+ if (LogLevel >= LogLevel.INFO)
+ {
+ 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)
+ {
+ 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)
+ {
+ 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)
+ {
+ 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)
+ {
+ 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)
+ {
+ 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)
+ {
+ 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)
+ {
+ data = ReplaceVars(data, ps);
+ var write = GetCurrTime() + " " + "[underline red1]ERROR[/] : " + data;
+ HandleLog(write);
+ }
+ }
+ }
+}