using GFramework.Core.Abstractions.logging; namespace GFramework.Core.logging; /// /// 日志抽象基类,封装日志级别判断、格式化与异常处理逻辑。 /// 平台日志器只需实现 Write 方法即可。 /// public abstract class AbstractLogger( string? name = null, LogLevel minLevel = LogLevel.Info) : IStructuredLogger { /// /// 根日志记录器的名称常量 /// public const string RootLoggerName = "ROOT"; private readonly string _name = name ?? RootLoggerName; #region Metadata /// /// 获取日志器的名称 /// /// 日志器名称 public string Name() { return _name; } #endregion /// /// 平台输出入口,由具体实现负责真正的日志写入。 /// /// 日志级别 /// 日志消息 /// 异常对象(可为null) protected abstract void Write(LogLevel level, string message, Exception? exception); #region Level Checks /// /// 判断指定日志级别是否启用 /// /// 要检查的日志级别 /// 如果指定级别大于等于最小级别则返回true,否则返回false protected bool IsEnabled(LogLevel level) { return level >= minLevel; } /// /// 检查Trace级别日志是否启用 /// /// 如果Trace级别启用返回true,否则返回false public bool IsTraceEnabled() { return IsEnabled(LogLevel.Trace); } /// /// 检查Debug级别日志是否启用 /// /// 如果Debug级别启用返回true,否则返回false public bool IsDebugEnabled() { return IsEnabled(LogLevel.Debug); } /// /// 检查Info级别日志是否启用 /// /// 如果Info级别启用返回true,否则返回false public bool IsInfoEnabled() { return IsEnabled(LogLevel.Info); } /// /// 检查Warning级别日志是否启用 /// /// 如果Warning级别启用返回true,否则返回false public bool IsWarnEnabled() { return IsEnabled(LogLevel.Warning); } /// /// 检查Error级别日志是否启用 /// /// 如果Error级别启用返回true,否则返回false public bool IsErrorEnabled() { return IsEnabled(LogLevel.Error); } /// /// 检查Fatal级别日志是否启用 /// /// 如果Fatal级别启用返回true,否则返回false public bool IsFatalEnabled() { return IsEnabled(LogLevel.Fatal); } /// /// 检查指定日志级别是否启用 /// /// 要检查的日志级别 /// 如果指定级别启用返回true,否则返回false /// 当传入的日志级别不被识别时抛出 public bool IsEnabledForLevel(LogLevel level) { // 根据不同的日志级别调用对应的检查方法 return level switch { LogLevel.Trace => IsTraceEnabled(), LogLevel.Debug => IsDebugEnabled(), LogLevel.Info => IsInfoEnabled(), LogLevel.Warning => IsWarnEnabled(), LogLevel.Error => IsErrorEnabled(), LogLevel.Fatal => IsFatalEnabled(), _ => throw new ArgumentException($"Level [{level}] not recognized.", nameof(level)) }; } #endregion #region Trace /// /// 记录Trace级别日志 /// /// 日志消息 public void Trace(string msg) { Log(LogLevel.Trace, msg); } /// /// 记录Trace级别日志(带格式化参数) /// /// 格式化字符串 /// 格式化参数 public void Trace(string format, object arg) { Log(LogLevel.Trace, format, arg); } /// /// 记录Trace级别日志(带两个格式化参数) /// /// 格式化字符串 /// 第一个格式化参数 /// 第二个格式化参数 public void Trace(string format, object arg1, object arg2) { Log(LogLevel.Trace, format, arg1, arg2); } /// /// 记录Trace级别日志(带多个格式化参数) /// /// 格式化字符串 /// 格式化参数数组 public void Trace(string format, params object[] arguments) { Log(LogLevel.Trace, format, arguments); } /// /// 记录Trace级别日志(带异常信息) /// /// 日志消息 /// 异常对象 public void Trace(string msg, Exception t) { Log(LogLevel.Trace, msg, t); } #endregion #region Debug /// /// 记录Debug级别日志 /// /// 日志消息 public void Debug(string msg) { Log(LogLevel.Debug, msg); } /// /// 记录Debug级别日志(带格式化参数) /// /// 格式化字符串 /// 格式化参数 public void Debug(string format, object arg) { Log(LogLevel.Debug, format, arg); } /// /// 记录Debug级别日志(带两个格式化参数) /// /// 格式化字符串 /// 第一个格式化参数 /// 第二个格式化参数 public void Debug(string format, object arg1, object arg2) { Log(LogLevel.Debug, format, arg1, arg2); } /// /// 记录Debug级别日志(带多个格式化参数) /// /// 格式化字符串 /// 格式化参数数组 public void Debug(string format, params object[] arguments) { Log(LogLevel.Debug, format, arguments); } /// /// 记录Debug级别日志(带异常信息) /// /// 日志消息 /// 异常对象 public void Debug(string msg, Exception t) { Log(LogLevel.Debug, msg, t); } #endregion #region Info /// /// 记录Info级别日志 /// /// 日志消息 public void Info(string msg) { Log(LogLevel.Info, msg); } /// /// 记录Info级别日志(带格式化参数) /// /// 格式化字符串 /// 格式化参数 public void Info(string format, object arg) { Log(LogLevel.Info, format, arg); } /// /// 记录Info级别日志(带两个格式化参数) /// /// 格式化字符串 /// 第一个格式化参数 /// 第二个格式化参数 public void Info(string format, object arg1, object arg2) { Log(LogLevel.Info, format, arg1, arg2); } /// /// 记录Info级别日志(带多个格式化参数) /// /// 格式化字符串 /// 格式化参数数组 public void Info(string format, params object[] arguments) { Log(LogLevel.Info, format, arguments); } /// /// 记录Info级别日志(带异常信息) /// /// 日志消息 /// 异常对象 public void Info(string msg, Exception t) { Log(LogLevel.Info, msg, t); } #endregion #region Warn /// /// 记录Warning级别日志 /// /// 日志消息 public void Warn(string msg) { Log(LogLevel.Warning, msg); } /// /// 记录Warning级别日志(带格式化参数) /// /// 格式化字符串 /// 格式化参数 public void Warn(string format, object arg) { Log(LogLevel.Warning, format, arg); } /// /// 记录Warning级别日志(带两个格式化参数) /// /// 格式化字符串 /// 第一个格式化参数 /// 第二个格式化参数 public void Warn(string format, object arg1, object arg2) { Log(LogLevel.Warning, format, arg1, arg2); } /// /// 记录Warning级别日志(带多个格式化参数) /// /// 格式化字符串 /// 格式化参数数组 public void Warn(string format, params object[] arguments) { Log(LogLevel.Warning, format, arguments); } /// /// 记录Warning级别日志(带异常信息) /// /// 日志消息 /// 异常对象 public void Warn(string msg, Exception t) { Log(LogLevel.Warning, msg, t); } #endregion #region Error /// /// 记录Error级别日志 /// /// 日志消息 public void Error(string msg) { Log(LogLevel.Error, msg); } /// /// 记录Error级别日志(带格式化参数) /// /// 格式化字符串 /// 格式化参数 public void Error(string format, object arg) { Log(LogLevel.Error, format, arg); } /// /// 记录Error级别日志(带两个格式化参数) /// /// 格式化字符串 /// 第一个格式化参数 /// 第二个格式化参数 public void Error(string format, object arg1, object arg2) { Log(LogLevel.Error, format, arg1, arg2); } /// /// 记录Error级别日志(带多个格式化参数) /// /// 格式化字符串 /// 格式化参数数组 public void Error(string format, params object[] arguments) { Log(LogLevel.Error, format, arguments); } /// /// 记录Error级别日志(带异常信息) /// /// 日志消息 /// 异常对象 public void Error(string msg, Exception t) { Log(LogLevel.Error, msg, t); } #endregion #region Fatal /// /// 记录Fatal级别日志 /// /// 日志消息 public void Fatal(string msg) { Log(LogLevel.Fatal, msg); } /// /// 记录Fatal级别日志(带格式化参数) /// /// 格式化字符串 /// 格式化参数 public void Fatal(string format, object arg) { Log(LogLevel.Fatal, format, arg); } /// /// 记录Fatal级别日志(带两个格式化参数) /// /// 格式化字符串 /// 第一个格式化参数 /// 第二个格式化参数 public void Fatal(string format, object arg1, object arg2) { Log(LogLevel.Fatal, format, arg1, arg2); } /// /// 记录Fatal级别日志(带多个格式化参数) /// /// 格式化字符串 /// 格式化参数数组 public void Fatal(string format, params object[] arguments) { Log(LogLevel.Fatal, format, arguments); } /// /// 记录Fatal级别日志(带异常信息) /// /// 日志消息 /// 异常对象 public void Fatal(string msg, Exception t) { Log(LogLevel.Fatal, msg, t); } #endregion #region Generic Log Methods /// /// 使用指定的日志级别记录消息 /// /// 日志级别 /// 要记录的消息字符串 public void Log(LogLevel level, string message) { if (!IsEnabled(level)) return; Write(level, message, null); } /// /// 使用指定的日志级别根据格式和参数记录消息 /// /// 日志级别 /// 格式字符串 /// 参数 public void Log(LogLevel level, string format, object arg) { if (!IsEnabled(level)) return; Write(level, string.Format(format, arg), null); } /// /// 使用指定的日志级别根据格式和参数记录消息 /// /// 日志级别 /// 格式字符串 /// 第一个参数 /// 第二个参数 public void Log(LogLevel level, string format, object arg1, object arg2) { if (!IsEnabled(level)) return; Write(level, string.Format(format, arg1, arg2), null); } /// /// 使用指定的日志级别根据格式和参数数组记录消息 /// /// 日志级别 /// 格式字符串 /// 参数数组 public void Log(LogLevel level, string format, params object[] arguments) { if (!IsEnabled(level)) return; Write(level, string.Format(format, arguments), null); } /// /// 使用指定的日志级别记录消息和异常 /// /// 日志级别 /// 伴随异常的消息 /// 要记录的异常 public void Log(LogLevel level, string message, Exception exception) { if (!IsEnabled(level)) return; Write(level, message, exception); } #endregion #region Structured Log Methods /// /// 使用指定的日志级别记录消息和结构化属性 /// /// 日志级别 /// 日志消息 /// 结构化属性键值对 public virtual void Log(LogLevel level, string message, params (string Key, object? Value)[] properties) { if (!IsEnabled(level)) return; // 默认实现:将属性附加到消息后面 if (properties.Length > 0) { var propsStr = string.Join(", ", properties.Select(p => $"{p.Key}={p.Value}")); Write(level, $"{message} | {propsStr}", null); } else { Write(level, message, null); } } /// /// 使用指定的日志级别记录消息、异常和结构化属性 /// /// 日志级别 /// 日志消息 /// 异常对象 /// 结构化属性键值对 public virtual void Log(LogLevel level, string message, Exception? exception, params (string Key, object? Value)[] properties) { if (!IsEnabled(level)) return; // 默认实现:将属性附加到消息后面 if (properties.Length > 0) { var propsStr = string.Join(", ", properties.Select(p => $"{p.Key}={p.Value}")); Write(level, $"{message} | {propsStr}", exception); } else { Write(level, message, exception); } } #endregion #region Core Pipeline (Private) #endregion }