开发时间省三倍:用 Ragic 自建 app 错误回报系统
开始开发 app 以来,后续维护方面一直有个困扰,就是有时候因为线索不足,很难直接透过订户口头、字或图片说明的错误回报内容找到问题源头来解 bug,所以一直在找能帮我更快解决问题的自动化回报机制。
其实,我们现阶段采用的 Flutter 已能支持 Firebase report 来自动获取错误回报信息。但是,通常看到错误回报的统计后,下一步就是要想办法确认问题、改善问题、避免问题再次出现。而 Firebase report 这样的第三方套件毕竟不是为我们“量身打造”的,实际上很多问题发生时,不见得能从 Firebase report 获取对应的 log。此时经常又得回到源、人工的“用户回报”流程,依靠用户的描述猜测是哪里出错,这样仍然无法有效抓出问题根源。
日前就遇到一个这样的例子:用户回报 app 一直无法顺利获取数据库的数据,但该台计算机又可以正常使用我们的网页版本。从我们手边既有的 log 信息、用户起初提供的信息,一直找不到问题的原因。后来经过多次猜测、邀请用户配合安装测试版本的 app ,才抓出问题所在:原来是该用户公司的网络环境不小心将我们其中一台服务器 IP 封锁掉了。
像这样的问题虽然最终解决了,但来来回回也耗掉好几天的时间,也因为如此,我们决定干脆自行开发专属的问题回报系统。这个回报机制最好让开发团队看到问题回报就知道哪一段 code 出问题,最好还能把用户是在什么操作情况下生成问题的信息带入,以达成比第三方套件更精确、更快解决问题的目的。
考量开发的时间成本、管理接口友善度等因素,我们采用 Ragic 作为存放 log 的数据库,Ragic 现成的工具接口和 API 大幅节省了开发时间,让我在 7 个小时内就建好系统,比原本预估时间省了将近三倍,很推入荐有类似开发需求的朋友参阅。以下就分享我们构思此系统的几个步骤,供大家参阅。
1. Log 存放
要做问题回报的系统,第一个问题就是:log 数据要放在哪边,用什么格式存放?
一开始的构想是写入到服务器某一个 log 字文件,或者使用 SQL 服务器存放,但不管是哪一个方案,似乎都还要花不少时间去处理纯字数据的呈现方式,毕竟我们希望可以更直觉地看到 log 内容所表达的问题,但前提是我们又不想花太多时间在视觉处理上面。
参阅很多现成方案之后,我们决定直接采用 Ragic 来当成回报数据的存放方案,考量的原因包括下列几点:
(1) 可将回报数据直接无痛支持 Ragic 26 种字段的呈现方式。举例来说,Log Type 就可以是从菜单选择字段,而 Record Time 直接可以是 Ragic 的日期字段(可对照下方采用 Ragic 当管理接口的图)。
(2) 可以直接使用 Ragic 写好的工具接口,包含转檔,大量修改、报表、通知......等功能。
(3) 数据串接的部分也可以直接使用 Ragic 提供的 API,也省去了自行开发 API 的时间。
另外,相较于纯字接口,直接使用 Ragic 来管理查询 app 回报的 log 变成一件很轻松的事情,Ragic 接口将纯字的 log 变成了一个漂亮整齐的数据浏览画面,提供更迅速直观数据的预览方式,直接内置的了字筛选与排序等数据库功能,在这些功能上面省去了不少开发时间。
下面两张图分别为“直接采用 Ragic 当成问题回报管理系统前端画面”与“传统纯字数据”的差异。
采用 Ragic 当作管理接口:
传统字 log:
2019/08/15, NoSuchMethodError: The method '[]' was called on null.2019/08/15, RangeError (length): Invalid value: Not in range 0..5
2019/08/15, moveToAddress camera update NoSuchMethodError..
2. Log 上载方式
存放方式解决之后,接下来要处理的就是让 app 调用的 API ,传统做法就是自己要开始写服务器端的 API 来处理 app 的调用,但因为我们把 log 存放在 Ragic,所以直接使用 Ragic 写好现成的 API 即可,Ragic 有完整的 REST API,开发者可以从官网 API查询并直接调用使用即可,这部分也是省下不少的开发时间啊!
3. Log 分析
我们前几年包含现在的 app 调试流程如下:
如果继续走这个流程,单纯分析 log 的话,Ragic 内置的的图形化报表分析工具已经很够用。Ragic 内置的的报表包括以下工具:
数据仪表板、排行报表、数据透视、分群报表、看板(任务板)、圆饼图、曲线图、行事历、甘特图
如果对 JavaScript 很熟的朋友,还可以直接使用 Ragic 提供的 Workflow 功能开发。
但既然现在 app 已经具有搜集问题的能力,接下来就会希望更进一步,除了上述维护方式之外,增加自动分析问题的能力,期望的模式如下:
要做到上述功能,就会需要自动分析每天的所有 log,其实每日 log 数量也不小,每天都有好几万笔数据,要分析的层面包含每个版本生成的 bug 归类、分析 bug 在新版本上是否有效降低生成次数、相同问题的用户回报数量......等等,数据处理需求较大,所以我们选择透过另外一台服务器来抓取 Ragic 上面的 log 数据并分析,需要编写额外的程序来处理这部分。
如果像我们一样,功能需要比较复杂或者有比较大量运算量的统计,建议这部分也另外创建一台服务器处理。下面我们就介绍如何透过 PHP 的方式来访问目前我们在 Ragic 上面的数据。
Ragic PHP SDK
Ragic API目前有提供 PHP SDK,有需要的人可以直接透过以下链接下载使用:
https://github.com/ragic/public/tree/master/HTTP%20API%20Sample/PHP-Sample
(1) SDK初始方式
require_once(RagicSDK/Ragic.php");$RagicSDK = new RagicSDK();
(2) Get 调用方式
基本使用方式
$RagicSDK = new RagicSDK();$RagicSDK->SetAPIKey("Your APIKey");
$Parameter = [];
$Parameter["api"] = true;
$RagicSDK->Get("表单路径", $Parameter);
服务器会响应范例
{"12": {
"_ragicId": 12,
"_star": false,
"姓名": "test guest",
"_index_title_": "test guest",
"pic": "k81cktVS1M@截屏 2020-04-13 下午3.07.54.png",
"file": "wBAK5UZp26@分机表.pdf",
"note": "",
"_index_": "",
"_seq": 1
}
}
(3) 数据排序与筛选
Ragic API 数据排序的说明见此链接;Ragic API 数据筛选的说明见此链接。
$RagicSDK = new RagicSDK();$RagicSDK->SetAPIKey("Your APIKey");
$Parameter = [];
$Parameter["api"] = true;
$Filter = ["1000002,eq,Error"];
$Sort = array(
"1000003" => "DESC"
);
$RagicSDK->Get("表单路径", $Parameter, $Filter, $Sort);
(4) Ragic登录调用范例
$RagicSDK = new RagicSDK();$LoginParameter = [];
$LoginParameter["u"] = $_GET["u"];
$LoginParameter["p"] = $_GET["p"];
$RagicSDK->Get("/AUTH", $LoginParameter);
(5) Post 调用方式
新增一笔数据
$RagicSDK = new RagicSDK();$RagicSDK->SetAPIKey("Your APIKey");
$PostParameter = [];
$PostParameter["1001183"] = "Test";
$PostParameter["1001184"] = "1234";
$PostParameter["api"] = "";
$RagicSDK->Post("表单路径", $PostParameter);
(6) Post 上载文件范例
require_once(RagicSDK/Ragic.php");$RagicSDK = new RagicSDK();
$RagicSDK->SetAPIKey("Your APIKey");
$PostParameter = [];
$PostParameter["api"] = "";
$file = realpath("test.jpg");
$mime = "image/jpg";
$file_name_onserver = "sample.jpg"; // use on server side
$cfile = curl_file_create($file, $mime, $file_name_onserver);
$PostParameter["1001228"] = $cfile;
$RagicSDK->Post("/zen4641/ios-test/18", $PostParameter);
(7) Delete 调用方式
$RagicSDK = new RagicSDK();$RagicSDK->SetAPIKey("Your APIKey");
$RagicSDK->Delete("表单路径")
4.总结
当初规划自建问题回报系统的目标有下面几项:
(1) 能提供比采用第三方套件更精准的回报信息
(2) 用最少的时间成本达成
(3) 接口友善
实际上这些目标确实都达到了,整套系统不包含 log 分析的部分,开发下来时间大概约 5-7 小时,比当初预估的时间省了将近三倍,原因是很多数据处理的部分,都直接透过 Ragic 处理掉了,实际运作下来也大幅度降低跟客户来回往返要数据与测试数据的时间。
最后,额外发现一个当初没预估到的优势:因为 Ragic提供的接口很容易上手,所以第一线客服人员就算不具备工程师的能力,一样可以查询看懂客户出现的回报问题,所以很多简易的问题或者非 app 错误的问题,就直接被解决掉,而不用再回报到工程师这边再测试。所以这边真的很推入荐有相同开发需求的朋友,直接采用 Ragic 当作问题回报方案的数据库。