采集协议与 SDK
三端 SDK 与服务端之间是同一种报文。这一页给要改采集链路的人:协议在哪里定义、服务端怎么规范化、加一个字段要改哪些地方,以及怎么写一个新平台的 SDK。协议本身的完整说明见 HTTP 协议。
报文
POST /sa,正文是 JSON:{"batch": [...], "sentAt": "..."},可以 gzip。批量外壳的字段沿用 Segment HTTP API:messageId、type、event、anonymousId、userId、timestamp、properties、traits、context。- 鉴权用写入密钥:
Authorization: Basic base64(key + ":");浏览器用sendBeacon时带不了请求头,改在正文里写writeKey。 - 成功是响应里
code = 0,data.accepted是写进队列的条数。 - 单个请求最大 1MB、每批最多 100 条、单个事件的属性最大 16KB,完整的上限见 限制与上限。
服务端怎么处理
入口在 evs-aggr/internal/collect/handler.go,逐条规范化在 normalize.go:
type决定写成哪种事件:track用event名;page写成$pageview;identify写成$SignUp,带traits时再写一条profile_set。- 过滤:域名白名单与黑名单、爬虫 UA、排除 IP;被过滤的按原因计数,给接入检查用。
- 时间:客户端时间比服务器快 2 小时以上时改用服务器时间;早于 7 天前的丢弃(原因
too_old)。 - 页面:
url、path、title、referrer,referrer_host去掉www.;UTM 从context.campaign、属性或页面地址的查询参数里取。 - 身份:
userId非空时distinct_id取它,否则取anonymousId。 - 终端:从 User-Agent 解析浏览器、系统、设备类型;
lib取 SDK 名。
规范化之后的一行就是 evs_event 的一行,字段名与表的列名相同(collect.Row)。
加一个字段
以「事件带上屏幕宽度,作为可筛选的列」为例:
| 步骤 | 文件 |
|---|---|
| 表加列(只加不删,启动时自动补上) | evs-aggr/schema/data.sql 的 evs_event |
| 规范化时取值 | evs-aggr/internal/collect/normalize.go 与 collect.Row |
| 需要按它分组或筛选时 | internal/stat/query.go 的维度列清单;需要预聚合时改 evs_mv_agg_dim_daily |
| SDK 采集 | evs-sdks/web/src/core/context.ts 等 |
| 文档 | 官网 事件与属性名、HTTP 协议、更新日志 |
只是业务属性时不需要改表:放进 properties 就能在事件日志里看到,在筛选和自定义分析里按属性键使用。
物化视图的定义变了时,启动调和会删掉视图再按新定义创建,聚合表里的旧数据保留,新维度只对之后写入的数据生效。
写一个新的 SDK
App、小程序或别的语言没有官方 SDK 时,按下面的约定写,报文与三端一致:
endpoint是完整的采集地址,原样请求,不再拼路径;初始化参数叫key。- 每条消息的
messageId(UUID)在入队时生成,重试时不变;sentAt、timestamp是 RFC3339 毫秒 UTC。 - 客户端有本地队列:网络失败、超时、429、5xx 时从 200ms 起指数退避重试,最多 5 次;400、401 等其它 4xx 不重试,丢弃这一批。
- 属性值只用字符串、数字、布尔;
properties里写$lib与$lib_version,context.library写 SDK 名与版本。 - 不采密码、证件号、验证码、输入框内容。
三端已有的实现可以当参考:evs-sdks/go(只依赖标准库)最短,evs-sdks/java 语义与 Go 相同,evs-sdks/web 另有全埋点、热力图叠加、A/B 与回放。
A/B 分流
分流在 SDK 本地做,按匿名 ID 的稳定哈希分到变体,进入实验时发 $ABTestTrigger。同一个算法在 Web SDK 和服务端 internal/behavior 各有一份,共用 evs-sdks/web/test/ab-vectors.json 测试向量,改算法时两边和向量一起改。
测试与发布
| SDK | 测试 | 发布 |
|---|---|---|
| Web | yarn lint、yarn test、yarn size、yarn test:browser | 标签 sdk-web/vX.Y.Z,发 npm 并把 IIFE 附到 Release |
| Go | go test -race ./... | 标签 evs-sdks/go/vX.Y.Z,由 Go 模块代理拉取 |
| Java | ./mvnw -q verify(JDK 17 与最新 LTS) | 标签 sdk-java/vX.Y.Z,发 Maven Central |
也可以在 evs-test 里按编号跑:uv run main.py --case sdk。