一、背景
在文章云音乐曙光埋点:还原数据理想国中,我们介绍了曙光埋点项目方案,该方案基于多端一致埋点对象树建设管理,实现了统一自动化埋点和链路追踪,方案高度还原了大前端埋点的理想状态、具备较强通用性和扩展性。我们围绕这套埋点方案研发了配套的埋点管理系统,以承载及埋点规则数据管理、埋点设计、埋点研发、埋点测试、埋点上线等功能,本文主要介绍该平台功能及建设思路。
二、平台现状介绍
经过前几期建设,我们已经实现了一个适配研发流程的、按版本来管理的埋点数据管理平台,其核心功能为:
1、承载埋点研发生命周期
2、承载埋点的元数据管理
我们的研发生命周期如下:
平台在埋点元数据管理设计如下,参考和学习了版本管理工具的功能,并且充分考虑了客户端的研发流程特点
1、客户端每个大版本需求研发时,BI对埋点需求进行分类,建立需求组。可以理解为基于Master CheckOut出了多个分支。
2、BI在各需求组内,按埋点需求设计埋点。设计完成后,平台会计算出埋点的变更列表,如新增对象、新增血缘关系、修改参数、删除对象、删除血缘关系。
3、上述变更由BI指派到任务,交由开发处理
4、经过一个版本迭代开发后,若任务开发测试完成处于可上线状态,会被打上版本的TAG,并且发布上线,在Master产生一个新版本;未完成的任务,则可在后续版本迭代开发完毕后再上线。
相比版本控制工具,适配研发流程的版本控制具有以下特点:
1、支持部分变更上线:需求内的变更可以*筛选出来部分上线,可以类比为分支内提交数个文件,可以筛选出几个文件单独合入Master
2、需要走研发流程才可上线:每个埋点变更都拥有独立的研发流程控制和校验。这些流程(设计完成->开发->测试通过)需要走完后,才准许合入Master。
3、模型更加复杂:不是简单的文本,而是复杂的层级对象结构。
三、我们遇到的问题和痛点
在上述研发流程模式的落地过程中,我们发现了以下问题和痛点:
1、落地质量问题
漏埋:因为涉及较多埋点事件、埋点参数的组合,在某些组合下,埋点没有上报。
错埋:埋点参数缺失或格式不正确。
归因错误:埋点里的归因字段设置错误、不合理。
2、落地效率问题
大量重复埋点代码编写:如果涉及大量对象埋点,埋点工作势必成为大量重复劳动,影响研发效率。
埋点进行增量变更时,无法知道改动了什么:平台只展示了某个埋点全量信息,并未展示其增量改动(没有类似版本管理工具的Compare视图)。
3、功能痛点
有一些埋点长期停留在研发阶段未上线(类比于写代码时开发分支落后Master多次提交,没有去Pull Master获取最新的主线代码改动),导致这些埋点很可能是过时的,如果不进行卡点直接上线,就会导致问题
埋点数据是按APP+端两个维度隔离的,但实际运用时存在内嵌情况,如APP端可内嵌WEB端H5页面的功能,这种情况下,需要把原本隔离的数据进行整合,如把部分WEB埋点树挂载在APP端树上。
针对以上问题痛点,平台在近半年内进行了针对性的解决。
四、埋点质量建设
解决该问题的思路为先解决源头防止增量质量问题产生,再解决存量质量问题。
1、建设实时埋点校验功能,从源头解决埋点质量问题
客户端埋点开发完成后,需要进行"实时校验",从而对被指派的埋点任务进行测试覆盖,其步骤如下:
客户端连接到实时校验平台,平台根据该任务需求,生成埋点校验树
客户端上报日志,平台根据埋点校验树进行校验
平台根据测试情况,决定测试是否通过
需求范围内有埋错:不通过,且可以查看日志看到具体为何不通过,如下图所示
需求范围内有漏埋:默认不通过,但事实推进落地中,存在部分分支客户端难以复现覆盖的情况,因此我们也支持了勾选某些分支无需测试的功能,如下图所示
若测试为不通过,则将卡点阻塞流程,后续无法正常上线
经过实时埋点校验功能的上线后,我们封堵住了大部分埋点错误源头,达到了较好效果。
2、建设线上埋点稽查功能,发现存量埋点问题并推进解决
稽查功能定位为企业日志的统计分析,解决以下问题:
1、分析日志是否按规则正确输出,检测出少参数、参数取值错误、归因错误等问题,并对这类问题进行归类,并可进一步钻取,直至能够看到原始日志的样本。
2、自定义灵活业务统计监控、报表、报警。通过监控、报表中数值变化报警来发现、辅助定位端上发版后一些bug。如:某些点位日志变少、PV/UV比例变化等。
为实现上述功能,需要对日志进行采样分析计算(可以理解为打上各种标签),并且将计算结果存储在能够支持筛选、统计查询功能的数据库中,为典型的OLAP场景,我们选型时,采用了ClickHouse来完成这块功能,其主要考量点如下图所示
经过稽查功能上线和推进,我们的线上埋点错误数已经下降了95%,并且还在逐渐降低中,达到了较好的效果。
五、埋点效率建设
使用模版引擎自动生成代码 上文提到,埋点时涉及大量重复埋点代码编写,我们针对该问题使用模版引擎语言自动生成埋点代码,且支持适配了安卓、iPhone、Web、RN等多套客户端,把代码提前生成好,能自动填写的部分全部自动填写,客户端复制代码后只需要把代码模版里剩余部分补全即可,如下图所示
展示埋点DIFF,让开发更容易理解埋点改动点
我们开发了埋点DIFF功能,相比与版本管理软件中的代码文本对比,埋点元数据是一种更加复杂的数据结构,因此在服务端计算DIFF和前端界面展示DIFF上相对来说较复杂一些。如下图所示,我们通过在原有界面上通过背景色来区分变更操作是新增、修改、还是删除。
六、研发中埋点自动Rebase到最新Master
前文提到,有一些埋点长期停留在研发阶段未上线,目前没有pull master的功能,导致:
1、这些未上线埋点元数据很可能是过时的,如果直接上线会导致业务问题。
2、无法使用到最新Master下的新增对象,或者还在使用已删除对象
因此我们对在需求池内未上线的研发阶段对象,每次上线后,都自动pull master处理。如下图所示为一个未上线需求从安卓8.8.11 Rebase到 安卓8.8.12的过程,rebase后可能存在部分变更需要删除或重新研发。
rebase算法的核心在于计算出Master和本研发分支对比同一个基线的原子改动列表,并尝试依次合并,并将合并后的变更应用到基线上。其流程图如下:
其中变更合并时的逻辑如下:
人工冲突解决时,我们采用了上文“展示埋点DIFF”的功能,让埋点设计人员同时看到两方改动,并在界面中录入最终合并结果。
七、埋点跨空间打通
云音乐业务存在多个业务线,他们的“埋点空间”是相互独立的。但云音乐存在内嵌业务的情况,如云音乐APP下可内嵌LOOK直播APP、以及WEB端的H5页面等,即使云音乐APP不发版,内嵌的业务的埋点也可能会发生变化。因此需要把内嵌业务对应的的埋点树“桥接”到当前APP埋点中。针对这种诉求,我们研发了“桥梁”模式,如下图所示:
桥梁为一类特殊对象,用于衔接父子空间,如图示为衔接云音乐APP和WEB H5两个独立的埋点空间,其中云音乐APP是父空间,WEB为子空间
桥梁在父空间定义
子空间对象可设置挂载在父空间桥梁下
父空间展示埋点树时,只关心到桥梁为止
子空间展示埋点树时,会把桥梁以上所挂载的父空间树也展示出来
内嵌开发完毕后,需要使用父空间APP验证子空间的带桥梁埋点是否正确,其SPM为带父空间的完整路径
此外由于埋点按版本管理,因此埋点树若变化,必须要在平台内产生新版本,因此:
子空间发布,父空间不需要发布新版本,因为子空间埋点树对父空间不可见
父空间发布,若涉及桥梁更改,则会改变子空间埋点树,此时需要在子空间同步发布一个新版本
八、未来规划
在埋点领域中,除了纯客户端埋点,还有服务端埋点,以及双端共同完成的混合埋点,常见的混合埋点包括:
服务端下发的字段,客户端需要打到客户端埋点里
客户端上报的字段,服务端需要打到服务端埋点里
此类需求广泛存在,但未在本平台上进行管控,其流程、效率、效果是不可控、不可监控的,后续平台将把服务端埋点及服务端+客户端混合埋点也平台产品化并进行管控。
此外,网易云音乐全链路埋点管理平台前后端、客户端SDK等组件都将在近期贡献到开源社区,为业界带来更大价值。