【Unity】【PC】【错误上报】Bug上报插件 Trello Bug Tracker 使用介绍 (二):错误抓取部分

前言

上一章(https://blog.csdn.net/cyf649669121/article/details/105637064)说了关于Trello这个插件的使用和用户自定义上报的部分,不过还需要实现的一个就是错误抓取的功能。这个就和手机上用的Bugly就很像了,就是抓取Unity控制台输出的报错和异常,然后分类上报。

不过这个插件没有自己实现,需要我们自己来实现他。

 

设想

根据现有的一些功能,我想的是当接收到一次报错之后,是先记录下来。因为Unity经常有一个报错报很多次的情况,如果每次都记录下来上报未免太消耗了。而且我想在报错的瞬间抓取一下截图,上传的时候上传下当前的日志。这个是当前插件自带的功能需要整合一下。

此外个人建议是,收集之后不要直接上报。因为在报错收集的监听里是不能打Log的。所以收集到就报错,万一有新的报错岂不是很尴尬?

 

实现

报错收集

Unity里面收集报错需要监听一个函数:

//这里是两个函数二选一使用。
Application.logMessageReceivedThreaded += OnReceiveLog;
Application.logMessageReceived += OnReceiveLog;

Application.logMessageReceivedThreaded  和    Application.logMessageReceived 这两个函数二选一即可。两个的区别,我从网上看下来的话是 logMessageReceivedThreaded  是可以接受多线程的,而 logMessageReceived  是只能接受主线程的。我在主线程测试了一下两个函数,两个都能收到报错,多线程的没测试过。

我觉得可能区别不太大,我就监听 logMessageReceivedThreaded  了。

报错的监听函数如下:

        /// <summary>
        /// 一个打印物件;
        /// </summary>
        struct LogItem
        {
            public string condition;
            public string stackTrace;

            public LogItem(string con, string sta)
            {
                condition = con;
                stackTrace = sta;
            }
        }

        /// <summary>
        /// 已经生成过的报错;
        /// </summary>
        Dictionary<LogItem, int> dictLogIttems = new Dictionary<LogItem, int>();
        /// <summary>
        /// 等待上传的LogItem
        /// </summary>
        Dictionary<LogItem, Texture2D> dictUploadItem = new Dictionary<LogItem, Texture2D>();

        /// <summary>
        /// 报错信息的处理;
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="stackTrace">堆栈</param>
        /// <param name="type">打印类型</param>
        private void OnReceiveLog(string condition, string stackTrace, LogType type)
        {
            //编辑器下报错不需要上传,除非是在调试状态;
#if UNITY_EDITOR
            //return;
#endif
            if (type == LogType.Error || type == LogType.Exception)
            {
                LogItem newItem = new LogItem(condition, stackTrace);
                //去重;
                if (dictLogIttems.ContainsKey(newItem))
                    dictLogIttems[newItem]++;
                else
                {
                    //记录;
                    dictLogIttems.Add(newItem, 1);
                    //这里使用协程是因为截图需要在协程中完成;
                    StartCoroutine(GetScreenShotForLog(newItem));
                }
            }
        }

        IEnumerator GetScreenShotForLog(LogItem newLog)
        {
            yield return new WaitForEndOfFrame();
            //第一次产生的还需要截图;
            var tex2D = ScreenshotTool.TakeScreenshot();
            dictUploadItem.Add(newLog, tex2D);
        }

这里就把报错和异常滤出来进行处理,先存起来。不过这时候的截图确实是要实时的,不过也是只存第一次的截图即可。

 

报错上传

这里我对上传的函数做了一些改造,大概就是只传一张图,日志可传可不传之类的。考虑到可能会在同一时间上报多次错误,所有做了一些优化。

我这里设定的是,上传是每个1s就上传一次。具体方法如下:

   bool IsUploadEnd = true;
        /// <summary>
        /// 上传所有的Log;
        /// </summary>
        IEnumerator UploadAll()
        {
            IsUploadEnd = false;
            yield return null;

            if (dictUploadItem.Count > 0)
            {
                //截图需要实时截图,但是Log日志可以在上传时传最终的那个即可;
                string logPath = GetLogCopy();
                //上传每个错误;
                foreach (var item in dictUploadItem)
                {
                    LogItem log = item.Key;
                    Texture2D tex = item.Value;
                    TrelloCard card = trello.NewCard(log.condition, log.stackTrace, ListName_AutoReport);
                    yield return StartCoroutine(SendReportRoutine(card, tex, logPath));
                }
            }
            dictUploadItem.Clear();
            IsUploadEnd = true;
        }

这样就可以实现报错上传了,上面这个协程1s触发一次,没有上传完成不触发第二次。

        int uploadTime = 1;
        float lastUploadTime = 0;

        private void Update()
        {
            //分批地上传;
            if (IsUploadEnd)
            {
                //每隔一段时间上报一次
                lastUploadTime += Time.deltaTime;
                if (lastUploadTime > uploadTime)
                {
                    lastUploadTime = 0;
                    StartCoroutine(UploadAll());
                }
            }
        }

然后测试一下,随便手动打印个报错。

最后看到已经在网站上有当前的报错上报了:

不过这个有个缺点就是我的屏幕设置成1920*1080的,确实上传有点满了。

后续需要考虑把图片缩小一些,日志也弄小一些。(其实如果有报错堆栈的话,日志有没有其实没什么所谓)。

这样我们就实现了Unity的PC端错误上报。

 

后记

我后面把商店上的插件做了一些改造:https://download.csdn.net/download/cyf649669121/12346924

上传的版本没有例子文件和绘图工具(没有那么多花里胡哨的~),新增了我自己写的BugReport类,可以直接移植到别的项目中。另外我还升级了API,把以前的一些过时的API升级到Unity最新的了。

如果这两篇介绍与上传的包有冲突,以最新的为准~~(目前是包是最新的)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值