企业级埋点教学!到底多重要一看就知道 🦾

允许我上来先介绍一个好东西!

面试导航 是一个专注于前、后端技术学习和面试准备的 免费 学习平台,提供系统化的技术栈学习,深入讲解每个知识点的核心原理,帮助开发者构建全面的技术体系。平台还收录了大量真实的校招与社招面经,帮助你快速掌握面试技巧,提升求职竞争力。如果你想加入我们的交流群,欢迎通过微信联系:Tongxx_yj

背景

埋点到底有多重要呢?严格意义来说,埋点适用于任何服务用户的场景,无论是 C 端、B 端业务,还是内部使用的工具链

那埋点能带来什么作用呢?通过埋点获取用户、平台的相关数据,可以帮助我们:

  • 报警监控:如果观测到 xx 指标存在问题(不合实际、波动显著等),可触发报警让研发及时响应问题
  • AB 实验,回收数据收益:通过相关的指标来认证 xx 需求是否带来了业务、技术收益(比如某次性能优化,减少了用户流失)
  • 分析用户行为 :通过多项数据联动(指标下钻、漏斗分析等),观测用户行为
    • 为应用优化提供更多思路
    • 为数据分析提供有力证明

如果对埋点的概念还有不清晰的同学,可以前置学习一下:大家都该学学的埋点概念与使用😎

本篇文章将默认大家对埋点拥有基本认知,核心围绕埋点在复杂应用中的实践(尤其是 C 端业务),通过这篇文章,你可以学习到:

  1. 埋点的基本实践方案
  2. 复杂场景的埋点运用

埋点的基本实践方案

如果你有一定的埋点开发经验,可以直接跳过这一部分

首先我们给自己一个明确的身份:电商 C 端业务的一个研发同学

其次,我们明确要负责的业务场景:近期主要负责商品浏览记录的场景 ,此处参考"抖音商城=足迹"

再者,我们明确一下我们要做的事情:

  1. 需求:实现一个记录的商品浏览信息的页面
  2. 功能:用一个 list 展示商品信息,点击商品信息可跳转至对应商品

产品视角

OK,面对这样的一个简单需求,我们尝试从产品的角度对功能进行拆解:

功能点 详细说明
浏览信息展示 页面初始化后,在页面渲染一个无限滚动 list,展示该用户的浏览商品记录
点击商品进行跳转 点击商品卡,页面会跳转至对应的商品详情页

明确功能之后,我们再从产品的角度来看看需要些什么数据(简单版本)

数据 指标描述
页面曝光数 描述用户对足迹页面的使用频率和潜在关注度
商品曝光 描述用户进入页面后,某个商品的展示
商品点击 描述用户进入页面后,某个商品的点击

好了,至此一个简易版本 PRD 已经输出到了研发这边,需求评审要开始了

研发视角

需求评审阶段,我们得知了产品想要什么数据,那这个时候,我们就需要通过埋点来满足他们的诉求

我们先忽视页面搭建的过程(这太简单了),只关注埋点的设计、研发和验收

埋点设计

对于埋点的参数,我们默认系统会带上用户 id 等全局参数

我们基于产品的诉求来设计埋点,这种埋点大部分是和数据一一对应的,如:

数据 事件名称 事件参数
页面曝光数 page_view - page_name,string,页面名称 - total_count,number,商品数量
商品曝光 product_show - page_name,string,页面名称 - product_id,string,商品 id
商品点击 product_click - page_name,string,页面名称 - product_id,string,商品 id

埋点开发

有了一个比较清晰的设定,我们用来开发就很方便了,直接在对应的场景调用埋点 sdk 的 API! 比如:

ts 复制代码
handleProductClick = async (id: string) => {
    sendEvent('product_click', {
        page_name: 'foot_print',
        product_id: id
    })
    // 处理业务逻辑
}

当我们调用 sendEvent 的时候,相关的事件就会进行上报,此时数据服务会记录相关的数据,我们可以通过埋点平台 or 数据库直接查询对应的数据内容

