Unity 输出Debug.log Debug.ErrorLog文件保存到本地

用法:直接挂到第一个场景内的游戏对象上即可。代码如下

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public abstract class MonoSingletonManager<T> : MonoBehaviour where T : MonoSingletonManager<T>
{
    protected static T instance = null;

    public static T GetInstance()
    {
        if (instance == null)
        {
            instance = FindObjectOfType<T>();
        }

        return instance;
    }

    protected virtual void OnDestroy()
    {
        instance = null;
    }
}
public enum LogLevel
{
    LOG = 0,
    WARNING = 1,
    ERROR = 2,   
}
public class DebugHelper : MonoSingletonManager<DebugHelper>
{
    public LogLevel SaveLogLevel;
    public bool IsSameFile;
    Queue<LogItem> m_vLogs;
    FileInfo m_logFileInfo;
    static bool m_isInited;
    string logFolder;
    string logFilename;
    string path;

    private Dictionary<LogType, LogLevel> logTypeLevelDict = null;
    private void Awake()
    {
        if (m_isInited)
        {
            Debug.Log("existed logfile object,break");
            Destroy(gameObject);
            return;
        }
        Init();
    }
    private void OnDestroy() 
    {
        //Application.logMessageReceived -= OnLogMessage;
        Application.logMessageReceivedThreaded -= OnLogMessageThread;
    }
    void FixedUpdate()
    {
        if (m_isInited)
        {
            this.Refresh(Time.fixedDeltaTime);
        }       
    }

    public void Init()
    {
        if (m_isInited)
        {
            return;
        }
        DontDestroyOnLoad(gameObject);
        m_isInited = true;
        logTypeLevelDict = new Dictionary<LogType, LogLevel>() {
                { LogType.Log, LogLevel.LOG },
                { LogType.Warning, LogLevel.WARNING },
                { LogType.Assert, LogLevel.ERROR },
                { LogType.Error, LogLevel.ERROR },
                { LogType.Exception, LogLevel.ERROR }};
        // 创建文件
        DateTime timeNow = DateTime.Now;
#if UNITY_EDITOR
        logFolder = Application.dataPath+"/..";
#else
        logFolder = Application.persistentDataPath;
#endif
        if (IsSameFile)
        {
            path = logFolder + "/Log.txt";
        }else
        {
            path = logFolder + "/Log" + timeNow.ToString("yyyyMMddHHmmss") + ".txt";
        }

        m_logFileInfo = new FileInfo(path);
        var sw = m_logFileInfo.CreateText();
        sw.WriteLine("[{0}] - {1}", Application.productName, timeNow.ToString("yyyy/MM/dd HH:mm:ss"));
        sw.Close();
        Debug.Log("日志文件已创建:" + path);

        // 注册回调
        m_vLogs = new Queue<LogItem>();
        //Application.logMessageReceived += OnLogMessage;
        Application.logMessageReceivedThreaded += OnLogMessageThread;
        Debug.Log("日志系统已启动");
    }


    public void Refresh(float dt)
    {
        if (m_vLogs.Count > 0)
        {
            try
            {
                var sw = m_logFileInfo.AppendText();
                var item = m_vLogs.Peek(); // 取队首元素但先不移除
                var timeStr = item.time.ToString("HH:mm:ss.ff");
                var logStr = string.Format("{0}-[{1}]{2}", timeStr, item.logType, item.messageString);
                //if (item.logType.Equals(LogType.Error))
                if(logTypeLevelDict[item.logType].Equals(LogLevel.ERROR))
                {
                    logStr = string.Format("{0}-[{1}]{2}==>{3}", timeStr, item.logType, item.messageString, item.stackTrace);
                }
                sw.WriteLine(logStr);
                sw.Close();
                m_vLogs.Dequeue(); // 成功执行了再移除队首元素
            }
            catch (IOException ex)
            {
                Debug.Log(ex.Message);
            }
        }
    }

    private void OnLogMessage(string condition, string stackTrace, LogType type)
    {
        if(logTypeLevelDict[type]>= SaveLogLevel)
        {
            m_vLogs.Enqueue(new LogItem()
            {
                messageString = condition,
                stackTrace = stackTrace,
                logType = type,
                time = DateTime.Now
            });
        }      
    }

    void OnLogMessageThread(string condition, string stackTrace, LogType type)
    {
        if (logTypeLevelDict[type] >= SaveLogLevel)
        {
            m_vLogs.Enqueue(new LogItem()
            {
                messageString = condition,
                stackTrace = stackTrace,
                logType = type,
                time = DateTime.Now
            });
        }        
    }
}

public struct LogItem
{
    /// <summary>
    /// 日志内容
    /// </summary>
    public string messageString;

    /// <summary>
    /// 调用堆栈
    /// </summary>
    public string stackTrace;

    /// <summary>
    /// 日志类型
    /// </summary>
    public LogType logType;

    /// <summary>
    /// 记录时间
    /// </summary>
    public DateTime time;
}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值