162 lines
4.9 KiB
C#
162 lines
4.9 KiB
C#
using Serilog;
|
||
using Serilog.Core;
|
||
using Serilog.Events;
|
||
using Serilog.Sinks.SystemConsole.Themes;
|
||
|
||
namespace BangumiRenamer.Utils;
|
||
|
||
public sealed class Log
|
||
{
|
||
private static readonly Lazy<Log> _instance = new Lazy<Log>(() => 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() { }
|
||
|
||
/// <summary>
|
||
/// 初始化日志配置
|
||
/// </summary>
|
||
public static void Initialize(Action<LoggerConfiguration> configure = null)
|
||
{
|
||
Instance.InitializeInternal(configure);
|
||
}
|
||
|
||
private void InitializeInternal(Action<LoggerConfiguration> 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.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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 为特定类型创建Logger
|
||
/// </summary>
|
||
public static ILogger ForContext<T>()
|
||
{
|
||
Instance.EnsureInitialized();
|
||
return Instance._logger.ForContext<T>();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 为特定源创建Logger
|
||
/// </summary>
|
||
public static ILogger ForContext(string source)
|
||
{
|
||
Instance.EnsureInitialized();
|
||
return Instance._logger.ForContext("SourceContext", source);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开始一个带属性的日志上下文
|
||
/// </summary>
|
||
public static IDisposable BeginScope(string propertyName, object value)
|
||
{
|
||
Instance.EnsureInitialized();
|
||
return Serilog.Context.LogContext.PushProperty(propertyName, value);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开始多个属性的日志上下文
|
||
/// </summary>
|
||
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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关闭并刷新日志
|
||
/// </summary>
|
||
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();
|
||
}
|
||
}
|
||
}
|
||
} |