using System; using System.Collections.Generic; using UnityEngine; namespace Logging { public static class LogCapturer { // 日志条目结构 public struct LogEntry { public DateTime Timestamp; public LogType Type; public string Message; public string StackTrace; public override string ToString() { // 逻辑修改:扩展条件,使LogType.Error和LogType.Assert也能显示堆栈信息 if (Type == LogType.Exception || Type == LogType.Error || Type == LogType.Assert) { return $"[{Timestamp:HH:mm:ss}] [{Type}] {Message}\n{StackTrace}"; } return $"[{Timestamp:HH:mm:ss}] [{Type}] {Message}"; } } private static readonly Queue _logs = new Queue(); private static readonly object _lock = new object(); // 线程锁 private static int _maxLogs = 1000; // 默认容量 private static bool _isInitialized = false; // 逻辑修改:添加一个私有标志来跟踪是否已初始化 // 最大日志容量属性 public static int MaxLogs { get => _maxLogs; set { lock (_lock) { _maxLogs = Mathf.Max(value, 1); // 最小值为1 TrimExcess(); } } } // 逻辑修改:添加 [RuntimeInitializeOnLoadMethod] 特性,确保 Init() 方法在 Unity 启动时自动执行 [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] public static void Init() { // 确保线程安全地检查和设置初始化状态 lock (_lock) { if (_isInitialized) { Debug.LogWarning("[LogCapturer] Init() called multiple times. LogCapturer is already initialized."); return; } Application.logMessageReceivedThreaded += HandleLog; _isInitialized = true; } } // 逻辑修改:添加一个 Shutdown 方法来解除事件注册和清理 public static void Shutdown() { // 确保线程安全地检查和解除注册 lock (_lock) { if (!_isInitialized) { Debug.LogWarning("[LogCapturer] Shutdown() called but LogCapturer was not initialized."); return; } Application.logMessageReceivedThreaded -= HandleLog; _isInitialized = false; _logs.Clear(); // 逻辑修改:在关闭时清空所有捕获的日志,确保下次启用时是全新状态。 } } // 日志处理回调 private static void HandleLog(string message, string stackTrace, LogType type) { lock (_lock) { var entry = new LogEntry { Timestamp = DateTime.Now, Type = type, Message = message, StackTrace = stackTrace }; _logs.Enqueue(entry); TrimExcess(); } } // 日志队列修剪 private static void TrimExcess() { while (_logs.Count > _maxLogs) { _logs.Dequeue(); } } // 获取当前所有日志(倒序:最新在前) public static List GetLogs(bool reverseOrder = true) { lock (_lock) { var list = new List(_logs); if (reverseOrder) list.Reverse(); return list; } } // 清空日志 public static void Clear() { lock (_lock) { _logs.Clear(); } } } }