直接上效果和代码:
代码:
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.VisualBasic.Logging;
public static class LogHelper
{
private static TraceSource _logSource;
private static FileLogTraceListener _fileListener;
private static string _currentLogPath;
private const int MaxLogSizeKB = 500; // 日志文件最大500KB
private const int KeepLogFiles = 3; // 保留最近3个日志文件
/// <summary>
/// 初始化日志系统(支持按大小滚动)
/// </summary>
public static void Initialize(string logDirectory = null, string baseFileName = "App")
{
_logSource = new TraceSource("AppLogSource");
_logSource.Switch = new SourceSwitch("LogSwitch") { Level = SourceLevels.All };
// 初始化日志路径
string logDir = logDirectory ?? $"{AppDomain.CurrentDomain.BaseDirectory}\\Logs";
Directory.CreateDirectory(logDir);
// 创建初始日志文件
CreateNewLogFile(logDir, baseFileName);
}
/// <summary>
/// 记录日志(自动检查文件大小)
/// </summary>
public static void Log(string message, TraceEventType eventType = TraceEventType.Information)
{
if (_logSource == null) throw new InvalidOperationException("请先调用 Initialize()");
// 写入日志
_logSource.TraceEvent(eventType, 0, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}");
// 检查文件大小
CheckAndRotateLog();
}
/// <summary>
/// 创建新日志文件并清理旧文件
/// </summary>
private static void CreateNewLogFile(string logDir, string baseFileName)
{
// 关闭旧监听器
if (_fileListener != null)
{
_logSource.Listeners.Remove(_fileListener);
_fileListener.Close();
_fileListener.Dispose();
}
// 生成带序号的新文件名(例如:App_1.log)
int fileIndex = GetNextFileIndex(logDir, baseFileName);
_currentLogPath = Path.Combine(logDir, $"{baseFileName}_{fileIndex}.log");
// 创建新监听器
_fileListener = new FileLogTraceListener
{
LogFileCreationSchedule = LogFileCreationScheduleOption.None,
Location = LogFileLocation.Custom,
CustomLocation = logDir,
BaseFileName = Path.GetFileNameWithoutExtension(_currentLogPath),
Append = true,
AutoFlush = true
};
_logSource.Listeners.Add(_fileListener);
// 清理旧文件
CleanOldLogs(logDir, baseFileName);
}
/// <summary>
/// 获取下一个可用文件序号
/// </summary>
private static int GetNextFileIndex(string logDir, string baseFileName)
{
var files = Directory.GetFiles(logDir, $"{baseFileName}_*.log");
return files.Length + 1;
}
/// <summary>
/// 清理旧日志文件(保留最近 KeepLogFiles 个)
/// </summary>
private static void CleanOldLogs(string logDir, string baseFileName)
{
var files = Directory.GetFiles(logDir, $"{baseFileName}_*.log")
.OrderBy(f => File.GetCreationTime(f))
.ToList();
while (files.Count > KeepLogFiles)
{
File.Delete(files.First());
files.RemoveAt(0);
}
}
/// <summary>
/// 检查当前日志文件大小并滚动
/// </summary>
private static void CheckAndRotateLog()
{
try
{
var fileInfo = new FileInfo(_currentLogPath);
if (fileInfo.Exists && fileInfo.Length > MaxLogSizeKB * 1024)
{
CreateNewLogFile(Path.GetDirectoryName(_currentLogPath),
Path.GetFileNameWithoutExtension(_currentLogPath).Split('_')[0]);
}
}
catch (Exception ex)
{
Trace.TraceError($"日志滚动失败: {ex.Message}");
}
}
}
可以实现滚动记录日志,效率不算高,如果追求效率考虑使用seriallog库等,这个库只适合简单工具,不想依赖其他库的情况下使用。