事件的一生
一条事件从插件产出到发往网关,要经过固定的加工与上送流程。理解这条链路,你就能读懂上报数据长什么样、为什么「埋了却没上报」、以及各能力的事件最终如何汇到同一个接口。
全景:从 RawEvent 到网关
所有能力(行为 / 错误 / 性能 / 归因 / 身份)产出的事件,都走同一条链路、用同一个信封、发往同一个网关接口(POST …/v2/trace/events):
L3 插件 emit RawEvent(仅经 ctx.emit)
▼
L4 Pipeline 六阶段加工 → WireItem
▼
L5 Transport 单队列三级优先级上送
▼
后端网关(单 endpoint,X-DeviceId + 微服务路由头)- RawEvent:插件产出的原始事件,只带类型与业务私参。
- WireItem:经管线加工、可直接上报的最终形态(即下方的「统一信封」)。
第一站:Pipeline 六阶段
每条事件从插件 emit 出来后,固定经过六个阶段才上报,顺序不可调换:
Enricher(注入身份/运行时/上下文/全局参数/面包屑)
→ killSwitch(远端熔断统一闸断)
→ Sampler(概率采样;错误默认 100%,可被远端 control.tech 坐标级规则覆盖)
→ SchemaValidator(结构校验,可丢)
→ PIIFilter(PII 脱敏,只改 payload 不丢事件)
→ beforeEmit(业务钩子,可改写或返回 null 丢弃)
→ Serializer(构造最终 WireItem)- PIIFilter 对
payload做脱敏——只改 payload、不丢事件,是默认就在的安全网。 - 业务能直接介入的只有
beforeEmit(见 构造参数 · beforeEmit);其余阶段由 SDK 与 远程配置 驱动。
事件「明明埋了却没上报」,多半就是被 killSwitch / Sampler / Schema 丢在这条管线里——killSwitch 与采样的治理语义见 远端配置治理,排查见 排查:没有上报。
第二站:统一信封
管线产出的 WireItem 是一个统一信封,四个顶层段各司其职:
| 段 | 作用 |
|---|---|
event_format | 事件坐标(点分 TracePath)+ 类型段,标识「这是什么事件、发生在哪个位置」 |
context | 运行时上下文:页面 URL / referrer、设备与会话标识、用户标识等由 SDK 注入 |
payload | 业务私参:你在 params / track(…, props) 里传的字段,外加 globalParams 命名空间 |
timestamp | 事件发生时间点(前端只报时间点,时长由后端按时间线还原) |
坐标不在 payload 里
事件坐标统一承载在 event_format,不随 payload 重复下发;payload 只装你的业务私参。这也是为什么 DevTools 用 event_format 做事件 ↔ 元素的反查。
完整字段以 API Reference 的 *Payload 类型为准;context 里三个 ID 的来历见 身份与会话;信封的服务端注入部分见 SSR 采集。
事件类型
一张表看清各能力产出什么事件(类型段进入 event_format):
| 能力 | 事件类型 |
|---|---|
| 渠道归因 | landing |
| 身份绑定 | identity |
| 行为埋点 | click · expo · pageview · hide · show · leave · track |
| 错误收集 | js · promise · resource · white-screen · api · ssr |
| 性能收集 | performance |
行为埋点的坐标是一条点分 TracePath(. 分隔 2–8 段、每段 [a-z0-9_-]{1,32}),唯一定位「页面上的哪个位置」;声明式与命令式写法、拼接与去重规则统一见 行为埋点。各事件的触发与字段见对应能力页:错误收集 · 性能收集 · 渠道归因。
第三站:单队列三级优先级
所有事件进同一个传输队列,按优先级区别对待:
| 优先级 | 事件 | 行为 |
|---|---|---|
| P0 | landing / identity | 入队即发 + 等送达回执;豁免折叠;背压永不淘汰 |
| P1 | 行为七类 click/expo/pageview/hide/show/leave/track | 批量、内容指纹折叠去重、fire-and-forget |
| P2 | 错误六子类 + performance + 未知类型 | 批量、折叠;背压最先淘汰(P0 永不被挤出) |
唯一发送方式 = fetch keepalive
常规 flush、补发、卸载兜底都走 fetch keepalive,没有 sendBeacon。可靠性靠批量 + localStorage 两点写盘 + 离线存储(IndexedDB → 内存两级降级)兜底;没有重试矩阵(产品决定交后端幂等)。个别上报失败属预期,不要依赖端侧重试。
相关
- 架构总览:这条链路在六层里的位置
- 插件与能力装配:RawEvent 从哪来
- 远端配置治理:killSwitch / 采样如何在管线里筛事件
- API Reference(自动生成)