unity-错误上报之Bugly

这个功能是为了上线后能获取到用户运行中遇到的 报错, 闪退 日志, 便于及时修正错误然后做个 热更 (lua)


前篇

主要记录一下接入 bugly 遇到的坑及解决办法, 和 上报机制

Bugly Unity Plugin 使用指南 - https://bugly.qq.com/docs/user-guide/instruction-manual-plugin-unity/?v=20181014122344


bugly 接入 - Android 篇

  1. 基本按照官方的方式去接入, 导入 bugly_plugin_*.unitypackage, 安卓只保留 buglyagent.jar , 其他的 如 bugly.jar 和 动态库 so 等都去掉.

  2. 安卓方面使用官方建议的 自动集成 的方式去集成 jar 和 so 库. 参考: Bugly Android SDK 使用指南 - https://bugly.qq.com/docs/user-guide/instruction-manual-android/

    AndroidManifest.xml 加入相关权限, 然后在 unity 的 mainTemplate.gradle 中引入 bugly 的 jar 和 so 库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    // ------ sdk begin ------
    // bugly
    implementation 'com.tencent.bugly:crashreport:latest.release'
    implementation 'com.tencent.bugly:nativecrashreport:latest.release'
    // ------ sdk end ------

    **DEPS**}
  3. 然后按官方的文档在 csharp 初始化一下就可以用了.

踩坑

  1. 使用 手动集成 方式, 官方提供的 jar,so 都丢进 Plugins\Android 目录里, mainTemplate.gradleimplementation 引入 jar,so.

    在游戏运行时遇到 >= LogError 错被 bugly 捕获时会偶现 闪退 或 卡死(主线程被阻塞) GitHub 上有哥们也遇到这样的问题:Unity 在Android P系统上会闪退 - https://github.com/leancloud/realtime-SDK-dotNET/issues/176

    解决办法就是项目内保留 buglyagent.jar , 其他的 如 bugly.jar 和 动态库 so 等都去掉, 通过 mainTemplate.gradle 中引入 bugly 的 jar 和 so 库

  2. 使用 自动集成 方式, 项目内 连 buglyagent.jar 都不保留, 全部 jar,so 都去掉, 只是通过 mainTemplate.gradle 中引入 bugly 的 jar 和 so 库, 会遇到 报错后上报不了错误到 bugly 后台

    解决办法还是项目内保留 buglyagent.jar , 其他的 如 bugly.jar 和 动态库 so 等都去掉, 通过 mainTemplate.gradle 中引入 bugly 的 jar 和 so 库


bugly 接入 - iOS 篇


上报机制

调用 bugly 的 BuglyAgent.EnableExceptionHandler(); 接口默认将 >= LogError 的日志上报. 游戏里用了 tolua, 可以捕获到异常日之后自己组织数据格式调用 BuglyAgent.ReportException(title, reason, stack); 上报.

这样一个 lua 错误可能会有两个日志, 这是不需要的. 修改一下 bugly , 可以在 bugly 监听中拦截

然后在 LuaException 中植入错误捕获回调

1
2
3
4
public LuaException(string msg, Exception e = null, int skip = 1) : base(msg) {    
//植入错误捕获
if (ErrorCallback != null)
ErrorCallback(msg, StackTraceUtility.ExtractStackTrace());

调用 lua 的全局错误捕获函数

1
2
3
LuaException.ErrorCallback = (string msg, string stack) => {
Ins.CallFunction("__G__TRACKBACK__", msg, stack);
};

lua 中组织数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
local errIns = require("logic.error_handler"):New()
function __G__TRACKBACK__(errMsg, stack, isCs)
errIns:Catch(errMsg, stack or debug.traceback("", 1), isCs == nil)
end

-- error_handler.lua
function CErrorHandler.SendToServer(self, errMsg, stack, isLuaType)
errMsg = string.format("[v%s]-[%s]-[%s]", GetVersion(), (isLuaType and "lua" or "cs"), errMsg)

local userMsg, userId = self:GetUserInfo()

if isLuaType then
stack = string.gsub(stack, "\nstack traceback:\n", "")
end
gLog("--- ReportCustomExp\nerrMsg:\t{0}\nuserMsg:\t{1}\nuserId:\t{2}\nstack:\t{3}", errMsg, userMsg, userId, stack)
self._gameIns:ReportCustomExp(errMsg, userMsg, stack, userId) -- bugly 上报接口
end

后代看到的数据

高级搜索支持模糊搜索, 比如搜索 [lua]*

  • 为什么要自己组织数据格式?
    1. 为了搜索定位某些日志
    2. bugly 后台中的版本只是打包时的版本, 如果游戏打 patch 热更后修复了某些问题, 就需要知己把当前的版本也上报上去, 所以这里在 title 中加了 版本号 用来区分是哪个版本的错误日志.