mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 19:03:29 +08:00
- 将所有小写的命名空间导入更正为首字母大写格式 - 统一 GFramework 框架的命名空间引用规范 - 修复 core、ecs、godot 等模块的命名空间导入错误 - 标准化文档示例代码中的 using 语句格式 - 确保所有文档中的命名空间引用保持一致性 - 更新 global using 语句以匹配正确的命名空间格式
117 lines
3.0 KiB
C#
117 lines
3.0 KiB
C#
using System.IO;
|
|
using System.Text;
|
|
using GFramework.Core.Abstractions.Logging;
|
|
using GFramework.Core.Logging.Formatters;
|
|
|
|
namespace GFramework.Core.Logging.Appenders;
|
|
|
|
/// <summary>
|
|
/// 文件日志输出器(线程安全)
|
|
/// </summary>
|
|
public sealed class FileAppender : ILogAppender, IDisposable
|
|
{
|
|
private readonly string _filePath;
|
|
private readonly ILogFilter? _filter;
|
|
private readonly ILogFormatter _formatter;
|
|
private readonly object _lock = new();
|
|
private bool _disposed;
|
|
private StreamWriter? _writer;
|
|
|
|
/// <summary>
|
|
/// 创建文件日志输出器
|
|
/// </summary>
|
|
/// <param name="filePath">日志文件路径</param>
|
|
/// <param name="formatter">日志格式化器</param>
|
|
/// <param name="filter">日志过滤器(可选)</param>
|
|
/// <exception cref="ArgumentException">当文件路径为空或无效时抛出</exception>
|
|
/// <exception cref="IOException">当无法创建或打开日志文件时抛出</exception>
|
|
public FileAppender(
|
|
string filePath,
|
|
ILogFormatter? formatter = null,
|
|
ILogFilter? filter = null)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(filePath))
|
|
throw new ArgumentException("File path cannot be null or whitespace.", nameof(filePath));
|
|
|
|
_filePath = filePath;
|
|
_formatter = formatter ?? new DefaultLogFormatter();
|
|
_filter = filter;
|
|
|
|
try
|
|
{
|
|
EnsureDirectoryExists();
|
|
InitializeWriter();
|
|
}
|
|
catch
|
|
{
|
|
// 确保在初始化失败时清理资源
|
|
_writer?.Dispose();
|
|
_writer = null;
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 释放资源
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
if (_disposed) return;
|
|
|
|
lock (_lock)
|
|
{
|
|
_writer?.Flush();
|
|
_writer?.Dispose();
|
|
_writer = null;
|
|
_disposed = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 追加日志条目到文件
|
|
/// </summary>
|
|
/// <param name="entry">日志条目</param>
|
|
public void Append(LogEntry entry)
|
|
{
|
|
if (_disposed)
|
|
throw new ObjectDisposedException(nameof(FileAppender));
|
|
|
|
if (_filter != null && !_filter.ShouldLog(entry))
|
|
return;
|
|
|
|
var message = _formatter.Format(entry);
|
|
|
|
lock (_lock)
|
|
{
|
|
_writer?.WriteLine(message);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 刷新文件缓冲区
|
|
/// </summary>
|
|
public void Flush()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
_writer?.Flush();
|
|
}
|
|
}
|
|
|
|
private void EnsureDirectoryExists()
|
|
{
|
|
var directory = Path.GetDirectoryName(_filePath);
|
|
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
|
{
|
|
Directory.CreateDirectory(directory);
|
|
}
|
|
}
|
|
|
|
private void InitializeWriter()
|
|
{
|
|
_writer = new StreamWriter(_filePath, append: true, Encoding.UTF8)
|
|
{
|
|
AutoFlush = true
|
|
};
|
|
}
|
|
} |