using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using WIDESEAWCS_Core.Helper; namespace WIDESEAWCS_Core.LogHelper { public class LoggerHelper { // 读写锁,确保多线程环境下日志写入的线程安全 static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim(); // 日志文件夹路径 static string folderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"Log"); // 记录日志的队列 static Queue logQueue = new Queue(); static LoggerHelper() { try { if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } /// /// /// /// /// public static void WriteError(Exception ex, string filePath = "") { StringBuilder builder = new StringBuilder(); builder.Append("错误信息:"); builder.Append(ex.Message); builder.Append(Environment.NewLine); builder.Append("错误源:"); builder.Append(ex.Source); builder.Append(Environment.NewLine); builder.Append("错误堆栈:"); builder.Append(ex.StackTrace); builder.Append(Environment.NewLine); builder.Append("错误类型:"); builder.Append(ex.GetType().ToString()); builder.Append(Environment.NewLine); builder.Append("错误方法:"); builder.Append(ex.TargetSite?.ToString()); builder.Append(Environment.NewLine); builder.Append(Environment.NewLine); WriteLogToFile($"Error_", builder.ToString(), filePath); } /// /// 将日志内容写入指定文件 /// /// 日志文件名 /// 要记录的日志内容 /// /// 该方法会确保线程安全地写入日志,若目录不存在会自动创建, /// 日志内容会自动添加时间戳并追加到文件末尾 /// public static void WriteLogToFile(string fileName, string log, string filePath = "") { try { // 进入写锁 LogWriteLock.EnterWriteLock(); string path = string.IsNullOrEmpty(filePath) ? folderPath : filePath; // 如果文件夹不存在,则创建文件夹 if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } // 获取日志文件路径 string logFilePath = Path.Combine(path, GetLastAccessFileName(fileName, path)); // 获取当前时间 DateTime now = DateTime.Now; // 构造日志内容 string logContent = $"【{now}】{Environment.NewLine}{log}"; // 将日志内容追加到日志文件中 File.AppendAllText(logFilePath, logContent); WriteCompleted(); } catch { } finally { // 退出写锁 LogWriteLock.ExitWriteLock(); } } static int size = 10 * 1024 * 1024; /// /// 获取最后一个可用的日志文件名 /// /// 日志文件基础名称 /// 如果存在未达到大小限制的日志文件则返回该文件名,否则返回基于当前时间的新日志文件名 /// /// 该方法会遍历所有已存在的日志文件,返回第一个文件大小未超过限制的文件名。 /// 如果没有符合条件的文件,则生成一个以当前时间命名的新日志文件名。 /// private static string GetLastAccessFileName(string fileName, string path) { foreach (var m in GetExistLogFileNames(fileName, path)) { FileInfo fileInfo = new FileInfo(m); if (fileInfo.Length < size) { return m; } } // 返回一个新的默认当前时间的日志名称 return $@"{fileName}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.log"; } /// /// 获取指定文件名模式的所有日志文件 /// /// 日志文件名前缀 /// 匹配文件名模式的所有日志文件路径数组 private static string[] GetExistLogFileNames(string fileName, string path) { string[] fileNames = Directory.GetFiles(path, fileName + "*.log"); return fileNames; } private static string[] GetExistLogFileNames() { if (!string.IsNullOrEmpty(folderPath)) return Directory.GetFiles(folderPath, "Error_*.log"); else return new string[] { }; } private static int controlFileQuantity = 100; protected static void WriteCompleted() { if (controlFileQuantity > 1) { try { string[] files = GetExistLogFileNames(); if (files.Length > controlFileQuantity) { List fileInfos = new List(); for (int i = 0; i < files.Length; i++) { fileInfos.Add(new FileInfo(files[i])); } fileInfos.Sort(new Comparison((m, n) => { return m.CreationTime.CompareTo(n.CreationTime); })); for (int i = 0; i < fileInfos.Count - controlFileQuantity; i++) { File.Delete(fileInfos[i].FullName); } } } catch { } } } } }