Appetizer Appetizer 基于字节码插桩的质量监控

AppetizerIO · 2017年03月31日 · 最后由 finger 回复于 2023年04月24日 · 9266 次阅读

前言

长久以来,开发过程中需要对 APP 进行各个方面的测量,例如启动时间、崩溃、HTTP 请求时间、控件点击时间、内存泄露、耗电等等。通常做法是插代码,打 log,或者使用一些 SDK(Bugly, acra 之类的)。这些方法要么变成满地不可维护的Log.d,搜集的数据是有一个逮一个,全凭人看。测量方法千奇百怪,测量点千变万化,手工的方法低效,不专业,不可维护,不可重用。我们发布了新版 Appetizer 带来了我们的自动监控服务。

简介

自动监控服务分为三步骤:

  1. 对一个打包好的 APK 文件进行字节码级别的插桩,实现对 APP 内一些开发者关心的程序状态进行自动测量,输出是插桩后的 APK,可以重新签名;通过基于规则的方式找插入点,比手工高效、全面(可以插桩到第三方库代码),而且在源代码里面无痕,测量逻辑和业务逻辑分离。
  2. 在测试设备上运行插桩后的 APK,经过已有的测试流程(人工、自动、回归、压测等等),自动监控服务会持续记录各种数据(到设备 SD 卡);
  3. 收集数据的数据经过上传、分析,产生问题报告。报告目前涵盖崩溃、HTTP 请求、UI 线程卡顿等,未来会更多。报告简洁但不简单,展示的是一个个 “问题”,而不是 “CPU 使用率” 这种统计量,Appetizer 报告每个问题可以定位到源代码中某个/些函数。

特色与效果

  • 测量逻辑和业务逻辑分离: Appetizer 提供测量点和测量方法,测量与业务低耦合。Appetizer 独立升级,服务升级带来更广的测量面。
  • 测量全面:APP 代码与库代码
  • 部署方便:测量代码与 APP 同进程,同权限,不需要搞 Root,HTTP 代理等等
  • 结合自动化遍历,夜间长时间自动遍历,找到的稳定性问题自动由质量监控捕获,上报完整、专业
  • 结合 UI 自动化测试,评测 APP 性能、HTTP 延时等性能问题
  • 低性能影响:log 到本地,控制 log 频率,数据量,以及 log 方式,对 APP 流畅性无影响
  • 效果实例:

怎么用

下载 Appetizer Desktop

  • https://appetizer.io 主页下载 Appetizer 确保使用的是最新版
  • 到注册 Appetizer 账号后登陆客户端,或者用 Github 直接登录客户端
  • 确认 Android SDK 正确安装, adb 在 PATH 里
  • 连接手机,启动 Appetizer,“设备管理” 中应该能正常看到设备
  • 更多 Appetizer Desktop 基本介绍,请戳:https://testerhome.com/topics/6284

Appetizer 质量监控的流程图如下:

插桩

  • 到 “质量监控” 界面选择 “插桩 APK 文件”,会提示要上传 APK,选择 APK 后等待,视 APK 文件大小可能需要 1-5 分钟,
    • 插桩后的 APK 是使用我们服务器上的开发签名重新签名的,如果有需要用自己的签名重签,TesterHome 上关于这个的很多,例如:https://testerhome.com/topics/3027 我们建议直接用原生的 jarsigner 进行重新签名

测试

  • 插桩后的 APK 就可以开始测试了,注意安装到设备后要确认 APP 有读写 SDCARD 的权限,绝大多数机型可以通过 adb 进行命令行授权,MIUI 不行,需要到设置去授权
  • 如果是使用 Appetizer 的多设备测试的(基于屏幕重放的),请参考这里:https://testerhome.com/topics/7168
  • Appetizer 可以配合其他 UI 自动化框架使用,只要确保安装的是插桩包,并且有 SD 卡读写权限即可

分析与报告

  • 测试完成后,关闭 APP,来到 Appetizer 的质量监控界面的第三步

  • 分析完成后可以在我的历史报告界面看到最新的报告,点击打开,左边是问题分类,没有的不会显示,主要有

    • 未解决:未解决的所有问题
    • 已解决和关注可以通过问题行前方的两个图标标记,暂时不保存到磁盘,只是用于看的时候分类
    • 崩溃报告包含 Java 异常、ANR 导致的程序崩溃
    • 性能问题目前主要包括耗时操作,也就是会造成主线程卡顿的函数调用
    • HTTP 请求包括成功的(2xx),错误 (4xx 5xx),缓存的(3xx),高延时以及可缓存的,有饼图展示比例
  • 具体每一个问题都有细节信息,点击查看

    • 崩溃问题中如果是 Java 异常,会包含标准的堆栈位置;如果是 ANR 则会包含所有的线程的堆栈;崩溃时内存和存储使用情况在最下方
    • 耗时操作会指向某个在主线程上运行长时间的函数,会造成 UI 卡顿,详细信息中有堆栈信息
    • HTTP 请求会包括所有信息 + 使用的 API 方式,目前支持 java.net,Apache 和 Okhttp3,有问题的部分(比如延时会标记红色),可以查看原始的信息。同样,有问题的请求会携带堆栈信息

