159 lines
5.3 KiB
C#
159 lines
5.3 KiB
C#
using System.Text;
|
||
|
||
namespace Gatedge.ScanCode.Common
|
||
{
|
||
/// <summary>
|
||
/// 文件日志帮助类
|
||
/// </summary>
|
||
public class FileLogger : ILogger
|
||
{
|
||
private readonly string _categoryName;
|
||
private readonly string _filePath;
|
||
private readonly long _maxFileSize; // 最大文件大小(字节)
|
||
private readonly int _maxRetainedFiles; // 最大保留文件数
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
/// <param name="categoryName"></param>
|
||
/// <param name="filePath"></param>
|
||
/// <param name="maxFileSize"></param>
|
||
/// <param name="maxRetainedFiles"></param>
|
||
public FileLogger(string categoryName, string filePath, long maxFileSize = 10 * 1024 * 1024, int maxRetainedFiles = 5)
|
||
{
|
||
_categoryName = categoryName;
|
||
_filePath = filePath;
|
||
_maxFileSize = maxFileSize;
|
||
_maxRetainedFiles = maxRetainedFiles;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开始
|
||
/// </summary>
|
||
/// <typeparam name="TState"></typeparam>
|
||
/// <param name="state"></param>
|
||
/// <returns></returns>
|
||
public IDisposable BeginScope<TState>(TState state) => null;
|
||
|
||
/// <summary>
|
||
/// 检测日志等级是否启用
|
||
/// </summary>
|
||
/// <param name="logLevel"></param>
|
||
/// <returns></returns>
|
||
public bool IsEnabled(LogLevel logLevel) => true;
|
||
|
||
/// <summary>
|
||
/// 写入日志
|
||
/// </summary>
|
||
/// <typeparam name="TState"></typeparam>
|
||
/// <param name="logLevel"></param>
|
||
/// <param name="eventId"></param>
|
||
/// <param name="state"></param>
|
||
/// <param name="exception"></param>
|
||
/// <param name="formatter"></param>
|
||
public void Log<TState>(
|
||
LogLevel logLevel,
|
||
EventId eventId,
|
||
TState state,
|
||
Exception exception,
|
||
Func<TState, Exception, string> formatter)
|
||
{
|
||
// 过滤日志级别(可选)
|
||
if (!IsEnabled(logLevel)) return;
|
||
|
||
// 格式化日志消息
|
||
var message = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [{logLevel}] {_categoryName}: {formatter(state, exception)}{Environment.NewLine}";
|
||
|
||
// 确保目录存在
|
||
var directory = Path.GetDirectoryName(_filePath);
|
||
if (!Directory.Exists(directory))
|
||
{
|
||
Directory.CreateDirectory(directory);
|
||
}
|
||
|
||
// 检查文件大小并滚动
|
||
RollFileIfNeeded();
|
||
|
||
// 写入日志
|
||
File.AppendAllText(_filePath, message, Encoding.UTF8);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 文件滚动刷新
|
||
/// </summary>
|
||
private void RollFileIfNeeded()
|
||
{
|
||
try
|
||
{
|
||
var fileInfo = new FileInfo(_filePath);
|
||
if (fileInfo.Exists && fileInfo.Length >= _maxFileSize)
|
||
{
|
||
// 滚动文件命名:logs/app_20231005_001.log
|
||
var timestamp = DateTime.Now.ToString("yyyyMMdd");
|
||
var basePath = Path.Combine(
|
||
Path.GetDirectoryName(_filePath),
|
||
Path.GetFileNameWithoutExtension(_filePath)
|
||
);
|
||
var newFilePath = $"{basePath}_{timestamp}_{Guid.NewGuid():n}{Path.GetExtension(_filePath)}";
|
||
File.Move(_filePath, newFilePath);
|
||
|
||
// 清理旧文件
|
||
var directory = new DirectoryInfo(Path.GetDirectoryName(_filePath));
|
||
var files = directory.GetFiles($"{Path.GetFileNameWithoutExtension(_filePath)}_*")
|
||
.OrderByDescending(f => f.CreationTime)
|
||
.Skip(_maxRetainedFiles - 1)
|
||
.ToList();
|
||
|
||
foreach (var file in files)
|
||
{
|
||
file.Delete();
|
||
}
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
// 处理文件操作异常(如权限不足)
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 日志写入帮助类
|
||
/// </summary>
|
||
public class FileLoggerProvider : ILoggerProvider
|
||
{
|
||
private readonly string _filePath;
|
||
private readonly long _maxFileSize;
|
||
private readonly int _maxRetainedFiles;
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
/// <param name="filePath"></param>
|
||
/// <param name="maxFileSize"></param>
|
||
/// <param name="maxRetainedFiles"></param>
|
||
public FileLoggerProvider(string filePath, long maxFileSize, int maxRetainedFiles)
|
||
{
|
||
_filePath = filePath;
|
||
_maxFileSize = maxFileSize;
|
||
_maxRetainedFiles = maxRetainedFiles;
|
||
}
|
||
/// <summary>
|
||
/// 创建日志写入器
|
||
/// </summary>
|
||
/// <param name="categoryName"></param>
|
||
/// <returns></returns>
|
||
public ILogger CreateLogger(string categoryName)
|
||
{
|
||
return new FileLogger(categoryName, _filePath, _maxFileSize, _maxRetainedFiles);
|
||
}
|
||
/// <summary>
|
||
/// 清理资源
|
||
/// </summary>
|
||
public void Dispose()
|
||
{
|
||
// 清理资源(如需要)
|
||
}
|
||
}
|
||
}
|