直接上效果和代码:
代码:
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; // 日志文件最大500KBprivate 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库等,这个库只适合简单工具,不想依赖其他库的情况下使用。