怎么集成

我们提供了Python 命令行工具用于集成,功能与图形界面一样,使用流程:

  • 将待测试的 apk 上传到服务端进行插桩
  • 下载插桩后的 apk
  • 安装插桩后的应用,授权,进行测试流程(自动化测试,人工测试都可以),log 会存在手机本地
  • 将设备通过 USB 连接到开发机,并使用本客户端将 log 上传至服务端进行分析
  • 通过Appetizer Desktop >= 1.2.0 进行可视化查看报告

插桩和分析包括

  • 应用崩溃(Crash)的原因和崩溃时的状态
  • 所有线程抛出的异常(即使不会造成崩溃)
  • 应用未响应(ANR)的状态
  • HTTP 请求以及回复的详细信息,包含以下库的 API(更多库支持正在添加)
    • okhttp3
    • retrofit(基于 okhttp3 的)
    • apache http
    • urlconnection
    • volley
  • 主线程卡顿(图片问题,回调问题等)
  • 界面切换耗时
  • CPU 占用率和 heap 占用大小

环境要求

  • Python 2.7.x 3.3+
  • node >= 0.10.4
  • adb 已经安装并已经添加到环境变量 PATH 中
  • 支持 Windows, MacOS, Linux
  • APK 文件名尽量用英文,APP 本身状态、字符串等可以有中文

用法

安装依赖

python -m pip install -r requirements.txt

帮助

python insights.py -h

确认不会有错误即依赖安装正确

login: 登录账号

python insights.py login username password

所有客户端操作均需要登录认证,执行登录后登录用 token 保存在当前 .access_token 文件。token 默认 60 天有效,使用任意操作会自动续期。60 天后 token 过期需要重新登录。

账号可在 Appetizer.io 注册。

插桩 apk

python insights.py process apk processed_apk

例如

python insights.py process my.apk my_processed.apk 

插桩需要上传、处理、下载,需要一定时间,依据网络情况与 APK 大小不同大致在 1 分钟-3 分钟内,期间会有输出表示进展情况。

安装插桩后的 APK 并授权

python insights.py install my_processed.apk -s serialno1 -s serialno2
  • my_processed.apk 是插桩后的 apk
  • -s是可选参数, serialno1 serialno2 之类的是设备的串号,通过 adb devices 获得,需要安装到多个设备可以用多个-s命令指定设备; 不提供任何-s命令时,默认认为只有一个设备并对该设备进行安装
  • 安装后会自动授权 log(小米无法自动化授权,建议在安装完成后授权读写 SDCARD)

测试

Appetizer 质量监控客户端对测试没有特别限制,可以是简单的人工测试,也可以是复杂的回归测试,测试长度不限。插桩后的 APK 会自动 log

上传 log 获取分析报告

python insights.py analyze my_processed.apk -s serialno1 -s serialno2 --clear
  • -s是可选参数, serialno1 serialno2 之类的是设备的串号,通过 adb devices 获得,需要分析多个设备上的 log 可以用多个-s命令指定设备; 不提供任何-s命令时,默认认为只有一个设备并对该设备进行分析
  • --clear是可选参数,用于从设备下载 log 后将设备上 log 清空
  • 分析成功后可以通过Appetizer Desktop >= 1.2.0 查看

其他功能

python insights.py clearlog my_processed.apk -s serialno1 -s serialno2 --clear

将设备上有指定插桩后的 APK 的 log 清除

