版权归原作者所有,如有侵权,请联系我们

什么是App在线诊断模式?

中移科协
原创
有用的科技知识又增加了
收藏

互联网时代,在面向终端用户的移动App上,我们经常会收到用户反馈的各种问题,比如启动崩溃,登录失败等等。每次遇到这些问题,最终会流转到开发手里,并且需要尽快给出答复。日常中,开发人员一般都需要结合日志才能定位问题,但现实的难点是,这种时候往往没有日志提供,可能仅有一张问题截图。而当我们缺少这样的功能时,排查问题几乎不可能。因此,开发并上线这样的功能,就显得尤为迫切,它可以极大地提升处理客诉问题的效率,进而提升客户满意度。本文将从以下三个方面对App在线诊断模式进行全面的介绍。

1、简介

App在线诊断模式,顾名思义,它是App上辅助问题诊断的,这么说,可能还是不好理解。我举一个现实中非常形象且等价的例子,大家都知道飞机的黑匣子,即实时记录飞机飞行时的一些关键信息,各种参数等。同理,延伸到App层面,也是类似的。我们会在App运行时,记录它的各种关键信息,比如前后台切换信息、设备信息、网络信息、接口调用信息、用户操作行为等等。这些记录默认是开启的,且实时记录在本地文件中,当然可以通过后端开关来控制此行为,而上传只在用户报问题,需要进一步分析时,才会由后端下发上传指令。目的是能做到,当用户反馈问题时,本地大概率已经记录了问题发生时的日志,这时只要给此设备打开上传开关,拿到本地记录好的日志,便可进行下一步的分析了。

2、系统构成

一个完整的诊断模式系统,一般应包含三个大的模块,下文将按照终端、后端、前端的顺序,依次介绍各个模块。

2.1 终端模块

终端部分是诊断模式的核心所在,包含了最核心的功能实现,其架构如下图所示:


图1 终端模块示意图

①启动检查:诊断模式可以包含两个开关,diagMode(实时log开关)和upload开关,前者默认打开,后面默认关闭。diagMode也表示大的功能开关,启动时首先检查功能是否打开(通过读取本地存储的值,而非调用接口,主要是为了启动流程的连贯性),打开的话,则进入诊断模式逻辑,即启动日志线程(整个诊断模式运行在单独的diagnose线程里,这样做是为了减少对UI线程的干扰,以免影响到用户体验);否则做一些日志文件清理后退出诊断模式。单线程方式是一种典型的做法,当然不排除其他的实现方式。

②配置接口请求:App启动后,紧接着会请求配置接口信息,拿到诊断模式的两个开关值,App会将最新的diagMode写入到本地存储中(下次启动时,会直接读取)。如果是功能打开且需要上传,则立即执行上传操作,如果是功能关闭,则清理并退出诊断模式即可。当触发上传操作后,整个日志功能暂时是关闭的,因为上传时需要读取日志文件内容,而记录日志时,又需要写入文件,这里为了避免读写冲突,选择的方案就是等上传结束后,再根据诊断的开关,重启诊断模式,简单而有效。

③业务打点:这一部分是跟业务紧密相关的,具体日志内容,完全由上层业务决定,也是后期诊断问题时判断的重要依据。比如你可以写入关键接口请求的入参和出参,设备的信息、网络连接状态的信息,以及用户操作行为等等。这些日志请求,可以在任意线程里触发,而诊断模式内部会据此构造一条日志,日志格式和系统adb logcat -v threadtime的输出保持一致,包含进程id、线程id、时间戳等信息,方便后期定位问题。通过这些信息,可以轻松地分辨出日志来自哪个线程,而不一定是主线程。具体要添加哪些日志,需要结合业务场景来判断,也可以根据开发人员的经验决定。一般系统哪里容易出问题,哪个流程比较关键,这些都是比较理想的添加日志的地方。当然,这里的日志也是可以后期慢慢完善的,一开始的话,可以仅添加比较关键、重要的日志即可。

