2991 字
约 9 分钟
16
S14-A10 · 埋点与指标口径:谁定义、谁维护

同一场周会,两个人各拿一张报表,同一个"周新增"差了 6%:一个按注册完成时间,一个按首次登录时间;一个含三个内部测试账号,一个不含。会开到一半,议题从增长转成"到底谁的数对"。

根因不在数据,在口径没有 owner。口径只存在于某个人的 SQL 里,就没有维护者、没有版本、没有变更记录,谁改谁负责都说不清。


1. 三种埋点与它们的完整性

类型 完整性风险 成本 适合
前端事件 网络失败、SDK 阻塞、隐私限制导致丢报 低,改动快 交互行为、曝光与点击
后端事件 只在服务端能观测到,但业务分支易漏 中,需服务发版 交易、状态流转、服务端校验
日志派生 依赖日志字段稳定,解析易随格式漂移 低边际成本,高维护 已有日志覆盖的系统行为

判据:事实发生在哪一侧。点击在前端,支付成功在后端;把支付成功做成前端事件,等于用"看到成功页"代表"已支付"——弱网下两者必然分叉。

同一个指标跨端拼接时,还要处理"同一动作被两侧各记一次"的重复。常见做法是前端只记意图、后端记事实,指标计算以后端为准。


2. 口径必须写到什么程度

要素 必须回答 只写名字会怎样
分子 计什么、按什么条件筛 双方各算一版,差在排除条件
分母 是否存在、范围如何界定 比率型指标分母漂移,趋势假性上升
时间窗 自然日/滚动 7 日/按事件时间 跨零点的行为被切到两天
去重键 按 user_id、device_id 还是订单号 多端用户被算成两个

"周新增用户"这六个字,至少缺五项。只写名字的口径有个特征:它能被两种都正确的方式实现,而这两种实现在任何一次对话里都无法证伪。


3. 三方所有权与"三不管"

角色 负责 常见空档
产品 定义要回答什么问题、口径的业务含义 定义完就不再看实现
数据 口径实现、校验、文档与版本 不掌握埋点是否漏报
研发 埋点上报、字段含义、变更通知 认为口径与己无关

典型后果:产品改了语义("激活"从"首次登录"改成"首次核心行为"),研发按新语义改埋点,数据侧口径没动,于是报表在某版本悄悄换了一次定义,没人发现,直到半年后同比失真。

可行解是一个 owner + 两个协作者:owner 唯一(通常数据侧),产品确认业务含义,研发负责上报与变更通知。owner 唯一才有唯一责任人。


4. 埋点的生命周期

阶段 必须做的事 不做会怎样
新增 注册事件名、字段、owner、用途 半年后无人知道这个事件是谁加的
变更 通知下游、保留旧字段过渡期 下游静默取到空值
下线 标记废弃、观察零流量后再删 直接删导致历史报表断裂

埋点体系最常见的腐化是只增不减:三年积累几百个事件,能说出用途的不到三成,采集成本照付,校验规则没人维护。

# 埋点注册表:一条记录进仓库、进评审,禁止口头新增
event: checkout_success
owner: payment-team
status: active            # active | deprecated | sunset
fields:
  order_id: {type: string, required: true}
  amount:   {type: decimal, unit: cent, required: true}
consumers: [gmv_daily, funnel_report]   # 下线前逐个确认

consumers 这一栏是下线的依据:没有它,删事件只能靠猜,猜错的代价是一张看板归零。


5. 四类质量问题

问题 识别方式 典型成因
漏埋 期望量级与实际量级比 新分支未加埋点、SDK 未初始化
错埋 字段值与业务事实抽样比对 参数顺序错、单位错、枚举写反
重复埋 同一事件多来源计数对比 前端重试、后端重发、双端都记
版本漂移 分版本看指标断层 发版改了语义但未改版本号

后两类最难发现:漏埋表现为"量少",重复埋与漂移表现为"量正常但含义变了"。所以校验不能只查非空与量级,还要查分布:枚举分布、分位数、人均事件数。

-- 埋点有效率:通过校验规则的事件占比
SELECT e.event_name,
       COUNT(*) FILTER (WHERE v.result = 'pass')::numeric
         / NULLIF(COUNT(*) FILTER (WHERE e.status = 'active'), 0) AS valid_rate
FROM   event_registry e LEFT JOIN event_validation v USING (event_name)
WHERE  e.dt = CURRENT_DATE - 1
GROUP  BY e.event_name ORDER BY valid_rate;

valid_rate 长期偏低的团队,通常是"埋点加了但没人配校验规则"——问题不在上报,在校验清单空着。


6. 变更埋点的兼容策略

改口径不能一步切换,否则历史与当期不可比,趋势图全部出现台阶。

策略 做法 代价
新旧并行 同时上报两份,报表只读新的 采集成本翻倍,需定下线日期
老口径保留窗口 旧字段保留 N 个月只读 存储与文档负担
版本号伴随 事件带 schema_version 下游必须按版本分流
# 双写映射:并行期内两条口径同时产出,可对比、可回滚
metric: weekly_new_user
variants:
  v2: {basis: register_time, exclude_internal: true}
  v3: {basis: first_login_time, exclude_internal: true}
