自动打点Android客户设计文档

1.自动打点简介

之前的打点功能是开发人员手动写代码打点,开发人员需要在每个页面对点位数据进行处理,工作量和沟通成本大。 在此推出自动打点系统Savior,Savior和之前最明显的区别是打点操作不需要开发人员手动操作,数据需求人员和业务开发人员无需沟通,做到参数透传配置化,参数透传清除配置化,减少开发工作量,实现点位的精确有效计算。 做到埋点自动化或部分自动化,埋点集中管理,代码解耦以及埋点热部署,动态推送。

1.1 目标

a. 业务人员零工作量,配置工作交给数据方。
b. 随时更新、热部署,从 日期/版本/渠道/地域 等多维度按需获取数据。
c. 全平台联合统计,提供数据完整性保障。
d. 集成 app 稳定性数据。

1.2解决的问题

► 埋点混乱
► 数据团队和业务工程团队的配合问题
► 大量不可控数据对服务器造成的压力

1.3 统计内容

统计数据包括但不限于设备数据、用户数据、用户行为数据。

设备数据:机型、系统版本、IP、网络、分辨率,etc..
用户数据:用户ID、app 列表、网络状态、位置,etc..
用户行为数据:行为漏斗、PV/UV、停留时长、启动/结束页面,etc..

1.4 前端日志量评估

根据现有MVT打点文档评估出目前日志埋点覆盖页面、元素的程度,其中APP覆盖度为50%,H5、微信、手Q覆盖程度30%,PC目前没有打点。

APP日活用户30万左右,微信日活用户40万左右,每天总日志条数5000万左右,依照现有情况评估,新日志的前端日志量会上升3~5倍,预估每天平均日志条数在1.5亿~2.5亿,如遇到节假日高峰流量翻倍,峰值每天日志条数会在3亿~5亿

2.自动打点架构总览

Savior Framework包含了三个子模块,分别是注入框架、无痕点位处理模块和配置同步模块。
Local Cache通过三个队列对数据进行存储,分别存储设备数据、命中点位数据和未命中点位数据。三个队列分别加入缓存功能,数据存储在本地sqlite。
Savior Web Interface通过DataBaseTask将数据上传。

客户端自动打点包括 配置, 收集, 配置同步, 数据上传四个步骤
其中配置是由数据人员通过加装了“打点配置”功能的正常客户端添加点位信息。用户在客户端中可以操作选择界面需要打点的按钮,然后进行点位配置。当用户配置完成后,点击提交。
配置提交后,Savior Framework就可以将用户原始点击数据和点位进行融合操作,进行配置同步,并将同步处理后的数据上传。

3.设计方案

3.1.配置

用户在需要打点的页面摇一摇手机即可以唤起打点页面(可演示)。当唤起打点页面后界面会锁定,此时移动手指,即可以选择需要打点的按钮区域。选定后再摇一摇可以唤起打点的配置界面,在界面中配置提交(必须登陆,若未登录需登陆)既可以上传配置。注意,此处不需要注册界面。注册功能由后端统一配置。
综上描述,配置模块有三个功能:

打点选择功能

选择框,选择确认打印,信息打印(包括id,view的路径,view包含的文本,view的打印)

点位配置界面

填写IF值,OF值,CH值,INFO值,提交按钮。

登陆界面

登陆按钮,用户名,用户密码。

3.2.收集

用户打点采用全采集的方式,即是采集客户端所有点击响应的事件。并上传用户的全量点击信息。

绑定在艺龙旅行(或者艺龙酒店,艺龙出行等)产品线中的自动收集功能。会收集并上传用户所有的点击操作。

  • 首启日至 通用性数据仅首次上传
  • traceID 配合 DeviceID 串连用户行为
  • 时间同步 统一行为记录时间

配置表 (XPath - 配置信息) 更新配置表,实时添加新点位

Savior自动采集一些用户行为,开发者可以通过enableAutoTrack 接口打开自动采集:

Savior.sharedInstance(context).enableAutoTrack();  

打开 Auto Track 后,会开始采集事件。 上传策略是wifi环境直接上传,非wifi环境将数据记录到本地,然后在wifi环境再统一上传。

注入具体实现方案

由于Android系统对各种视图的点击事件处理差异性较大,不同系统版本的处理也不尽相同,收集方案的设计同时要兼顾Android插件化设计对系统的影响。在对比各种自动打点文案之后,在不影响业务开发的前提下,为了追求更高的自动打点效率,收集实现文案最终选择注入框架。
在打包过程中,通过动态代理hook打包进程,然后通过打包进程表态hook classToDex进程,拦截class转Dex,通过javassist修改字节码,查找所有实现onClickListener的View类,在setOnClickListener方法中注入TracelessDot中带点位统计的点击事件。

定位方法

/com.elong.myelong/FrameLayout/LinearLayout/LinearLayout[0]/Button[2]/id-testDynamicAdd

构造path格式: /包名/页面类/控件的容器路径/id

版本管理

  • 无线的特点多版本同时在线,支持区分版本
  • 以app/页面/控件为维度管理埋点配置信息

问题和难点

1.Android版本碎片化,不同版本会造成控件的UI路径不同。比如Android2.2与Android4.1版本下,获取到上文中Button的UI路径分别为:

//android2.2
DecorView>FrameLayout[1]>RelativeLayout[0]>Button[0]  
//android4.1
DecorView>LinearLayout[0]>FrameLayout[1]>RelativeLayout[0]>Button[0]  

