客户端埋点方案介绍

一、概念

构建一个数据平台,大体上包括数据采集、数据上报、数据存储、数据计算以及数据可视化展示等几个重要的环节。其中,数据采集与上报是整个流程中重要的一环,只有确保前端数据生产的全面、准确、及时,最终产生的数据结果才是可靠的、有价值的。

为了解决前端埋点的准确性、及时性、开发效率等问题,业内各家公司从不同角度,提出了多种技术方案,这些方案大体上可以归为三类:

1、代码埋点:在需要埋点的节点上,手动调用埋点方法,实现埋点数据的获取;

2、可视化埋点:通过可视化的方式配置采集节点并生成配置文件,客户端解析配置文件,在需要埋点的节点自动添加埋点代码,并上报埋点数据;

3、全埋点:客户端自动采集全部埋点数据并上报,通过可视化的方式查询埋点数据并显示;

二、介绍

1、代码埋点

在需要埋点的节点调用接口直接上传或者定时上传埋点数据,友盟、百度统计等第三方数据统计服务商大都采用这种方案;

1
2
3
4
5
6
7
8
9
10
11
12
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 业务代码
// ...
// 埋点上报
val properties = JSONObject()
properties.put("page", "MainActivity")
properties.put("type", "围棋")
TrackerManager.instance.commonTracker.onEvent("click", properties)
}
});

优点:使用灵活、方便设置自定义业务相关的属性

缺点:埋点成本高、更新成本高

2、可视化埋点

通过可视化工具配置采集节点,在前端自动解析配置并上报埋点数据,从而实现所谓的“无痕埋点”,代表方案是已经开源的Mixpanel

View标识

为了自动生成事件标识,我们需要获取每个控件自身的ID、类名以及位于所属父组件的Index等特征信息,并逐级向上遍历找到根节点。根节点一般是手动标记的,如果没有标记则默认是视图层次树的顶层节点。最后,将遍历产生的路径上所有节点的特征信息组合在一起,就是这个View的标识。

View标识

上面选中View的标识是:

ContentFrameLayout/ConstraintLayout[0]/AppCompatButton[0]#btClick

在同一个页面,View标识是唯一的,再加上页面名称和包名,就能够在当前App中唯一确定一个View对象,唯一确定View对象之后,就能够针对当前View进行埋点。

由于需求的改变,同一页面在不同版本肯能会发生变化,因此需要做容错处理。

可视化平台

可视化平台一般通过Web页面展示,客户端通过Socket与Web进行连接:

可视化流程

客户端打开APP之后,会从服务端拉取包含View标识的配置文件,就可以针对具体View进行埋点了。埋点信息的查询可通过与View标识关联的描述信息进行查询。

优点:开发、维护成本低;可以按需埋点,灵活性好;对业务代码侵入小

缺点:界面的结构发生变化时,圈选的待监测元素可能会失效;支持的控件和事件类型有限;无法灵活地收集到上下文属性

3、全埋点

它并不是真正的不需要埋点,而是前端自动采集全部事件并上报埋点数据,在后端数据计算时过滤出有用数据,代表方案是国内的GrowingIO。

基本原理:利用AOP,在预编译阶段实现在不修改源代码的情况下给所有的View点击事件的回调方法内部添加埋点信息。

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AspectJ

AspectJ是一个java实现的AOP框架,它能够对java代码进行AOP编译(一般在编译期进行),让java代码具有AspectJ的AOP功能,可以这样说AspectJ是目前实现AOP框架中最成熟,功能最丰富的语言,更幸运的是,AspectJ与java程序完全兼容,几乎是无缝关联,因此对于有java编程基础的工程师,上手和使用都非常容易。

下面我们以一个例子,来看一下如何对点击事件进行全埋点的:

1
2
3
4
5
6
7
@Aspect
class ViewAspectJ {
@After("execution(void android.view.View.OnClickListener.onClick(..)) && args(view)")
fun onViewClickAOP(view: View) {
TrackerManager.instance.viewTracker.onClick(view)
}
}

以上代码在编译后就会在工程中所有实现了OnClickListener接口的onClick方法内部插入以上代码,从而对View的点击事件进行全埋点。

数据查询

View事件埋点信息的搜集过程中同样会搜集当前View的标识,也通过可视化平台将View标识和事件描述信息进行关联,然后通过查询描述信息就能查询到View事件了,很方便。

优点:开发、维护成本低;可以追溯历史数据;对业务代码侵入小

缺点:高额流量和计算成本;无法灵活收集属性

SidXu wechat
联系作者