一、问题: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
}