2.对一些隐藏控件、弹出窗口或者浮动窗口等需要定制的点位,进行手动打点(需要设计上手动打点的功能)。

3.3.配置同步

配置同步主要是为了将收集到的点位与配置信息进行匹配计算,处理日至信息在本地的整个生命周期。配置同步模块主要分为三个子模块:

  • 点位命中模块 主动从服务器拉取点位配置,与用户行为点位进行匹配。
  • 日志处理算法模块 日志处理策略类,保证日志不会大量滞留本地,同时避免频繁的日志上传网络访问。
  • 日志缓存模块 对日志进行本地持久管理,确保日志完整性。使用第三方ORM框架,提升数据读写速度和数据库安全。

APP统计数据的处理核心,Savior提供一个全局实例和APP里的初始化方法,同时维护EventQueue和ConnectionQueue两个事件队列。其中EventQueue维护自定义(如激活,埋点,出错)事件的记录和发送,ConnectionQueue维护APP的打开,关闭,停留时间计算等常规数据记录。

Savior的配置同步是通过Timer进行定时定量批处理。将日志上传到服务器,成功后并通知本地进行日志删除,采用android统一的网络框架。

当需要统计时,将收集的所有点击和配置进行数据匹配,将命中和未命中的数据分别管理、上传。

当前采集的是用户的全量操作信息。如果在分析的时候,发现有数据出不来,就说明配置的数据和收集的数据对不上,此时还能从配置这一块进行补救。

Task进行配置同步命中,然后存往不同的库中,Savior通过Timer将两个Queue中的数据定时发往Server。EventQueue和ConnectionQueue同时带有本地存储功能(无需SD卡),在网络发送成功时清除本地数据库记录数据。
上传时使用Post方法,每次批量上传全部记录。如果上传不成功(网络异常),则本地缓存记录数据超过一定数量(100)后,会清除较早的一半数据。

未命中数据处理 如果打点的view没有ID,是不能确认view的唯一性的(通俗的说此点位打不上)。必须联系对应页面的负责人,并让他将ID加上。

3.4 网络上传机制

将日志上传到服务器,成功后并通知本地进行日志删除,采用android统一的网络框架。
将存储在本地的点击行为数据定时定量的按命中情况进行上传,需考虑用户流量,并在不同的网络环境下的上传机制,以及上传成功率及脏数据处理。
Savior自动打点日志收集系维护一个阻塞性日志收集队列,不断接收业务线产生的日志。日志分发组件不断从日志队列获取日志,并传给日志收集中心。当日志收集达到一定阈值后,将收集组件日志日志转移到日志发送中心,并触发日志发送。如果发送成功,则从发送中心删除对应的本地日志,否则进行重试。
系统的特性:
可用性:日志收集系统稳定收集用户日志,线上Android丢失率在5%以下。
可扩展:采用面向接口编程,各模块达到组件化。
下面为上图虚线框的详细过程。

4.自检系统

当数据方做完打点配置后,需要自行将打的点位全部遍历点击一遍。然后在后端将数据融合后,查看自己的打点操作是否能成功记录。

5.针对全链路日志平台确认android字段规范

  1. 首次开启时发送
    dt: 写死android
    md: 有
    bs: 有
    mac: 有
    osv: 有
    tsp: 有
    applist: 有

  2. 每条必打字段
    ct: 写死app
    appv: 程序配置写死
    version: 有
    cip:有
    location: 有
    coord_type: 写死
    nt: 有

  3. 扩展字段规范
    elementtype: 配置的时候写死(打点用户来操作)
    element
    id: 包名+页面名称+view路径+ID

1.首次开启时发送

此处包含的字段为设备静态属性或缓慢变化数据,只需用户首次开启APP时记录,以缩减日志冗余。

字段名称 中文解释 枚举值说明
dt 设备类型 1:iphone,2:ipad,3:android,5:winphone,7:pc,8:androidpad,99:未知
md 设备品牌型号
bs 屏幕分辨率 例:1920*1080
mac mac地址 例:02:e6:50:26:e3:3c
osv 系统版本 例:andorid5.5.1
tsp 运营商 cm:移动,cu:联通,ct:电信
applist 安装的应用 例:[‘微信’,’QQ’]

2.每条必打字段

字段名称 中文解释 枚举值说明
ct 端类型 1:app,2:浏览器,3:微信,4:手机QQ
appv app类型 1:艺龙旅行,2:艺龙酒店,5:艺龙pro,99:艺龙有房
version 版本 例:app:9.21.0
cip 用户IP
location 用户经纬度
coord_type 坐标系类型 1: GPS坐标, 2: sogou经纬度, 3: baidu经纬度, 4: mapbar经纬度, 5: 腾讯、google、高德坐标, 6: sogou墨卡托
nt 网络类型 wifi,2g,3g,4g
3.扩展字段规范(properties)

作为扩展字段,其主要目的是为了方便后期不同场景的个性化属性扩展,但对于常见字段,请参照如下规范

字段名称 中文解释 枚举值说明
element_type 元素类型 button:按钮,banner:轮播banner,filter:筛选框,map:键值对,list:列表
position 页面内位置 点击:记录对应点的位置(10,80)
element_id 元素ID 保证全局唯一即可

张鹏宇

继续阅读此作者的更多文章