2025-11-08 20:04:11 +08:00

169 lines
5.0 KiB
C#

using System.Runtime.CompilerServices;
using Newtonsoft.Json;
using Serilog;
using Serilog.Context;
using Serilog.Core;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;
namespace BangumiRenamer.Utils;
public interface ILog
{
public void Debug(string message, [CallerFilePath] string callerFilePath = "",
[CallerMemberName] string callerMemberName = "");
public void Info(string message, [CallerFilePath] string callerFilePath = "",
[CallerMemberName] string callerMemberName = "");
public void Warn(string message, [CallerFilePath] string callerFilePath = "",
[CallerMemberName] string callerMemberName = "");
public void Error(string message, [CallerFilePath] string callerFilePath = "",
[CallerMemberName] string callerMemberName = "");
public void Error(Exception ex, string message);
}
public sealed class Log : ILog
{
public enum LogLevel
{
Error,
Warn,
Info,
Debug,
}
[ConfigItem("Log")]
public class LogConfig : IConfigItem
{
[JsonIgnore] public LogLevel Level = LogLevel.Debug;
[JsonProperty("Level")] private string _level;
public bool ToConsole = true;
public bool ToFile = false;
public string LogFilePath;
public void AfterLoad()
{
if (!string.IsNullOrEmpty(_level)) LogLevel.TryParse(_level, out Level);
}
public void BeforeSave()
{
_level = Level.ToString();
}
}
public static ILog G => _G;
public static Log _G { private get; set; }
private LogConfig _config;
private Logger _logger;
public Log(LogConfig config)
{
_config = config;
}
public bool Init()
{
if (_config == null) return false;
var config = new LoggerConfiguration();
switch (_config.Level)
{
case LogLevel.Error:
config.MinimumLevel.Error();
break;
case LogLevel.Warn:
config.MinimumLevel.Warning();
break;
case LogLevel.Debug:
config.MinimumLevel.Debug();
break;
case LogLevel.Info:
default:
config.MinimumLevel.Information();
break;
}
var outputTemplate = "[{Timestamp:HH:mm:ss}][{CallerPlace}][{Level:u3}] {Message:lj}{NewLine}{Exception}";
if (_config.ToConsole)
{
config.WriteTo.Console(
outputTemplate: outputTemplate,
theme: AnsiConsoleTheme.Sixteen
);
}
if (_config.ToFile)
{
if (string.IsNullOrEmpty(_config.LogFilePath))
{
return false;
}
config.WriteTo.File(
outputTemplate: outputTemplate,
path: _config.LogFilePath
);
}
config.Enrich.FromLogContext()
.Enrich.WithThreadId();
try
{
_logger = config.CreateLogger();
}
catch (Exception)
{
return false;
}
return true;
}
// 静态快捷方法 - 使用更简短的名称
public void Debug(string message, [CallerFilePath] string callerFilePath = "", [CallerMemberName] string callerMemberName = "")
{
using (LogContext.PushProperty("CallerPlace", Path.GetFileNameWithoutExtension(callerFilePath) + "::" + callerMemberName))
{
_logger.Write(LogEventLevel.Debug, message);
}
}
public void Info(string message, [CallerFilePath] string callerFilePath = "", [CallerMemberName] string callerMemberName = "")
{
using (LogContext.PushProperty("CallerPlace", Path.GetFileNameWithoutExtension(callerFilePath) + "::" + callerMemberName))
{
_logger.Write(LogEventLevel.Information, message);
}
}
public void Warn(string message, [CallerFilePath] string callerFilePath = "", [CallerMemberName] string callerMemberName = "")
{
using (LogContext.PushProperty("CallerPlace", Path.GetFileNameWithoutExtension(callerFilePath) + "::" + callerMemberName))
{
_logger.Write(LogEventLevel.Warning, message);
}
}
public void Error(string message, [CallerFilePath] string callerFilePath = "", [CallerMemberName] string callerMemberName = "")
{
using (LogContext.PushProperty("CallerPlace", Path.GetFileNameWithoutExtension(callerFilePath) + "::" + callerMemberName))
{
_logger.Write(LogEventLevel.Error, message);
}
}
public void Error(Exception ex, string message)
=> WriteLog(ex, message);
private void WriteLog(Exception ex, string message)
{
_logger.Error(ex, message);
}
}