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()
|
|||
|
|
{
|
|||
|
|
// 清理资源(如需要)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|