虽然我们有完善的数据埋点和错误日志收集,但是有时候用户报告的问题有可能正好没有被埋点和日志覆盖,这不仅给我们解决问题造成困难,也无法估计问题影响范围,本文结合实例和时事要闻对此类问题的解决和估算做了分析和展望。[原文链接][原文链接]

什么是业务错误的”暗物质“成分?

我们判断业务的错误率一般是通过埋点,遇到异常或者失败的时候上报一个错误状态以及错误信息,这样可以监控到业务的失败率。应该说,绝大部分业务错误通过这种方式是可以检测到的。埋点就像警戒雷达一样随时监控错误,一旦发生就告警通知我们修复。

但是难免会出现意外的情况,业务发生了错误但是并没有上报埋点。这样的错误就像暗物质一样,它只对用户发生作用,不和我们的埋点、日志发生作用:悄悄得给用户制造一场意外,默默得退回到一个未知角落,静静得等待时机下一次作妖,我们的警戒雷达却无法发现它。因为这种“暗物质错误”不会报告埋点,我们也不能通过埋点知道它是否发生,不掌握它发生了多少次,只能依靠少数热心用户主动报告,这些热心用户很珍贵,他们就是我们的眼睛。

下图是一位特斯拉热心用户在主动报告问题: JPG

物理上的暗物质,是和引力场发生作用,但是不和电磁场发生作用的物质,因为人类观察宇宙的主要手段就是电磁波,所以被叫做暗物质。和这类不反应在埋点上但是反应在用户体验上的错误就很像。

“暗物质错误”的危害

特斯拉目前遇到的问题,疑似是这种错误:用户反馈了错误,但是他们排查埋点没有发现问题点,也不能用自己的设备重现问题,于是公布了错误发生前半小时埋点发动大家一起查:

JPG

就我遇到的情况,有三种原因:有的是因为吞掉异常导致,当然就无法检测到错误现象(被我们吞了);有可能是第三方SDK导致,比如第三方SDK本来失败了, 但是返回“成功”给快手,这样自然也会制造一个无法被检测到的错误;也有可能是手机系统问题,虽然比较罕见,但是也不是不可能,我们最近遇到的一个问题就是vivo Android 11手机上出现的,因为是系统问题,应用层面基本没机会捕获到这样的错误。当然不排除其他原因,好比特斯拉遇到的应该就不是这三种之一。

收到用户上报以后,如果能及时定位和解决问题就还好,然而这类问题也只有上述的第一种情况还可能相对容易及时定位,另外两种情况都需要和第三方反复沟通,甚至需要拿到问题现场获取日志,这个时候除了解决Bug的超期压力以外,我们还面临着另外一个压力就是,我们不知道这种错误在每天好几亿用户里面占比多少,无法评估这类错误的严重程度。

想一下,如果你的手机偶尔重启,你会联系厂商报告错误吗?大概心中暗下决心:换手机也换牌子!

很久以前我收到过一个用户反馈分享错误,还好这个错误通过查埋点可以查到失败信息和函数调用堆栈,它仍然在监控中只是没有设置在报警范围里面而已。这个用户报告的错误是每天发生N次,已经持续两星期,也就是说一个主动上报用户背后,可能是14*N次错误(pv),具体数字恕我保密了。这样可以在埋点查到的错误,总是有办法处理的,后来我们调整了APM监控,增加了集中出现的错误的监控,把这类问题纳入了警戒雷达的视线。

从这个角度来说,“暗物质错误”的最大危害就是我们不知道它有多严重。

就像物理学的暗物质可以通过电磁波以外的手段探知一鳞半爪,这样的“暗物质错误”也有可能通过埋点数据分析,至少能做到管中窥豹。

捕获已知“暗物质错误”的具体案例

就我遇到的一个案例来说,用户反馈了错误,虽然不能用埋点直接排查出来,但是根据现有的埋点也是有可能估计出大致的数量的。

问题的具体现象是用户执行QQ或者QZone分享的时候,没有拉起QQ,反而提示了”邀请成功”。

我们通过添加日志给用户重现回捞以后确认是QQ SDK的问题,没有成功拉起QQ并且直接返回了取消回调。在埋点的表现上看,这种错误隐藏在了普通的取消事件里面。