数据验收

我们直接跳过埋点自测(抓包看数据就行了)环节,假设这个时候需求已经上线了,产品要来找研发看数据了,这个时候我们可以给到我们的埋点事件设计,让产品自己看数(当然也可以研发包掉)

比如产品要看 id 为 xxxxx 的商品点击数据,可以通过以下的条件来筛选:
事件名 = product_click && page_name = foot_print && product_id = xxxxx

其实到这一步,整个需求就已经结束了,只要数据符合预期,产品就不会继续找咱研发的事了~

当然这只是一个最基本的实现流程,我们会在后面的板块中给出更难的场景

复杂场景的埋点运用

如果仅仅是掌握上一个板块的知识点,我们仅能做到勉强支撑一些埋点开发,在实际的工作中大概率是要踩坑的 在这一个板块,我们会基于更复杂的场景展开,带大家体验一下实际工作中的强度

背景问题一:庞大的业务团队

在这个背景下,可能存在一个埋点事件被多条业务线的同学使用的情况,这种情况下会带来什么问题?

  1. 数据混乱:
    • 原因:比如 page_name 参数,如果用成别的页面的命名,就导致数据错报了
    • 解决方案:一般会通过测试同学检查、设立报警监控等方式规避,但难以完全避免!
  2. 事件参数复杂,难以维护
    • 原因:每个团队都可能往公共事件里面加入参数定义,导致公共事件的参数越来越冗长,对公共事件的更新会变的异常艰难
    • 解决方案:非必要不删除参数,避免不可预估的影响;尽可能使用已有的参数

这两个大头的问题,其实也没有太好的解决方案,长期以往,研发同学将持续在心智负担较大的背景下开发埋点代码,那么这个时候,我们有什么比较好的解决方案呢?

方案一:新开事件

面对这种复杂的现状,我们可以将一些有特殊传参要求的业务场景开设独立的事件

比如我们的足迹场景中,商品卡片上有一个进入店铺的按钮,我们需要为进入店铺按钮,这个时候我们有两种事件命名方式:

  1. 通用维度button_click,记录所有的按钮点击事件
  2. 页面维度footprint_button_click,记录足迹页面下的所有按钮点击事件
  3. 独立维度footprint_enrty_shop_click,记录店铺按钮点击事件

选择 2、3 都是不错的选择,但各有优劣:

  • 页面维度不够精准 ,但能较大限度 避免上述问题带来的影响,且开发比较方便(维护更多的事件肯定会更加麻烦的)
  • 独立维度非常精准 ,能最大限度避免上述问题带来的影响,但是开发比较繁琐(要维护更多的事件了)

但综合来说,个人会更倾向使用页面维度,为什么?

我们把事件的数量比作 A,需要使用的场景比作 B,我们假设需求中,每个场景只需要埋一个

那么总共要埋的数量 X = A * B,可以理解为, A + B 是整个需求的复杂度(可以理解为研发要考虑的范围)

  • 通用维度:X = 1 * B1
  • 页面维度:X = A2 * B2
  • 独立维度:X = A1 * 1

可以得到 B1 = A2 * B2,我们取几组数字带入看看:

  1. 左侧:2,右侧:2 * 1
  2. 左侧:4,右侧:2 * 2
  3. 左侧:6,右侧:2 * 3
  4. 左侧:16,右侧:2 * 8

可以看到,随着数据越来越大,右侧两数之和会越来越低于左侧,那研发的复杂度就会越来越低~

👇很重要 !!!!!!!!!!!!!!!!!!!!!!!!

ps:这是一种通用的思想!非常好用,面对复杂度很高的场景,通过拆分 & 叉乘的方式,来降低复杂度

👆很重要 !!!!!!!!!!!!!!!!!!!!!!!!

方案二:统一参数标准

统一参数标准,顾名思义,我们会对一些通用参数的使用做规范统一