④日志写入文件:诊断模式内部是通过一个独立的HandlerThread来实现的,而且尽可能将所有相关操作都限定在本线程内部,这样做一方面是简单可靠,另一方面更重要的也是为了多线程安全。当业务层请求记录一条日志时,诊断模式内部会首先进行一些封装,生成一个Message对象,然后通过Handler将此消息发送到HandlerThread对应的消息队列中。可以看出这个实现是一个异步操作,好处就是业务层请求日志的速度不会受内部处理的影响,即上层可以1s内请求记录n条日志,而不用担心速度过快,导致日志丢失。HandlerThread内部从其消息队列中取出消息,逐一处理。而当遇到写入消息时,则打开日志文件(不存在的话,则先创建),写入一行日志内容,接着处理下一条消息,如此循环往复。

⑤上传并清理:当HandlerThread内部遇到的是条上传消息时,则关闭日志文件,执行真正的上传逻辑。等上传成功后,则将本地的日志文件删除,最后再根据diagMode的取值,决定是否重启诊断模式(上传的过程中,会短暂关闭,避免操作同一个文件产生冲突)。这里顺便提一下,日志文件可以不止一个,而是会根据一些策略生成不同的文件,且为了安全起见,单个日志文件的大小,也都有上限限制(避免极端情况下,占用端上过多存储)。

2.2 后端模块

后端部分主要涉及到配置和上传两个接口的功能实现。其架构如下图所示:


图2 后端模块示意图

①配置接口:根据全局配置、单台设备配置,综合计算得到此设备最终的配置信息,包括diagMode开关和upload开关。前者表示端上是否记录日志,后者表示是否上传本地日志。

②上传接口:承载具体的上传逻辑,校验端上的日志内容,文件大小等,接收并调用日志存储模块。

③日志存储:负责将上传的日志永久保留在服务器上,以便后续排查问题时使用。比如通过前端页面来展示日志内容,或者提供下载功能。

2.3 前端模块

前端主要是搭配管理平台使用。当遇到线上问题时,客服人员会在此页面进行配置,并且打开问题设备的上传开关,稍后就会有日志上传,接着开发人员就可以介入进行下一步分析了。其整体架构如下图所示:


图3 前端模块示意图

①添加设备:客服人员会根据用户的客诉反馈,拿到一些设备信息,比如sn或者mac。在此页面,输入这些信息,添加排障设备。

②设备列表:这里展示了所有之前排障过的设备,可以根据sn、mac进一步过滤展示,方便定位到单台设备。

③设备详情:当确定了具体的问题设备后,就可以进入到详情页面。在这里可以看到更多详细的信息,比如设备型号、系统版本、App版本等,当然最重要的还有日志上传按钮。点击按钮,等端上响应上传指令后,日志就可以在页面下方看到了,且依据记录日志的时间倒序排列。这时,就可以根据问题发生的时间找到相关日志,转交开发人员继续排查了。

3、未来展望

App在线诊断模式,上线后极大地提升了我们解决各种客诉问题的效率,但确实也存在一些技术上的点待优化。首先就是日志上传的时效性问题,从前面的介绍可以看出,上传还是依赖用户再次启动App,假设用户不配合,对时效的影响还是挺大的,这个可以考虑采用退后台外加定时的策略来进行弥补。另一个问题是功能上不是特别通用,跟业务还有些耦合,未来是希望能进一步解耦、封装,通过统一SDK的形式来输出这个能力,可以让三方App快速完成端上的对接。

作者:赵小伟

单位:中国移动智慧家庭运营中心

评论
陈 光 辉
少师级
App在线诊断模式,上线后极大地提升了我们解决各种客诉问题的效率,但确实也存在一些技术上的点待优化。
2024-03-30
飞马腾空
太师级
阅读理解
2024-03-30
科普张林海
太师级
学习
2024-03-30