diff --git a/BangumiRenamer.csproj b/BangumiRenamer.csproj
index eb83632..6c442a9 100644
--- a/BangumiRenamer.csproj
+++ b/BangumiRenamer.csproj
@@ -18,6 +18,9 @@
+
+
+
diff --git a/Src/Log/Log.cs b/Src/Log/Log.cs
new file mode 100644
index 0000000..d8e3583
--- /dev/null
+++ b/Src/Log/Log.cs
@@ -0,0 +1,164 @@
+using Serilog.Sinks.SystemConsole.Themes;
+
+namespace BangumiRenamer;
+
+using Serilog;
+using Serilog.Core;
+using Serilog.Events;
+
+public sealed class Log
+{
+ private static readonly Lazy _instance = new Lazy(() => new Log());
+ private Logger _logger;
+ private bool _isInitialized = false;
+ private readonly object _lockObject = new object();
+
+ public static Log Instance => _instance.Value;
+ public static ILogger Logger => Instance._logger;
+
+ private Log() { }
+
+ ///
+ /// 初始化日志配置
+ ///
+ public static void Initialize(Action configure = null)
+ {
+ Instance.InitializeInternal(configure);
+ }
+
+ private void InitializeInternal(Action configure = null)
+ {
+ lock (_lockObject)
+ {
+ if (_isInitialized)
+ {
+ Warn("日志系统已经初始化过");
+ return;
+ }
+
+ var config = new LoggerConfiguration()
+ .MinimumLevel.Debug()
+ .WriteTo.Console(
+ outputTemplate: "[{Timestamp:HH:mm:ss}][{Level:u3}] {Message:lj}{NewLine}{Exception}",
+ theme: AnsiConsoleTheme.Sixteen
+ )
+ .Enrich.FromLogContext()
+ .Enrich.WithProperty("Application", "MyApp")
+ .Enrich.WithThreadId();
+
+ configure?.Invoke(config);
+
+ _logger = config.CreateLogger();
+ _isInitialized = true;
+
+ Info("日志系统初始化完成");
+ }
+ }
+
+ // 静态快捷方法 - 使用更简短的名称
+ public static void Debug(string message, params object[] properties)
+ => Instance.EnsureAndLog(LogEventLevel.Debug, message, properties);
+
+ public static void Info(string message, params object[] properties)
+ => Instance.EnsureAndLog(LogEventLevel.Information, message, properties);
+
+ public static void Warn(string message, params object[] properties)
+ => Instance.EnsureAndLog(LogEventLevel.Warning, message, properties);
+
+ public static void Error(string message, params object[] properties)
+ => Instance.EnsureAndLog(LogEventLevel.Error, message, properties);
+
+ public static void Error(Exception ex, string message, params object[] properties)
+ => Instance.EnsureAndLog(ex, message, properties);
+
+ public static void Fatal(string message, params object[] properties)
+ => Instance.EnsureAndLog(LogEventLevel.Fatal, message, properties);
+
+ // 实例方法
+ private void EnsureAndLog(LogEventLevel level, string message, object[] properties)
+ {
+ EnsureInitialized();
+ _logger.Write(level, message, properties);
+ }
+
+ private void EnsureAndLog(Exception ex, string message, object[] properties)
+ {
+ EnsureInitialized();
+ _logger.Error(ex, message, properties);
+ }
+
+ ///
+ /// 为特定类型创建Logger
+ ///
+ public static ILogger ForContext()
+ {
+ Instance.EnsureInitialized();
+ return Instance._logger.ForContext();
+ }
+
+ ///
+ /// 为特定源创建Logger
+ ///
+ public static ILogger ForContext(string source)
+ {
+ Instance.EnsureInitialized();
+ return Instance._logger.ForContext("SourceContext", source);
+ }
+
+ ///
+ /// 开始一个带属性的日志上下文
+ ///
+ public static IDisposable BeginScope(string propertyName, object value)
+ {
+ Instance.EnsureInitialized();
+ return Serilog.Context.LogContext.PushProperty(propertyName, value);
+ }
+
+ ///
+ /// 开始多个属性的日志上下文
+ ///
+ public static IDisposable BeginScope(params (string Name, object Value)[] properties)
+ {
+ Instance.EnsureInitialized();
+ var disposables = properties.Select(p =>
+ Serilog.Context.LogContext.PushProperty(p.Name, p.Value)).ToArray();
+ return new DisposableGroup(disposables);
+ }
+
+ ///
+ /// 关闭并刷新日志
+ ///
+ public static void Close()
+ {
+ Instance._logger?.Dispose();
+ Serilog.Log.CloseAndFlush();
+ Instance._isInitialized = false;
+ }
+
+ private void EnsureInitialized()
+ {
+ if (!_isInitialized)
+ {
+ InitializeInternal();
+ }
+ }
+
+ // 辅助类:用于同时释放多个IDisposable
+ private class DisposableGroup : IDisposable
+ {
+ private readonly IDisposable[] _disposables;
+
+ public DisposableGroup(IDisposable[] disposables)
+ {
+ _disposables = disposables;
+ }
+
+ public void Dispose()
+ {
+ foreach (var disposable in _disposables)
+ {
+ disposable?.Dispose();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Tools/EmbededResourceViewer.cs b/Src/Tools/EmbededResourceViewer.cs
index ad06fd3..3314497 100644
--- a/Src/Tools/EmbededResourceViewer.cs
+++ b/Src/Tools/EmbededResourceViewer.cs
@@ -9,7 +9,7 @@ public class EmbededResourceViewer
var names = ResourceLoader.GetAllResNames();
foreach (var name in names)
{
- Console.WriteLine(name);
+ Log.Info(name);
}
}
}
\ No newline at end of file
diff --git a/Src/Tools/FolderCloner.cs b/Src/Tools/FolderCloner.cs
index 5860a49..a49acce 100644
--- a/Src/Tools/FolderCloner.cs
+++ b/Src/Tools/FolderCloner.cs
@@ -64,7 +64,7 @@ public static class FolderCloner
}
catch (Exception ex)
{
- Console.WriteLine($"Clone失败 {ex.Message}");
+ Log.Error(ex, "Clone");
}
}
}
diff --git a/Src/Tools/ShowCompletionChecker.cs b/Src/Tools/ShowCompletionChecker.cs
index e42ab41..b48751a 100644
--- a/Src/Tools/ShowCompletionChecker.cs
+++ b/Src/Tools/ShowCompletionChecker.cs
@@ -53,7 +53,7 @@ public static class ShowCompletionChecker
var checkPath = dir.Path;
var shows = FindShows(checkPath);
- Console.WriteLine($"Total Shows: {shows.Count}");
+ Log.Info($"Total Shows: {shows.Count}");
var client = new TMDbClient(
apiKey: Config.Default.Get().ApiKey ,
@@ -69,7 +69,7 @@ public static class ShowCompletionChecker
var info = result.Results.FirstOrDefault();
if (info == null)
{
- Console.WriteLine($"找不到对应的TV:{t.title}");
+ Log.Error($"找不到对应的TV:{t.title}");
continue;
}
foreach (var session in t.sessions)
@@ -77,7 +77,7 @@ public static class ShowCompletionChecker
var sessionInfo = client.GetTvSeasonAsync(info.Id, session.id).Result;
if (sessionInfo == null)
{
- Console.WriteLine($"季度对不上,可能找错了:{t.title} -> {info.OriginalName}");
+ Log.Error($"季度对不上,可能找错了:{t.title} -> {info.OriginalName}");
break;
}
foreach (var episode in sessionInfo.Episodes)
@@ -90,6 +90,6 @@ public static class ShowCompletionChecker
}
}
}
- Console.Write(output);
+ Log.Info(output.ToString());
}
}
\ No newline at end of file