Unity 日志存档功能
一、问题:Windows系统路径中生成的日志文件没有历史记录,
二、方案:程序每次运行时都生成一份日志文件,这样就可以有历史记录了
三、拓展:有历史记录了,但如何保证程序异常退出时日志依然不会丢失呢
使用固定时间自动保存一次
using UnityEngine;
using System.Collections.Concurrent;
using System.IO;
using System.Collections;
using System;public class LogBackup : MonoBehaviour
{private ConcurrentQueue<string> logBuffer = new ConcurrentQueue<string>();private string logDirectory;private string currentLogFile;private bool isSaving = false;[Tooltip("是否记录代码堆栈信息")]public bool CodeInfo = false;[Tooltip("自动保存间隔(秒)")]public float AutoSaveInterval = 5f;public bool UseDebugModel = true;void Awake(){}private void Start(){UseDebugModel = XMLConfig.Instance.GetBool("UseDebugModel");if (!UseDebugModel){gameObject.SetActive(false);}else{InitializeLogSystem();Application.logMessageReceived += HandleLog;Application.quitting += SaveAndClose;// 启动自动保存协程StartCoroutine(AutoSaveRoutine());}}void OnDestroy(){Application.logMessageReceived -= HandleLog;Application.quitting -= SaveAndClose;StopAllCoroutines();}void InitializeLogSystem(){logDirectory = Path.Combine(Application.persistentDataPath, "GameLogs");Directory.CreateDirectory(logDirectory);CreateNewLogFile();}void CreateNewLogFile(){string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss_fff");currentLogFile = Path.Combine(logDirectory, $"RunLog_{timestamp}.txt");File.WriteAllText(currentLogFile, string.Empty); // 清空旧文件}void HandleLog(string logString, string stackTrace, LogType type){string formattedLog = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} [{type}] {logString}";if (CodeInfo && !string.IsNullOrEmpty(stackTrace)){formattedLog += $"\nStack Trace:\n{stackTrace}";}logBuffer.Enqueue(formattedLog + "\n");}IEnumerator AutoSaveRoutine(){while (true){yield return new WaitForSeconds(AutoSaveInterval);if (!isSaving) SaveLogs();}}void SaveAndClose(){Debug.Log("程序结束,存档");SaveLogs();// 强制立即保存(针对强制关机场景)ForceSave();}void SaveLogs(){if (logBuffer.IsEmpty || isSaving) return;isSaving = true;try{using (StreamWriter writer = new StreamWriter(currentLogFile, true)){writer.AutoFlush = true; // 关键:自动刷盘while (logBuffer.TryDequeue(out string log)){writer.Write(log);}}//Debug.Log($"Logs saved to: {currentLogFile}");}catch (Exception e){Debug.LogError($"Log save failed: {e.Message}");}finally{isSaving = false;}}void ForceSave(){// 最后一次紧急保存(尝试立即写入)if (logBuffer.TryDequeue(out string log)){try{File.AppendAllText(currentLogFile, log);}catch (Exception ex) { Debug.Log(ex);/* 无法恢复的错误 */ }}}#if UNITY_EDITORvoid Update(){if (Input.GetKeyDown(KeyCode.S)){SaveLogs();}}
#endif
}