一条事件怎样变成指标
用户做了一个动作,前端先把它记录成一条标准事件。网络好就上传,网络不好就先放进本地队列。后端只接收合法事件,数据库保存原始记录,最后再汇总成每天能看的新增、活跃和功能使用指标。
1
用户动作
打开 App、进入训练、完成训练、查看统计。
2
iOS 采集
生成 event_id,带上匿名 ID、版本、渠道和事件时间。
3
本地队列
断网时先保存,恢复网络后批量补发,避免丢事件。
4
后端入口
校验事件名、字段白名单、重复 event_id 和异常时间。
5
数据库指标
原始事件入库,再按天汇总新增、活跃和训练使用。
当前 1.4 的统计边界
我们统计什么
首次打开、每日打开、训练页曝光、训练开始/完成/提前结束、身体记录添加、统计页查看。
我们怎样定义用户
当前 App 没有注册概念,所以用户按匿名安装 ID 计算。它适合看产品趋势,不等同于真实自然人。
我们不统计什么
不上传手机号、姓名、照片、媒体内容、密码、精确位置或其它可直接识别个人身份的信息。
新增和活跃怎么来
| 指标 | 事件来源 | 计算口径 | 适合回答的问题 |
|---|---|---|---|
| 新增 | app_first_open | 某天第一次出现的匿名安装 ID 数量。 | 今天有多少新设备第一次打开了 App。 |
| 活跃 | app_open、workout_view、workout_start 等 | 某天有任意有效活动事件的匿名安装 ID 去重数。 | 今天有多少匿名用户真正使用了 App。 |
| 训练使用 | workout_start、workout_complete、workout_abort | 按事件次数、用户数和完成率聚合。 | 用户是否进入训练、是否完成、在哪里流失。 |
| 生产过滤 | channel、build_type、is_test_mode | debug、UI test、内部测试数据默认不进入正式指标。 | 避免我们自己测试把新增和活跃冲高。 |
前端、后端、数据库各管什么
iOS 前端
知道用户做了什么动作,负责生成事件、匿名 ID、本地缓存、断网补发和隐私开关。
后端服务
负责接收事件、判断是否合法、去重、过滤无关字段、标记测试数据和异常时间。
PostgreSQL
保存原始事件和汇总指标。原始事件用于追查问题,汇总指标用于看业务趋势。
为什么要先存原始事件
统计一定会遇到口径调整。先存原始事件,后面才可以重新计算,不用因为今天的指标逻辑写错就永久丢数据。
原始事件入库
每条合法事件都保留 event_id、匿名 ID、时间、版本、渠道和白名单属性。
标记能否聚合
未来时间、过旧时间、测试渠道、非法字段不会进入正式指标。
按天汇总
每天计算新增、活跃、训练曝光、训练完成、提前结束等指标。
排查时回看
如果某天数据异常,可以回到原始事件检查是不是重复、测试包、时间错误或网络补发导致。
常见统计漏洞和防护
容易出问题
- 启动事件被前后台切换重复触发。
- 断网重试导致同一事件重复入库。
- debug 或 TestFlight 数据混进正式指标。
- 客户端时间不准,把事件算到未来或很久以前。
- 隐私开关关闭后,本地队列仍然继续上传。
当前防护思路
- 每条事件都有 event_id,后端按 event_id 去重。
- 后端只接受白名单事件和白名单字段。
- debug/test 数据可入原始表,但不进生产指标。
- 异常时间标记为不可聚合。
- 匿名统计关闭时清空本地待上传队列。
上线前最小验收清单
| 检查项 | 通过标准 |
|---|---|
| 真机首次启动 | 能在原始表看到 app_first_open 和 app_open。 |
| 训练流程 | 进入训练、完成或提前结束后能看到对应 workout 事件。 |
| 正式指标过滤 | debug/test 事件不会出现在生产 metrics 里。 |
| 隐私开关 | 开关可操作,关闭后停止采集并清空待上传队列。 |
| 断网补发 | 离线产生的事件在恢复网络后上传,且不会重复计数。 |
| 版本渠道 | App Store 包应被识别为正式渠道,TestFlight 包应能单独区分。 |