GeWuYou 1ba771e13a feat(logging): 实现结构化日志记录和异步日志输出功能
- 将 AbstractLogger 实现从 ILogger 扩展为 IStructuredLogger 接口
- 添加通用日志方法 Log(LogLevel, string, params object[]) 支持格式化参数
- 实现结构化日志方法支持属性键值对记录
- 添加 ConsoleAppender、FileAppender 和 AsyncLogAppender 日志输出器
- 实现 CompositeFilter 过滤器和 DefaultLogFormatter、JsonLogFormatter 格式化器
- 在 ConsoleLogger 和 GodotLogger 中使用预缓存的日志级别字符串提升性能
- 使用 ANSI 颜色代码替代 ConsoleColor 实现跨平台日志着色
- 在 ConsoleLoggerFactoryProvider 和 GodotLoggerFactoryProvider 中添加日志工厂缓存
- 优化 FileStorage 中目录遍历使用 OfType<string>() 类型转换
- 添加 LogContext 支持异步流中的结构化属性传递
2026-02-26 19:57:42 +08:00

91 lines
2.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.IO;
using GFramework.Core.Abstractions.logging;
namespace GFramework.Core.logging.appenders;
/// <summary>
/// 控制台日志输出器
/// </summary>
public sealed class ConsoleAppender : ILogAppender, IDisposable
{
private readonly ILogFilter? _filter;
private readonly ILogFormatter _formatter;
private readonly bool _useColors;
private readonly TextWriter _writer;
/// <summary>
/// 创建控制台日志输出器
/// </summary>
/// <param name="formatter">日志格式化器</param>
/// <param name="writer">文本写入器(默认为 Console.Out</param>
/// <param name="useColors">是否使用颜色(默认为 true</param>
/// <param name="filter">日志过滤器(可选)</param>
public ConsoleAppender(
ILogFormatter formatter,
TextWriter? writer = null,
bool useColors = true,
ILogFilter? filter = null)
{
_formatter = formatter ?? throw new ArgumentNullException(nameof(formatter));
_writer = writer ?? Console.Out;
_useColors = useColors && _writer == Console.Out;
_filter = filter;
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
_writer.Flush();
}
/// <summary>
/// 追加日志条目到控制台
/// </summary>
/// <param name="entry">日志条目</param>
public void Append(LogEntry entry)
{
if (_filter != null && !_filter.ShouldLog(entry))
return;
var message = _formatter.Format(entry);
if (_useColors)
{
WriteColored(entry.Level, message);
}
else
{
_writer.WriteLine(message);
}
}
/// <summary>
/// 刷新控制台输出
/// </summary>
public void Flush()
{
_writer.Flush();
}
private void WriteColored(LogLevel level, string message)
{
var colorCode = GetAnsiColorCode(level);
_writer.WriteLine($"\x1b[{colorCode}m{message}\x1b[0m");
}
private static string GetAnsiColorCode(LogLevel level)
{
return level switch
{
LogLevel.Trace => "90", // 暗灰色
LogLevel.Debug => "36", // 青色
LogLevel.Info => "37", // 白色
LogLevel.Warning => "33", // 黄色
LogLevel.Error => "31", // 红色
LogLevel.Fatal => "35", // 洋红色
_ => "37"
};
}
}