草庐IT

网易云音乐全链路埋点管理平台建设

ZYF 2023-03-28 原文

一、背景

在文章云音乐曙光埋点:还原数据理想国中,我们介绍了曙光埋点项目方案,该方案基于多端一致埋点对象树建设管理,实现了统一自动化埋点和链路追踪,方案高度还原了大前端埋点的理想状态、具备较强通用性和扩展性。我们围绕这套埋点方案研发了配套的埋点管理系统,以承载及埋点规则数据管理、埋点设计、埋点研发、埋点测试、埋点上线等功能,本文主要介绍该平台功能及建设思路。

二、平台现状介绍

经过前几期建设,我们已经实现了一个适配研发流程的、按版本来管理的埋点数据管理平台,其核心功能为:

  • 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等组件都将在近期贡献到开源社区,为业界带来更大价值。

有关网易云音乐全链路埋点管理平台建设的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  3. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  4. ruby - (Ruby || Python) 窗口管理器 - 2

    我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

  5. ruby-on-rails - 事件管理员和自定义方法 - 2

    这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什

  6. ruby-on-rails - (Ruby,Rails) 基于角色的身份验证和用户管理...? - 2

    我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源

  7. Linux磁盘分区中物理卷(PV)、卷组(VG)、逻辑卷(LV)创建和(LVM)管理 - 2

    文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分

  8. ruby-on-rails - 使用用户或管理员模型和 Basecamp 样式子域设计登录 - 2

    我为Devise用户和管理员提供了不同的模型。我也在使用Basecamp风格的子域。除了我需要能够以用户或管理员身份进行身份验证的一些Controller和操作外,一切都运行良好。目前我有authenticate_user!在我的application_controller.rb中设置,对于那些只有管理员才能访问的Controller和操作,我使用skip_before_filter跳过它。不幸的是,我不能简单地指定每个Controller的身份验证要求,因为我仍然需要一些Controller和操作才能被用户或管理员访问。我尝试了一些方法都无济于事。看来,如果我移动authentica

  9. ruby-on-rails - 具有管理 namespace 的 Rails 3 中的 I18n - 2

    我正在根据Rails指南的建议开发Rails应用程序,以创建包含翻译的文件夹树和文件。我的文件夹树与此类似:|-defaults|---es.rb|---en.rb|-models|---book|-----es.rb|-----en.rb|-views|---defaults|-----es.rb|-----en.rb|---books|-----es.rb|-----en.rb|---users|-----es.rb|-----en.rb|---navigation|-----es.rb|-----en.rbconfig/locales/views/books/en.yml中的内容

  10. Ruby 文件句柄管理(打开的文件太多) - 2

    我在ruby​​(2.0.0p39474)中执行非常快速的文件访问,并不断收到异常Toomanyopenfiles看过thisthread,here,以及各种其他来源,我很清楚操作系统限制(在我的系统上设置为1024)。我执行此文件访问的代码部分是互斥的,并采用以下形式:File.open(filename,'w'){|f|Marshal.dump(value,f)}其中filename会根据调用该部分的线程快速变化。据我了解,此表单在block后放弃其文件句柄。我可以使用ObjectSpace.each_object(File)验证打开的File对象的数量.这报告最多有100个常驻内

随机推荐