compare_window: 14d        # 差异率超阈值即阻断 v3 上线
cutover: 2026-Q1           # v2 转只读,保留历史

并行期的价值不是"稳",是给出可证伪的差异:连续两周差异率在预期内才敢切;差异率说不清,就别切。


7. 前端埋点的三个特殊困难

困难 表现 缓解
网络丢失 页面关闭时请求被取消 用 sendBeacon 或 keepalive 通道
SDK 阻塞 同步加载拖慢首屏 异步加载 + 队列缓冲
隐私限制 部分字段不可采集或被浏览器拦截 采集前先做字段分级
// 卸载类事件:beacon 在页面销毁后仍会被投递,fetch 会被取消
navigator.sendBeacon('/collect', new Blob([JSON.stringify({
  event: 'page_leave', ts: Date.now(), path: location.pathname,
})], { type: 'application/json' }));

隐私限制也是数据质量问题:被拦截的字段表现为"某些浏览器空值率高"。方案若没预留降级字段,指标会按浏览器分裂,而这种分裂很难被当成问题发现。


8. 口径的版本化与文档化

口径应当像 API 一样被管理:有版本、有 owner、有变更记录、有消费者清单。文档写在 wiki 里的问题是它不会随代码变,而写在配置里的口径可以被 CI 校验。

metric: weekly_active_user
version: v4
owner: growth-data
numerator: count(distinct user_id)
denominator: null
window: 7d                # 滚动窗口,按 event_time 归集
dedup_key: user_id
filters: [is_bot = false, is_internal = false, event_type in (login, core_action)]
consumers: [weekly_report, exec_dashboard]
changelog:
  - {version: v4, change: 排除内部账号, date: 2026-01, recompute: true}
  - {version: v3, change: 加入核心行为, date: 2025-08, recompute: false}

有了 consumers 与 changelog,口径变更才是一次可通知、可追溯的事件,而不是某人默默改了一行 SQL。


9. 口径变更的通知与历史重算

变更类型 是否重算历史 理由
排除条件修正(如剔除测试账号) 通常要 旧数据本身是错的
业务语义扩展(加入新行为) 通常不要 重算会抹掉真实的行为变化
去重键调整 要,且需并线观察 新旧不可比,必须双线过渡

判据是**"旧数据是错的,还是旧数据对但口径不同"**:前者必须重算,后者重算等于篡改历史。重算前答三个问题——影响哪些指标、影响多少期、下游是否已消费过旧值,第三个最常被漏掉。


10. 自埋自用的陷阱与度量

最常见的腐化是激励问题:负责功能的人同时负责证明功能有效,于是口径被微调——分母去掉不活跃、时间窗 7 日改 30 日。每次调整都合理,合起来只有一个方向:让数字变好。

指标 定义要点 健康信号
口径文档覆盖率 有 owner+版本+消费者的指标占比 上升,优先覆盖对外指标
埋点有效率 通过校验规则的事件占比 上升,校验规则同步增长
口径变更次数 按季度统计,区分修正与重定义 稳定,且每次都有 changelog

防自埋自用的办法不是禁止改口径,而是要求改口径必须走与改代码相同的评审:谁提、谁批、影响谁、要不要重算。把"调口径"的成本抬到与"改代码"相当,随手调整就会消失。


11. 排错:两个报表两个数时的排查顺序

现象 先查 常见结论
差异固定为某个百分比 排除条件(内部账号、机器人) 一侧未过滤测试流量
差异随时段变化 时间窗与事件时间/处理时间 跨零点切分或延迟归集
差异随时间扩大 去重键 多端或多设备被重复计数

第一条几乎必中:内部账号是最常见的固定比例差异来源,也最容易被漏进对外口径。


12. 边界:什么时候不必建口径管理体系

场景 判断 替代做法
内部工具、无对外数字 错也只影响自己 报表旁写清口径即可
无数据驱动决策 数字不进入任何判断 不做体系,只做基本校验
指标只被一个人看 无跨方对齐需求 该人自己维护口径
一次性分析、不复用 无历史可比性 分析脚本自带注释

判据:**当"两个数不一致"不会导致任何决策分歧时,口径管理的收益为零。**体系价值来自多方共用一个数;只有一方时,它只是文档负担。


13. 自测

  1. 判断一个事件该做成前端埋点还是后端埋点,看哪一句判据?
  2. 只写名字的口径有什么特征,为什么它无法被证伪?
  3. 三方所有权里,"三不管"的典型后果是什么?
  4. 埋点只增不减,三年后最直接的代价是什么?
  5. 哪两类质量问题表现为"量正常但含义变了"?
  6. 口径变更要不要重算历史,判据是哪一句?
S14-A10 · 埋点与指标口径:谁定义、谁维护
https://www.clxhxhhr.top/posts/6255/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。