namespace GFramework.Core.logging;
///
/// 控制台日志记录器
///
public sealed class ConsoleLogger : ILogger
{
private readonly LogLevel _minLevel;
private readonly string _name;
private readonly TextWriter _writer;
private readonly bool _useColors;
///
/// 初始化控制台日志记录器实例
///
/// 日志记录器名称,默认为根日志记录器名称
/// 最小日志级别,默认为Info级别
/// 文本写入器,默认为控制台输出
/// 是否使用颜色输出,默认为true
public ConsoleLogger(
string? name = null,
LogLevel minLevel = LogLevel.Info,
TextWriter? writer = null,
bool useColors = true)
{
_name = name ?? ILogger.RootLoggerName;
_minLevel = minLevel;
_writer = writer ?? Console.Out;
_useColors = useColors && _writer == Console.Out;
}
#region Metadata
///
/// 获取日志记录器名称
///
/// 日志记录器名称
public string Name() => _name;
#endregion
#region Level Checks
///
/// 检查是否启用Trace级别日志
///
/// 如果启用返回true,否则返回false
public bool IsTraceEnabled() => IsEnabled(LogLevel.Trace);
///
/// 检查是否启用Debug级别日志
///
/// 如果启用返回true,否则返回false
public bool IsDebugEnabled() => IsEnabled(LogLevel.Debug);
///
/// 检查是否启用Info级别日志
///
/// 如果启用返回true,否则返回false
public bool IsInfoEnabled() => IsEnabled(LogLevel.Info);
///
/// 检查是否启用Warn级别日志
///
/// 如果启用返回true,否则返回false
public bool IsWarnEnabled() => IsEnabled(LogLevel.Warning);
///
/// 检查是否启用Error级别日志
///
/// 如果启用返回true,否则返回false
public bool IsErrorEnabled() => IsEnabled(LogLevel.Error);
///
/// 检查是否启用Fatal级别日志
///
/// 如果启用返回true,否则返回false
public bool IsFatalEnabled() => IsEnabled(LogLevel.Fatal);
///
/// 检查指定日志级别是否启用
///
/// 要检查的日志级别
/// 如果启用返回true,否则返回false
private bool IsEnabled(LogLevel level) => level >= _minLevel;
#endregion
#region Trace
///
/// 记录Trace级别日志消息
///
/// 日志消息
public void Trace(string msg) => LogIfEnabled(LogLevel.Trace, msg);
///
/// 记录Trace级别日志消息(带格式化参数)
///
/// 格式化字符串
/// 格式化参数
public void Trace(string format, object arg) => LogIfEnabled(LogLevel.Trace, format, arg);
///
/// 记录Trace级别日志消息(带两个格式化参数)
///
/// 格式化字符串
/// 第一个格式化参数
/// 第二个格式化参数
public void Trace(string format, object arg1, object arg2) => LogIfEnabled(LogLevel.Trace, format, arg1, arg2);
///
/// 记录Trace级别日志消息(带多个格式化参数)
///
/// 格式化字符串
/// 格式化参数数组
public void Trace(string format, params object[] arguments) => LogIfEnabled(LogLevel.Trace, format, arguments);
///
/// 记录Trace级别异常日志
///
/// 日志消息
/// 异常对象
public void Trace(string msg, Exception t) => LogException(LogLevel.Trace, msg, t);
#endregion
#region Debug
///
/// 记录Debug级别日志消息
///
/// 日志消息
public void Debug(string msg) => LogIfEnabled(LogLevel.Debug, msg);
///
/// 记录Debug级别日志消息(带格式化参数)
///
/// 格式化字符串
/// 格式化参数
public void Debug(string format, object arg) => LogIfEnabled(LogLevel.Debug, format, arg);
///
/// 记录Debug级别日志消息(带两个格式化参数)
///
/// 格式化字符串
/// 第一个格式化参数
/// 第二个格式化参数
public void Debug(string format, object arg1, object arg2) => LogIfEnabled(LogLevel.Debug, format, arg1, arg2);
///
/// 记录Debug级别日志消息(带多个格式化参数)
///
/// 格式化字符串
/// 格式化参数数组
public void Debug(string format, params object[] arguments) => LogIfEnabled(LogLevel.Debug, format, arguments);
///
/// 记录Debug级别异常日志
///
/// 日志消息
/// 异常对象
public void Debug(string msg, Exception t) => LogException(LogLevel.Debug, msg, t);
#endregion
#region Info
///
/// 记录Info级别日志消息
///
/// 日志消息
public void Info(string msg) => LogIfEnabled(LogLevel.Info, msg);
///
/// 记录Info级别日志消息(带格式化参数)
///
/// 格式化字符串
/// 格式化参数
public void Info(string format, object arg) => LogIfEnabled(LogLevel.Info, format, arg);
///
/// 记录Info级别日志消息(带两个格式化参数)
///
/// 格式化字符串
/// 第一个格式化参数
/// 第二个格式化参数
public void Info(string format, object arg1, object arg2) => LogIfEnabled(LogLevel.Info, format, arg1, arg2);
///
/// 记录Info级别日志消息(带多个格式化参数)
///
/// 格式化字符串
/// 格式化参数数组
public void Info(string format, params object[] arguments) => LogIfEnabled(LogLevel.Info, format, arguments);
///
/// 记录Info级别异常日志
///
/// 日志消息
/// 异常对象
public void Info(string msg, Exception t) => LogException(LogLevel.Info, msg, t);
#endregion
#region Warn
///
/// 记录Warn级别日志消息
///
/// 日志消息
public void Warn(string msg) => LogIfEnabled(LogLevel.Warning, msg);
///
/// 记录Warn级别日志消息(带格式化参数)
///
/// 格式化字符串
/// 格式化参数
public void Warn(string format, object arg) => LogIfEnabled(LogLevel.Warning, format, arg);
///
/// 记录Warn级别日志消息(带两个格式化参数)
///
/// 格式化字符串
/// 第一个格式化参数
/// 第二个格式化参数
public void Warn(string format, object arg1, object arg2) => LogIfEnabled(LogLevel.Warning, format, arg1, arg2);
///
/// 记录Warn级别日志消息(带多个格式化参数)
///
/// 格式化字符串
/// 格式化参数数组
public void Warn(string format, params object[] arguments) => LogIfEnabled(LogLevel.Warning, format, arguments);
///
/// 记录Warn级别异常日志
///
/// 日志消息
/// 异常对象
public void Warn(string msg, Exception t) => LogException(LogLevel.Warning, msg, t);
#endregion
#region Error
///
/// 记录Error级别日志消息
///
/// 日志消息
public void Error(string msg) => LogIfEnabled(LogLevel.Error, msg);
///
/// 记录Error级别日志消息(带格式化参数)
///
/// 格式化字符串
/// 格式化参数
public void Error(string format, object arg) => LogIfEnabled(LogLevel.Error, format, arg);
///
/// 记录Error级别日志消息(带两个格式化参数)
///
/// 格式化字符串
/// 第一个格式化参数
/// 第二个格式化参数
public void Error(string format, object arg1, object arg2) => LogIfEnabled(LogLevel.Error, format, arg1, arg2);
///
/// 记录Error级别日志消息(带多个格式化参数)
///
/// 格式化字符串
/// 格式化参数数组
public void Error(string format, params object[] arguments) => LogIfEnabled(LogLevel.Error, format, arguments);
///
/// 记录Error级别异常日志
///
/// 日志消息
/// 异常对象
public void Error(string msg, Exception t) => LogException(LogLevel.Error, msg, t);
#endregion
#region Fatal
///
/// 记录Fatal级别日志消息
///
/// 日志消息
public void Fatal(string msg) => LogIfEnabled(LogLevel.Fatal, msg);
///
/// 记录Fatal级别日志消息(带格式化参数)
///
/// 格式化字符串
/// 格式化参数
public void Fatal(string format, object arg) => LogIfEnabled(LogLevel.Fatal, format, arg);
///
/// 记录Fatal级别日志消息(带两个格式化参数)
///
/// 格式化字符串
/// 第一个格式化参数
/// 第二个格式化参数
public void Fatal(string format, object arg1, object arg2) => LogIfEnabled(LogLevel.Fatal, format, arg1, arg2);
///
/// 记录Fatal级别日志消息(带多个格式化参数)
///
/// 格式化字符串
/// 格式化参数数组
public void Fatal(string format, params object[] arguments) => LogIfEnabled(LogLevel.Fatal, format, arguments);
///
/// 记录Fatal级别异常日志
///
/// 日志消息
/// 异常对象
public void Fatal(string msg, Exception t) => LogException(LogLevel.Fatal, msg, t);
#endregion
#region Internal Core
///
/// 如果指定级别已启用,则记录日志消息
///
/// 日志级别
/// 日志消息
private void LogIfEnabled(LogLevel level, string message)
{
if (!IsEnabled(level)) return;
LogInternal(level, message, null);
}
///
/// 如果指定级别已启用,则记录格式化日志消息
///
/// 日志级别
/// 格式化字符串
/// 格式化参数数组
private void LogIfEnabled(LogLevel level, string format, params object[] args)
{
if (!IsEnabled(level)) return;
LogInternal(level, string.Format(format, args), null);
}
///
/// 如果指定级别已启用,则记录异常日志
///
/// 日志级别
/// 日志消息
/// 异常对象
private void LogException(LogLevel level, string message, Exception exception)
{
if (!IsEnabled(level)) return;
LogInternal(level, message, exception);
}
///
/// 内部日志记录方法
///
/// 日志级别
/// 日志消息
/// 异常对象(可选)
private void LogInternal(LogLevel level, string message, Exception? exception)
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
var levelStr = level.ToString().ToUpper().PadRight(7);
var log = $"[{timestamp}] {levelStr} [{_name}] {message}";
// 添加异常信息到日志
if (exception != null)
{
log += Environment.NewLine + exception;
}
if (_useColors)
{
WriteColored(level, log);
}
else
{
_writer.WriteLine(log);
}
}
///
/// 以指定颜色写入日志消息
///
/// 日志级别
/// 日志消息
private void WriteColored(LogLevel level, string message)
{
var original = Console.ForegroundColor;
try
{
Console.ForegroundColor = GetColor(level);
_writer.WriteLine(message);
}
finally
{
Console.ForegroundColor = original;
}
}
///
/// 根据日志级别获取对应的颜色
///
/// 日志级别
/// 控制台颜色
private static ConsoleColor GetColor(LogLevel level) => level switch
{
LogLevel.Trace => ConsoleColor.DarkGray,
LogLevel.Debug => ConsoleColor.Cyan,
LogLevel.Info => ConsoleColor.White,
LogLevel.Warning => ConsoleColor.Yellow,
LogLevel.Error => ConsoleColor.Red,
LogLevel.Fatal => ConsoleColor.Magenta,
_ => ConsoleColor.White
};
#endregion
}