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_EDITOR
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            SaveLogs();
        }
    }
#endif
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值