// ====== 2025线程安全日志系统 ====== using Cysharp.Threading.Tasks; using System; using System.IO; using System.Threading; using UnityEngine; public static class LogSystem2025 { /// 日志存放的可读写位置 public static string mLogPath = Application.persistentDataPath; /// 日志存放文件名 public static readonly string mLogName = "CollectRunLog.log"; /// 日志存放完整路径 private static readonly string LogPath = Path.Combine(mLogPath, mLogName); private static readonly object fileLock = new object(); /// /// 初始化日志系统(游戏启动时调用) /// [RuntimeInitializeOnLoadMethod] static void Initialize() { ClearLogAsync().Forget(); Application.logMessageReceivedThreaded += OnLogReceived; } /// /// 清空日志文件(线程池执行) /// private static async UniTaskVoid ClearLogAsync() { await UniTask.RunOnThreadPool(() => { lock (fileLock) { try { using (var fs = new FileStream(LogPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true)) { fs.SetLength(0); // 原子清空操作‌:ml-citation{ref="2,3" data="citationList"} } File.AppendAllText(LogPath, $"=== 日志初始化 {System.DateTime.Now:yyyy-MM-dd} ===\n"); } catch (IOException ex) { CDebug.LogError($"日志清空失败: {ex.Message}"); } } }); } /// /// 日志接收回调(线程安全) /// private static void OnLogReceived(string condition, string stackTrace, LogType type) { UniTask.RunOnThreadPool(() => { if (type == LogType.Error)//只选择了错误的日志记录(按需设置) { var logEntry = $"[{type}] {System.DateTime.Now:HH:mm:ss} {condition}\n{stackTrace}\n"; lock (fileLock) { try { File.AppendAllText(LogPath, logEntry); // 异步追加写入‌:ml-citation{ref="1" data="citationList"} } catch (Exception ex) { CDebug.LogError($"日志写入失败: {ex.Message}"); } } } }).Forget(); } }