常见问答

  • 加固后的 APK 可以吗?混淆呢?
    • 不支持加固,考虑上传加固前的版本,如果有安全性考虑请联系商务合作;混淆的 APK 可以,但是会影响效果,例如用了 okhttp 库,混淆后 okhttp 库被改了,那么通过 okhttp 的 HTTP 请求就捕捉不到了;同样有安全性考虑请联系合作。
  • 质量监控是开发包还是发行包
    • 目前为开发包,在开发设备上;发行包插桩技术上可行,但需要裁剪,有具体需求请邮件联系
  • 手游支持吗?
    • 部分支持,注入只处理 native Java 层的问题,框架托管的代码,比如 Unity 的 C# 没有插桩
  • 支持混合 APP 吗?
    • 支持 ReactNative, Weex 开发的 APP,虽然 H5 代码不会插桩,但是转换成 native 后,或者从 native 层触发的操作(例如网络)都能正常捕获
    • Cordova 支持有限,WebView 内的功能正在研发中
  • 采集的数据是否公开?
    • Appetizer 图形化界面可视化的部分只是收集到的数据的一部分,总体的数据类似时间轴图,JSON 格式,可来邮件详询数据格式以及需求对接
  • 设备 log 能否通过 WiFi 传到服务器分析
    • 开发中,之后版本将开放 SDK,可以在 APP 里面布置一个按钮/Broadcast Receiver 一键上传 log,然后电脑端看
  • 是否可以定制化插桩点,定制化数据收集
    • 技术上可行,等待 SDK,请来信提供需求

联系与合作

  • Email: contact@appetizer.io
  • 合作请注明公司/个人,标题请以 “[Appetizer 合作]” 开头,请仔细说明需求,告知 APP 的基本情况(比如用了什么框架,混淆,加固等),非诚勿扰
  • 总体来说我们希望大家多提供需求,我们可以将一些计划优先处理
  • QQ 群:467889502
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 30 条回复 时间 点赞

我在 mac OS 上打开提示:“Appetizer” 因为出现问题而无法打开。
操作系统版本:10.12.4

露重烟轻 回复

刚才 CDN 抽风了,请再下载一次: http://dl.appetizer.io/Appetizer-1.1.0-darwin-x64.zip?v=1

AppetizerIO 回复

谢谢,已经好了

匿名 #4 · 2017年03月31日

点击用 github 登录的按钮,并且用 github 账号成功登录后,卡在 Authorize application 界面,Authorize application 的按钮是灰色的,无法点击,页面也没有跳转

匿名 #5 · 2017年03月31日

进去了,但是插桩 apk 的时候提示 The access token provided is invalid

Github 登录后第一次插桩会有问题,重启一下客户端插桩就可以了,下个版本修复

你怎么进去的?我也是卡在这里了

lovoro 回复

github 授权很慢,我们阿里云服务器连 Github 灰常慢,会卡一会,还有问题的话加群发个截图

AppetizerIO 回复

授权按钮一直灰色

lovoro 回复

重启下客户端用普通账号试试?

基于 class 文件字节码修改的 AOP 实现,赞

AppetizerIO Appetizer 移动开发智能化平台发布 中提及了此贴 04月01日 13:38
AppetizerIO Appetizer 移动开发智能化平台发布 中提及了此贴 04月01日 13:40
Fresh 回复

感谢专业的评价

镜像操作不支持物理按键,例如 back

你好,我插桩 APK,提示服务器拒绝了插桩请求,是什么原因

@object 重启下客户端,这个 bug 已经修复,1.1.1 发布就好了

show88118 回复

这块兼容性适配需要花挺多时间,在慢慢加

@appetizer.io 我插桩 apk 下载到本地后,打开 app 就崩溃了

准备找个时间实践下,不过还是给楼主点赞

大鸟 回复

试试最新的 1.1.1 版?后端我们也在持续更新,还有问题的话可以加群详细讨论😃

为什么我在质量监控里查看报告,无法生成的文件报告呢。

刘刘刘 回复

前面插桩等流程都成功了吗?加群讨论吧

大赞,要是能够对其它工具生成的测试 LOG 进行分析就好了

邓琳 回复

之后版本会接入其他 sdk 的数据,敬请期待


为什么启动客户端先提示 token 失效 然后跳转这个 也没有登录相关的控件啊

释放双手,放飞自我

插桩后的 apk 能被成功安装,但是打开 app 就 crash。
不知是客户端问题还是插桩的缘故。

MJW 回复

加 QQ 群,闪退问题直接按照这个格式上报:
https://github.com/appetizerio/insights.py/wiki/Issue-Reporting

老马 Appetizer 整合梳理 中提及了此贴 09月27日 17:06
AppetizerIO [该话题已被删除] 中提及了此贴 01月03日 14:51
AppetizerIO 优化 APP 网络流量 中提及了此贴 01月03日 15:04

非常帮~!~

为啥我的 app 打开提示无网络链接,我是有 WiFi,流量的,同时,软件也是授予权限的,

加固之后的 APP 可以插桩吗?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册