举个例子,电商场景,我们通过一系列方式让用户下单,完成交易,那这个时候我们需要额外注重一个事情:
用户从哪个商品卡点到商品详情的

为什么要额外注重?我们从产品的角度看看:每个包含商品卡的页面,都需要一些数据来论证他的价值,那此时用户通过商品卡进入商品详情时,应该带来一个特殊标志,来表明来源

这种场景我们就有必要统一一个参数,比如 enter_form,一般情况下 enter_form 会取自上一级页面的 open schema(打开对应链接)的 query 参数上,在商品详情页初始化时,触发 page_view 事件,我们可以带上 query 上的 enter_form 参数(xxxxxxxx?enter_form=footprint),就可以精准地判断来源了

回归主题,这个例子说明了什么?

  • 具体来看,我们给一个分析页面来源的方式统一了一个参数命名获取标准
  • 抽象来看,我们给一个类型的事件统一了 SOP(Standard Operating Procedure 标准作业程序)

有什么好处? 🌟🌟🌟

  1. 数据准确与一致性 :全域业务线统一标准,在任何同类场景中使用一种标准规范,保证数据不会出现差异性(比如一个页面用了 enter_form 作为来源,而另一个页面用了 origin
  2. 上下文一致性 :保证需求沟通过程中,避免理解 gap(比如我满嘴 enter_form,另一边的规范却是 origin,就会导致沟通低效,甚至出现理解错误导致数据回收有误的情况)

当然,统一参数标准还有更多的体现方式,也有很多的推进思路(如设立一套涵盖:测试环节标准 SOP 指定、本地脚本检查等卡点的检查流程,保证埋点需求顺利上线)

背景问题二:复杂的归因链路

背景带入

何为复杂的归因链路?我们还是以电商的商品成单归因为例:我们需要分析出商品详情的来源 ,保证相关场景的价值论证能力

我们在前面提到了,可以通过 enter_form 来归因,但在这个场景远没有那么简单

我们可以设想一个用户行为:

  1. 用户通过抖音进入了抖音商城
  2. 用户在首页的商品瀑布流进行浏览,并点击了一个商品进行查看
  3. 一天后,用户想要再看看之前那个商品,所以来到了足迹页面
  4. 用户找到了商品,并点击进入商品详情,把商品加入了购物车
  5. 又一天后,用户发现购物车的这个商品打折了,赶紧进入该商品详情并火速完成了下单

好了,我们分析一下这个链路出现了几个商品详情来源:首页商品瀑布流、足迹、购物车

如果套用我们之前的方法,仅计算成单前商品详情的来源,那么只有购物车会被记入来源,那瀑布流和足迹肯定就不乐意了(我也参与了整个交易链路,为什么没有我的功劳?!)

这种问题会带来什么后果??(远比你想象的严重)

  1. 价值论证不置信 :每个场景的价值论证都取决于当前场景的属性,足迹这些场景起到的作用,不是一定要以成单前商品详情的来源为标准。相应的,我们会把整个链路中涉及商品卡的场景都记录在内,这样才能准确地论证某个场景的业务价值
  2. 分佣出现错误:基于上述的论证标准,如果我们忽视了前置链路,那可能就会存在分佣问题(比如某个达人推荐的商品,会因为中间链路不记录而导致分佣数据丢失),那必然会存在客诉(人家的利益受到了挑战)

解决方案

那我们该如何解决这个问题呢?是不是应该加一个数组到 schema 的 query 上?

1. 获取参数

然而并不是很合适!

schema 上的参数应该做内容的限制,如果堆上了一个长度不可控的数组,可能导致 schema 过长导致跳转失效、数据丢失等情况

那我们有什么办法呢?

有一个比较好的思路,就是给我们埋点的全局参数上,加一个数组,用来记录上级来源,每次页面跳转时,我们都会读取 query 上的 enter_form,并更新这个全局参数

2. 参数内容规范

这样还有什么问题?我们再思考思考

  1. 每个页面都不一定有 enter_form,且 enter_form 的内容也可能会比较随意不可控
  2. enter_form 如果仅仅表达 footprintfeeds 等英文名,其实非常的粗糙

那我们还有什么优化方案?>> 参数内容规范

首先,我们不再基于 enter_form 来获取来源数据。我们约定每个页面都有一个特殊标志位 (具备唯一性),在每个页面初始化埋点 sdk 的时候,都要注册一下这个标志位(可以理解为一种通参)

那么我们就通过另一个参数来上报,比如我们叫 origins 吧,那么上报的格式就是这样的:

js 复制代码
page_view {
    page_name: 'product_detail',
    enter_form: 'footprint',
    origin: 'x3',
    origins: ['x1', 'x2', 'x3'],
    // ......
}

这个标志位我们可以通过一个管理平台、或者规范文档来进行收敛,来保证唯一性和研发的标准性

其次,我们要思考如何让这个标志位更加的具备信息密度

我们可以通过点位信息的思想来满足这个诉求,比如:x1 = "业务线A.页面B.块C.点D_[更多信息......]" 我们通过一套规范的格式,来传递更多的信息,我们再通过几个场景来加深大家的理解:

  1. page_view,页面级曝光,x = "电商.商品详情"
  2. product_click,足迹页面的商品卡点击,x = "电商.足迹.商品列表.商品卡_18" (18 表示第十八个商品卡)

那带入我们的整个归因链路,是不是就变成了:

js 复制代码
page_view {
   page_name: 'product_detail',
   enter_form: 'footprint',
   origin: '电商.商品详情',
   origins: ['电商.商城首页.顶 tab 按钮集.足迹按钮', '电商.足迹.商品列表.商品卡_18', '电商.商品详情'],
   // ......
}

到这一步,相比我们使用 enter_form,是不是好了太多?

有了这样的数据,那么数据分析师就可以结合这些信息,做出更严格、精确的价值论证、收益分佣等操作~

最后

不知不觉已经写了很多内容,本来预期再聊一些个人对埋点研发生命周期的思考,考虑到篇幅,我们还是放到下一次再介绍~(我会快马加鞭更新的😭)

在真正的企业级埋点需求开发中,这些问题层出不穷,不规范、上下文不对齐等一系列问题都会带来非常恶心的研发体验(亲身经历~)

这种时候,借助 AI 也是一个不错的选择,本人最近就是在研究 Trae 对我埋点开发的提效手段,体验还是非常不错的。我们可以在 Chat 模式下投喂相关的产品 PRD,让他做一些工作:

  1. 基于 PRD 生成一个埋点设计表格
  2. 你在微调表格后,进入 Build 模式,让 AI 基于你的历史开发规范,注入相关的埋点事件(前提是你把一个个埋点需要注入的地方明确好!)

最后的最后,希望这篇文章能给大家带来一定的收获,咱们下次再见 👋

相关推荐
刺客-Andy几秒前
React 之 Redux 第二十九节 Redux各项组成详解
前端·react.js·前端框架
m0_748241235 分钟前
spring-boot-starter和spring-boot-starter-web的关联
前端
鸿是江边鸟,曾是心上人44 分钟前
echarts使用记录
javascript·ecmascript·echarts
好_快1 小时前
Lodash源码阅读-nth
前端·javascript·源码阅读
maybe啊1 小时前
js 使用 Web Workers 来实现一个精确的倒计时,即使ios手机锁屏或页面进入后台,倒计时也不会暂停。
开发语言·前端·javascript
好_快1 小时前
Lodash 源码阅读-baseNth
前端·javascript·源码阅读
好_快1 小时前
Lodash源码阅读-join
前端·javascript·源码阅读
子洋1 小时前
Chroma+LangChain:让AI联网回答更精准
前端·人工智能·后端
好_快1 小时前
Lodash源码阅读-isIndex
前端·javascript·源码阅读
好_快1 小时前
Lodash源码阅读-reverse
前端·javascript·源码阅读