这个问题在排查过程中联系了QQ的技术支持人员,但是由于用户那里的QQ日志回捞失败,导致无法进一步推进。我们观察QQ和QZone的相关分享数据,在用户报告前后没有发生可信的数据波动,可以排除这个问题是刚刚发生并且有较大影响的可能,但是有没有可能这个问题从一开始就存在呢?它占比是多少呢?

更为严峻的是,这个用户提到,他的很多朋友也有一样的问题。

从正面的分析是不可能得到答案的,出错的取消和正常的取消对我们来说都是来自QQ SDK的取消回调,不会标记出来“这个取消是错的,请关注”,“这个取消是用户的,不用关注”。 JPG JPG JPG

不过我们可以观察一下龌龊的金条有什么特征:它是QQ SDK直接返回的,用户没有做任何操作,界面闪了一下就消失了。

那么,这样的取消,速度应该很快,比普通的用户亲手点取消按钮的取消分享要快很多。而且我们添加日志也证明这一点,用户那里上报的埋点可以计算出来从启动分享到取消只有2.15秒。

正好我们的埋点记录了开始分享、结束分享的时间,通过计算时间,如果大部分用户的取消用时间都比较长,那么就可以放心的认为这个错误影响并不大。

按照这个思路,我下载了一天当中两个小时的分享数据,然后写脚本计算了这些数据当中低于2秒的取消,占比在10%左右,考虑到手比较快取消掉的因素,又检查低于0.5秒的取消,占比不超过5%,那么可以判断出这个错误影响并不严重。

也可以用SQL直接查询,这样可以针对一整天采样,效率更高。

不过我们还遇到另外一个案例就不能这样简单的解决,这个问题是vivo 的Android 11手机上可能出现分享面板没有绘制出来,但是仍然保留了交互能力,对于这样的问题就比较复杂,可能可以通过检测被误点的按钮来排查,不过还没有尝试。

主动探索未知的“暗物质错误”

当用户反馈以后,我们就知道了某种“暗物质错误”的表现形式,按图索骥的去查出一个估计的错误数量级,能够评估错误严重程度,或者尝试与疑似用户联系取得更多的错误样本帮助解决问题,固然比收到反馈无可奈何好得多。但是有没有可能主动出击,在用户反馈以前就知道可能存在问题,通过增加日志、主动联系可能出问题用户方式解决问题呢?

简单一点的办法是找出“不合理的埋点”。好比分享埋点,如果从启动到结束的时间特别短,短得低于常识,不管成功、失败还是取消,都是很可疑的现象,值得增加日志去排查。虽然埋点上报了,但是它不合理,那么这很大概率是一个“暗物质错误”在作妖。

还有一个比较大胆的想法,我们的用户数据足够多,不知道能不能引入大数据分析,判断出来偏离主流用户的一些行为,如果偏离超过2个标准差一般就认为很异常了。类似前面的第二个案例,它没有简单的判断方法,但是因为用户看不到界面,却可以交互,就会发生乱点按钮的现象,如果可以通过一定方式判断“乱点按钮”,对我们已知的vivo Android 11用户群体重点排查,也许可以估计出来问题影响范围。我做客户端开发,对大数据分析是外行,希望专家们看一点是否有可能?

不过坦率讲,这样做可能投入产出比不高。

“暗物质错误”的总量估计

科学家估计宇宙中的暗物质占比大约是26.8%,我们有没有可能估计一下这种“暗物质错误”的占比呢?

具体的数值很难给出,但是好消息在于这类错误肯定概率很低,毕竟我们的发布流程是必须经过严格的测试才会上线,能够从我们的测试工程师手里逃过bug的,本身出现的概率就已经很低了,应该介于线上问题的数量和被发现的线上问题数量之间,所以是个很低的比例。

也因此这类“暗物质错误”的捕获绝不是件容易的事情,如果容易,我们的测试工程师就不会放过它。数据工程师需要精心设计埋点得以互相验证,开发工程师也需要认真核对和维护埋点,一般刚刚添加的埋点是正确的,就怕代码重构或者修改附带修改埋点导致错误。做到这些,出现了此类问题的时候,我们就可能通过埋点之间的不合理现象捉出来这些“暗物质错误”。