扫盲—关于埋点那些事儿
要监测网站上或app上的用户行为,需要在网站的每一页或者app上加入一些程序代码,这些代码在网页上叫检测代码,在app上叫SDK。要监测就必须加入这些代码,否则就收集不到数据。
不管是埋点还是不埋点,要想在网页或APP上监测用户数据,必须加入监测代码。这些监测代码叫基础代码。要想监测所有的用户行为数据,光有基础代码是不够的。
不能被基础代码监测的用户行为,统称为事件(Event)。
事件的定义:
- 网页:非http类型的交互,JavaScript的、Flash的、Silverlight的、AJAX的、各种页面插件的交互等
- APP:包含用户点击在内的所有交互
简单理解:
凡是遵循http协议的交互,都可以使用基础代码监测到数据,非http协议的交互,基础代码都无能为力。
每一个需要我们监测的event互动,都被称为一个“监测点”,你可以想象,web上的监测点不会特别多(因为大部分都是http互动,所以基础代码能搞定),而app上则布满了监测点。为了让这些监测点上的用户互动行为数据被我们收集到,我们必须在这些监测点上部署上专用的事件监测代码(即event tracking code),这些代码需要手工一个一个添加在想要获取数据的监测点上。这个过程被形象化的称为埋点。埋点只有在基础代码工作的情况下才能发挥作用。并且各家数据监测工具的基础代码只能用它们自家的event监测。这意味着,你想用Google Analytics的事件监测,前提是你必须已经在页面上部署好了Google Analytics基础监测代码(被称为GATC,Google Analytics Tracking Code),不能不部署基础代码,也不能部署别家的基础代码。
埋点理解
- 又称为事件追踪(Event Tracking),是数据采集领域(尤其是用户行为数据采集领域)的术语,指的是针对特定用户行为或事件进行捕获,处理和发送的相关技术及其实施过程。——可以结合5W2H:谁在什么时间什么地点通过什么方式做了什么事情,花了多少时间等。
- 当需要关注的事件发生时进行判断和捕获,然后获取必要的上下文信息,最后将信息整理后发送至服务器端。所监听的事件,通常由操作系统、浏览器、APP框架等平台提供,也可以在基础事件之上进行触发条件的自定义(如点击某一个特定按钮)。一般情况下,埋点可以通过监测分析工具提供的SDK来进行编程实现。
功能
收集用户行为数据,埋点埋什么取决于我们想从用户身上获取那些数据信息。一般包括用户基本属性信息和用户行为信息。
- 基本属性信息:城市、地址、年龄、性别、经纬度、账号类型、运营商、网络、设备等
- 行为信息:用户的点击行为和浏览行为,在什么时间,哪个用户点击了哪个按钮,浏览了哪个页面,浏览时长等的数据
实现方式
在某个页面或某个按钮植入一段代码,监听用户的行为并收集上报
第二步【数据传输】:传输埋点收集到数据
1.实时传输:flume>kafka>db
2.离线批量传输:jdbc>db
第三步【数据存储】:数据量较小选择mysql、Oracle等关系型数据库,数据量大则采用hive、hbase等分布式数据库
定义好数据存储的表结构,属性尽可能采集全面
第四步【数据统计】:根据业务需求进行etl开发,输出业务所需数据
第五步【数据应用】:业务人员验证和使用数据
1.埋点采集
需要提前规划埋点,数据采集的有效性决定了后续数据分析的可靠性
1.1 埋点范围
根据业务人员的需求,选取可以衡量需求效果的数据指标,比如页面浏览量,页面转化率,访问人数,访问频次分布等等。明确需要收集哪些维度的数据,按需选择性埋点。
1.2 埋点事件
我们可以对一条业务流程中涉及到的各种操作进行事件埋点,用于了解该业务各操作流程的用户流失率,转化率等情况。通常包括但不限于以下事件:
1.页面事件:用户访问页面的信息,比如可以通过页面埋点统计页面浏览量(PV),或收集该页面上的接口;
2.点击事件:用户在页面的点击行为,比如想要收集用户点击搜索按钮时,填入了哪些关键字,就可以在搜索按钮上埋一个点击事件,通过字段keywords上报的值实现分析关键字的目的;
1.3 采集内容
埋点时需要尽可能全面的采集数据,主要包括以下信息:
- 用户基本信息:描述用户的基本属性信息,包括用户ID,性别,运营商,设备类型等
- 时间信息:事件发生的时间
- 行为信息:用户做了哪些行为,比如点击行为,浏览行为等
- 行为对象信息:用户的行为作用在哪些对象上,比如点击按钮A,浏览页面B,那么A,B就是用户行为作用对象
- 另外,也可以从4w1h(who,when,where,what,how)五个维度来划分埋点属性
1.3 数据采集普遍遇到的问题
- 实时性,对于工具性产品在无网条件下的数据,无法实时上报;
- 完整性,由于用户隐私协议&欧盟通用数据保护条例的,部分数据无法采集;
- 异常,android_id、idfa、idfv 随版本升级变化或无法获取。
2. 数据存储
数据从上报开始——Nginx——Filebeat——Kafka——Spark——Kudu
2.1 存储方式
根据埋点数据量和现有平台选择一种最合适的存储方式。
【Mysql】: 使用于数据量较小,优点读写方便
【ES】:现有埋点方案中,阿里日志系统,通过ES查询埋点结果
【Hbase】:适合数据量较大,可考虑使用现有hbase集群。
数据写入方式:中间件 or 直接写入?
2.2 存储频率
- 采用【定时】+【定量】的方式,保证数据时效性和数据平滑处理。
- 定时:周期触发,进行存储。避免当数据量较小时很长一段时间不存储。
- 定量:设置阈值,当数据量达到一定量(1k)即进行存储
- 程序退出:某用户退出登录时,需立马进行存储
3. 埋点方法
3.1 代码埋点
在网页或APP上添加代码,当用户触发相应行为时收集数据并上报,网站上的代码称为监测代码,APP上的称为SDK。市面上第三方数据采集均支持代码埋点,如GA, GrowingIO,神策等
- 优点:可以详细的设置某一个事件自定义属性;
- 缺点:时间、人力成本大,数据传输的时效性。
3.2 可视化埋点
利用可视化交互手段,数据产品/数据分析师可以通过可视化界面(管理后台连接设备) 配置事件,如下是腾讯移动分析的可视化埋点界面。可视化埋点仍需要先配置相关事件,再采集。
- 优点:埋点只需业务同学接入,无需开发支持;
- 缺点:仅支持客户端行为。
3.3 无埋点
- 无埋点是指开发人员集成采集 SDK 后,SDK 便直接开始捕捉和监测用户在应用里的所有行为,并全部上报,不需要开发人员添加额外代码。
- 不再使用笨拙的采集代码编程来定义行为采集的触发条件和后续行为,而是通过后端配置或前端可视化圈选等方式来完成关键事件的定义和捕获,可以大幅提升埋点工作的效率和易用性。在“无埋点”的场景下,数据监测工具一般倾向于在监测时捕获和发送尽可能多的事件和信息,而在数据处理后端进行触发条件匹配和统计计算等工作,以较好地支持关注点变更和历史数据回溯。当然,即便是“无埋点”技术,也仍然需要部署数据采集基础SDK(又称基础代码)。
- 数据分析师/数据产品 通过管理后台的圈选功能来选出自己关注的用户行为,并给出事件命名。之后就可以结合时间属性、用户属性、事件进行分析了。所以无埋点并不是真的不用埋点了。目前市场第三方工具GrowingIO支持无埋点全量行为数据抓取
优点: - 无需开发,业务人员埋点即可;
- 支持先上报数据,后进行埋点。
无埋点和可视化埋点均不需要开发支持,仅数据业务同学进行设置即可。但两者数据上报-埋点设置存在加大的差异:无埋点支持在数据上报之后再进行埋点设置,因而数据采集/上报的量远大于可视化埋点。
3.4 对比
image.png image.png4. 埋点场景&埋点建议
- 客户端数据:页面点击数据,比如:tab栏的点击,某个icon的点击(各入口点击对比使用情况,统计页面点击行为的转化漏斗)。
- 服务端数据:安装数据,下载后安装情况;内容数据,比如某个视频内容 曝光/展示/播放数据;搜索内容。
5.其他
5.1 前端埋点or后端埋点
比如像点击、浏览、曝光这些行为便可以用前端埋点,主要是发生在用户与界面的交互;如果是电商中要统计下单成功这个事件,客户端是没有办法知道订单是否成功的。如果统计的事件里有需要用到后端的数据,也是要进行后端埋点的。
5.2 埋点事件的格式
埋点数据是需要存储起来的,数据就会有它对应的字段。一般一条埋点数据需要记录:事件ID、事件名(英文名、中文解释)、事件属性(属性英文名、中文解释、属性类型)、埋点形式(前端/后端)、事件触发时机(什么时候投递这个事件)
5.3 埋点报文
报文(message)是网络中交换与传输的数据单元,即站点一次性要发送的数据块。报文包含了将要发送的完整的数据信息,其长短很不一致,长度不限且可变。简单来说就是用户在App内有一个操作行为,就会上报一组带有数据的字段。这些字段组成一个报文。报文一般包含以下字段,简单举例,根据公司业务自行增删
{ "os": "js",
"os_vers": "端上的OS版本",
"dev_id": "设备id",
"model": "设备型号",
"manufacturer": "设备制造商",
"proj_id": "工程id",
"source": "渠道输入数字:1android_2ios_3H5_4小程序_5微信_6服务器后端_7QQ_100其它",
"proj_ver": "软件版本",
"up_time": "报文上传时间-毫秒时间戳",
"face_id": "事件全局唯一标识",
"accs_time": "事件发生时间,毫秒时间戳",
"serv_time": "服务器时间,毫秒时间戳",
"event_type": "view/click", "event_ver":"业务版本/事件版本
"ip": "290.39.55.75",
"longitude": "56°75.343",
"latitude": "143°07.230【非必填GPS关闭无法获取】",
"netwk_typ": "wifi/4G" },
"refer_id": "无埋点场景下所浏览页面的上一个页面的唯一标识",
"duration": "页面浏览毫秒数,关闭页面时统计",
"banner_id": "埋点自定义事件属性值",
"banner_name": "埋点自定义事件属性值",
"banner_type": "埋点自定义事件属性值",
"banner_city": "埋点自定义事件属性值" },
"usr_props": { "gid": "游客id", "uid": "登录账号", "province": ‘上海’】",
"city": "北京",
"city_code": "110",
"age": "22",
"sex": "1男_2女",
"phone": "13601197458",
解释一下这些报文的意思
- trace_id为每个事件的全局唯唯一识别符,trace_id=md5(proj_id+source+accs_time+"salt盐")
- proj_id为工程id,accs_time为端上行为时间
- source为渠道来源:1android_2ios_3H5_4微信小程序_5微信环境_6服务器后端(只填数字)
- 请求为post提交方式,header中需要添加:projId,source,upTime,uploadId 四个参数,uploadId=md5((projId+source+upTime+"salt盐")
- proj_id为设备id,upTime为上传时间
- source为渠道来源:1android_2ios_3H5_4微信小程序_5服务器后端(只填数字)
- 由于nginx中lua编程接收参数自身原因,header中的参数只能使用驼峰 projId,source,upTime,uploadId
- salt测试环境下为:test,salt正式环境下为:p1@PeFz4ZX
- uid值在游客状态下为空,登录状态下有值;dev_id值在任何情况下都得传
- 上面的报文为一次上报的报文格式,data中可以包括多次事件的信息
- 上面的报文为一次上报的报文格式,data中可以包括多次事件的信息
- 报文中的json的所有的key可以不能遗漏,即使是value为空,如果是空值要用双引号"",不要用null。
- proj_id、sdk_ver、event_id,业务属性,必须按照产品需求保证对应关系,否则上报的数据会被丢弃。