@blueking/open-telemetry 0.0.22 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +256 -70
  2. package/dist/bk-rum.global.js +2 -2
  3. package/dist/bk-rum.global.js.map +1 -1
  4. package/dist/core/config.d.ts +4 -2
  5. package/dist/core/processor.d.ts +2 -2
  6. package/dist/core/runtime-context.d.ts +4 -0
  7. package/dist/core/sampling.d.ts +0 -1
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.js +395 -477
  10. package/dist/index.js.map +1 -1
  11. package/dist/plugins/blank-screen.d.ts +1 -1
  12. package/dist/plugins/common.d.ts +3 -4
  13. package/dist/plugins/web-vitals.d.ts +0 -5
  14. package/dist/schema/attributes.d.ts +6 -8
  15. package/dist/schema/span.d.ts +24 -15
  16. package/package.json +1 -1
  17. package/skills/bk-rum-otele/SKILL.md +26 -23
  18. package/skills/bk-rum-otele/references/actions.md +166 -0
  19. package/skills/bk-rum-otele/references/api.md +248 -215
  20. package/skills/bk-rum-otele/references/architecture.md +139 -37
  21. package/skills/bk-rum-otele/references/blank-screen.md +190 -0
  22. package/skills/bk-rum-otele/references/capabilities.md +175 -83
  23. package/skills/bk-rum-otele/references/configuration.md +226 -151
  24. package/skills/bk-rum-otele/references/data-model.md +156 -24
  25. package/skills/bk-rum-otele/references/errors-security.md +168 -0
  26. package/skills/bk-rum-otele/references/extensions.md +236 -0
  27. package/skills/bk-rum-otele/references/framework-integration.md +318 -75
  28. package/skills/bk-rum-otele/references/getting-started.md +186 -70
  29. package/skills/bk-rum-otele/references/network.md +258 -0
  30. package/skills/bk-rum-otele/references/performance.md +197 -0
  31. package/skills/bk-rum-otele/references/privacy.md +236 -67
  32. package/skills/bk-rum-otele/references/production.md +264 -0
  33. package/skills/bk-rum-otele/references/session-context.md +185 -0
  34. package/skills/bk-rum-otele/references/telemetry-reference.md +479 -51
  35. package/skills/bk-rum-otele/references/transport-sampling.md +318 -32
  36. package/skills/bk-rum-otele/references/troubleshooting.md +341 -151
  37. package/skills/bk-rum-otele/references/views-routing.md +211 -0
  38. package/skills/bk-rum-otele/references/concepts.md +0 -60
  39. package/skills/bk-rum-otele/references/custom-plugin.md +0 -170
  40. package/skills/bk-rum-otele/references/plugins-basic.md +0 -135
  41. package/skills/bk-rum-otele/references/plugins-error-security.md +0 -83
  42. package/skills/bk-rum-otele/references/plugins-experience.md +0 -124
  43. package/skills/bk-rum-otele/references/plugins-network.md +0 -32
  44. package/skills/bk-rum-otele/references/plugins.md +0 -62
@@ -1,56 +1,484 @@
1
1
  <!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
2
2
 
3
- # 遥测参考
4
-
5
- SDK 只产出 RUM Span,不产出 OpenTelemetry Metric 或 Log。计数、直方图、分位数和错误分组由服务端从原始 Span 派生。
6
-
7
- ## 公共字段
8
-
9
- | 字段 | 类型 | 说明 |
10
- | --- | --- | --- |
11
- | `event.id` | string | 每条原始事件的唯一 ID,服务端去重键 |
12
- | `event.type` | string | `session`、`view`、`resource`、`error`、`vital`、`action`、`websocket` 等 |
13
- | `event.phase` | string | 生命周期事件阶段;非生命周期事件可不带 |
14
- | `event.timestamp` | number | 浏览器事件发生的 epoch ms |
15
- | `session.id` | string | Session 关联 ID |
16
- | `session.start_time` | number | Session 开始时间 |
17
- | `session.type` | string | 当前为 `user` |
18
- | `session.sample_rate` | number | Resource 字段,范围 `0..1` |
19
- | `view.id` | string | View 关联 ID |
20
- | `view.name` | string | View 名称 |
21
- | `view.url` | string | 脱敏后的 URL |
22
- | `view.url_path_group` | string | 服务端聚合用路由模板 |
23
- | `action.id` | string/string[] | Action 关联 ID |
24
- | `span_type` / `span_subtype` | string | RUM 分类 |
25
- | `result` / `error_type` | string | 单事件结果分类 |
3
+ # 遥测字段字典
4
+
5
+ 本页是当前 SDK 实际产出的 RUM Span、Resource Attribute、Span Attribute 和 Span Event 字典。它面向 Collector 接入、后端建模、查询规则、告警配置和数据验收。SDK 当前只上报 Trace Span,不产出 OpenTelemetry Metric 或 Log。
6
+
7
+ ## 快速定位
8
+
9
+ 一条 RUM Span 的信息按以下层级组合。建模时应保持层级分工,不要把所有字段压成一套无差别标签:
10
+
11
+ | 层级 | 主要字段 | 适合回答的问题 |
12
+ | ---- | -------- | -------------- |
13
+ | SDK 与应用 Resource | `service.*`、`deployment.environment.name`、`telemetry.sdk.*` | 哪个应用、环境、版本和 SDK 产生了数据? |
14
+ | RUM 运行时上下文 | `session.id`、`view.id`、`action.id`、`user.id`、设备和网络字段 | 事件属于哪个 Session、View、Action 和用户上下文? |
15
+ | 公共分类 | `span_type`、`outcome.type`、`outcome.reason` | 这是什么信号,结果是否正常,失败属于哪类原因? |
16
+ | 领域属性 | `resource.*`、`error.*`、`vital.*`、`long_task.*` 等 | 具体发生了什么,耗时、来源和诊断细节是什么? |
17
+ | OTLP Envelope 与 Event | `traceId`、`spanId`、时间戳、`status`、`events` | 如何定位单条记录、关联调用链和读取异常/脚本归因? |
18
+
19
+ 推荐先用 Resource 字段限定应用和环境,再以 `span_type` 选择信号类型,最后使用领域字段细分。Session/View 聚合优先使用 `session.id`、`view.id`;路由聚合优先使用低基数的 `view.url_path_group`,不要直接按完整 URL 或原始 path 建立高基数索引。
20
+
21
+ ## 阅读约定
22
+
23
+ - `类型` 指 OpenTelemetry Attribute Value 类型;数组表示同一字段可以同时关联多个值。
24
+ - `条件` 说明字段何时出现。字段缺失通常表示对应插件未开启、浏览器 API 不支持、事件阶段不适用或浏览器未暴露数据,不应直接解释为数值 `0`。
25
+ - `epoch ms` 表示自 1970-01-01 UTC 起的毫秒数;`相对 timeOrigin ms` 表示相对当前文档 `performance.timeOrigin` 的高精度毫秒数;Resource 阶段的 `start` 则相对该 Resource Entry 的 `startTime`。
26
+ - OTLP 的 `traceId`、`spanId`、`startTimeUnixNano` 等 Envelope 字段不是 Span Attribute,查询时要与 `attributes` 下的 RUM 字段区分。
27
+ - 未注明 Span Kind 的内置 Span 为 `INTERNAL`;请求、静态资源和 WebSocket Span 为 `CLIENT`。
28
+ - URL 字段是否脱敏以各表说明为准。业务仍应通过 `redactUrl` 和 `redactAttributes` 清理 token、用户标识等敏感信息。
29
+
30
+ ## 上报准入与字段覆盖
31
+
32
+ 字段存在不等于 Span 一定会被导出。当前采集链路依次受以下条件约束:
33
+
34
+ 1. SDK 必须启用、获得采集授权,并且当前 Session 命中确定性采样。
35
+ 2. 普通 Span 导出时必须同时具备有效的 `session.id` 和 `view.id`;`browser.session` 是唯一例外,它允许没有 View,但仍必须属于已采样 Session。
36
+ 3. 指向 SDK Collector 自身的请求会被过滤;请求级 `tracking.request.beforeSend` 和全局 `tracking.beforeSend` 返回 `false` 时也会丢弃 Span。
37
+
38
+ 因此,插件已开启但没有数据时,应先检查授权、`session.sample_rate`、Session/View 是否已建立、浏览器能力和 beforeSend 过滤,而不是只检查字段解析。
39
+
40
+ 属性合并和脱敏遵循以下优先级:
41
+
42
+ - SDK 原生 Span 先带入运行时上下文,再由本次事件属性覆盖同名字段,合并结果统一经过 `redactAttributes`。
43
+ - `reportAction`、`reportCustomEvent` 的 payload Attribute 位于固定 RUM 分类字段之前,不能覆盖 `span_type`、`outcome.*` 和对应事件标识字段。
44
+ - `startView({ attributes })` 会过滤 SDK 保留字段;这些属性在 View 有效期内成为运行时上下文,并随该 View 的 Span 上报。
45
+ - 第三方 Instrumentation 已写入的 Attribute 优先,SDK 只补齐缺失的运行时属性。第三方自身字段不会自动经过 `redactAttributes`,需要在 Instrumentation 配置或全局 `tracking.beforeSend` 中另行治理。
46
+
47
+ ## OTLP Span Envelope
48
+
49
+ 每条 Span 除 RUM Attribute 外还包含 OpenTelemetry 标准字段:
50
+
51
+ | OTLP 字段 | 类型/格式 | 条件 | 详细说明 |
52
+ | ------------------- | ------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
53
+ | `traceId` | 32 位十六进制字符串 | 必有 | 16 字节 Trace ID。同一条调用链上的 Span 使用同一个值,可用于串联用户操作、前端请求和已传播 Trace Context 的后端链路。 |
54
+ | `spanId` | 16 位十六进制字符串 | 必有 | 当前 Span 的 8 字节唯一 ID,与 `traceId` 一起唯一定位本次 Span。 |
55
+ | `parentSpanId` | 16 位十六进制字符串 | 有活动父 Span 时 | 父 Span ID。没有活动父上下文的 RUM 根 Span不包含该字段;缺失不代表数据异常。 |
56
+ | `name` | string | 必有 | Span 名称,例如 `browser.view`、`browser.resource`。稳定一级分类使用 `span_type`,具体类别使用各领域字段查询。 |
57
+ | `kind` | enum number/string | 必有 | OpenTelemetry Span Kind。SDK 内置值为 `INTERNAL` 或 `CLIENT`;不同 OTLP JSON 实现可能编码为枚举数字或名称。 |
58
+ | `startTimeUnixNano` | epoch ns 字符串 | 必有 | Span 开始时间。OTLP JSON 使用十进制字符串保存纳秒整数,避免 JavaScript Number 精度丢失。 |
59
+ | `endTimeUnixNano` | epoch ns 字符串 | 必有 | Span 结束时间。瞬时生命周期事件通常与开始时间相同;Resource Span 的差值表示请求或资源加载耗时。 |
60
+ | `attributes` | key-value[]/object | 可选 | 本页记录的 Resource 之外的字段位于这里。具体 JSON 形态取决于 Collector/Exporter 是否已将 OTLP KeyValue 数组展开。 |
61
+ | `events` | event[] | 可选 | Span 内的时间点事件。当前包括 `exception`、`long_task.script` 和 `long_task.attribution`。每个 Event 有独立时间戳和 Attributes。 |
62
+ | `status` | object | 可选 | OpenTelemetry 状态。三类自动浏览器错误、带 Error 的自定义事件和失败请求可能设置 `ERROR`;未设置通常表示 `UNSET`,不等同于业务字段 `outcome.type=success`。白屏、CSP、WebSocket 错误目前只写 RUM Outcome,不设置 OTLP Status。 |
63
+
64
+ ## Resource Attribute
65
+
66
+ Resource Attribute 描述产生 Span 的 SDK 实例和运行环境,同一实例的所有 Span 共用:
67
+
68
+ | 字段 | 类型 | 条件 | 来源与详细说明 |
69
+ | -------------------------------- | ------ | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
70
+ | `service.name` | string | 必有 | 来自 `application.name`。标识被监控的前端应用,是按应用聚合、路由和授权的主维度。 |
71
+ | `service.version` | string | 配置 `application.version` 时 | 来自应用版本配置,通常填写发布版本或构建号,用于比较发布前后性能和错误变化。 |
72
+ | `deployment.environment.name` | string | 必有 | 来自 `application.environment`,未配置时为 `production`。用于区分生产、预发布、测试等环境。 |
73
+ | `session.sample_rate` | number | 必有 | 解析后的 `session.sampleRate`,范围 `0..1`。表示配置的 Session 采样概率,不表示当前某条 Span 的采样结果。 |
74
+ | `telemetry.sdk.name` | string | 必有 | 固定为 `@blueking/open-telemetry`,用于识别数据生产 SDK。 |
75
+ | `telemetry.sdk.language` | string | 必有 | 固定为 `webjs`,表示浏览器 JavaScript SDK。 |
76
+ | `telemetry.sdk.version` | string | 必有 | 当前 npm 包版本,用于排查字段能力或采集行为是否受 SDK 版本影响。 |
77
+ | `browser.name` | string | `tracking.device !== false` 且有浏览器环境 | 从 User-Agent 识别,取值 `Edge`、`Chrome`、`Firefox`、`Safari` 或 `Other`。识别不到时为 `Other`。 |
78
+ | `browser.version` | string | 能识别浏览器版本时 | 从 User-Agent 提取的浏览器主版本号,不包含次版本和补丁版本;识别不到时缺失。 |
79
+ | `os.name` | string | `tracking.device !== false` 且有浏览器环境 | 从 User-Agent / User-Agent Client Hints 推断,取值 `iOS`、`Android`、`macOS`、`Windows`、`Linux` 或 `Other`。 |
80
+ | `device.type` | string | `tracking.device !== false` 且有浏览器环境 | `mobile` 或 `desktop`。根据 `userAgentData.mobile` 或移动端 User-Agent 特征推断,不代表具体硬件型号。 |
81
+ | `device.memory_gib` | number | 浏览器支持 `navigator.deviceMemory` 时 | 浏览器提供的近似设备内存容量,单位 GiB。该值通常已分档并可能受隐私策略限制,不应当作精确物理内存。 |
82
+ | `device.logical_processor_count` | number | 浏览器支持 `navigator.hardwareConcurrency` 时 | 浏览器暴露的逻辑处理器数量,可辅助分析低端设备性能;可能因浏览器隐私策略而低于真实数量。 |
83
+
84
+ `tracking.device=false` 时 SDK 构造的 Resource 不写入设备 Resource 字段。Resource 在 SDK 初始化时经过一次 `redactAttributes`,运行期间不会随窗口或网络状态变化。
85
+
86
+ ## 运行时公共属性
87
+
88
+ 普通 Span 创建时会继承创建时刻的运行时上下文;历史事件可按事件发生时间回查当时的 Session、View 和 Action 关联关系。
89
+
90
+ | 字段 | 类型 | 条件 | 来源与详细说明 |
91
+ | ------------------------- | -------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
92
+ | `user.id` | string | 调用 `setUser({ id })` 后 | 业务提供的用户 ID,SDK 原样写入并经过 `redactAttributes`。建议使用不可逆标识,避免直接上传手机号、邮箱等个人信息。 |
93
+ | `session.id` | string | Session 有效 | SDK 生成的 Session 关联 ID。15 分钟无活动或 4 小时最大生命周期到期后会更换;同一 Session 的事件可用它聚合。 |
94
+ | `session.start_time` | number | Session 有效 | Session 创建时间,单位 epoch ms。它不会因用户活动续期而变化,可用于计算 Session 相对时间。 |
95
+ | `session.type` | string | Session 有效 | 当前固定为 `user`,为未来区分其他 Session 类型保留。 |
96
+ | `session.has_replay` | boolean | Session 有效 | 当前固定为 `false`,表示 SDK 没有随该 Session 上报 Session Replay 数据。 |
97
+ | `view.id` | string | View 有效 | 当前页面视图的关联 ID。首次加载、有效 SPA 路由变化、BFCache 恢复或 Session 续建都会创建新 View。 |
98
+ | `view.name` | string | View 有效 | View 的可读名称。默认取路由分组,也可由 `startView` 或 `setViewName` 设置,适合展示和聚合。 |
99
+ | `view.url` | string | View 有效 | 创建 View 时的完整 URL,经 `redactUrl` 脱敏。与当前实时 `location.href` 不一定相同。 |
100
+ | `view.url_path_group` | string | View 有效 | 低基数路由模板。默认把数字 ID、UUID 和长十六进制路径段归一为 `:id`,也可由 `getPathGroup` 自定义。 |
101
+ | `view.loading_type` | string | View 有效 | View 创建类型:`initial_load` 首次文档加载、`route_change` SPA 路由、`bf_cache` BFCache 恢复、`session_renewal` Session 到期后续建。 |
102
+ | `action.id` | string[] | 自动 Action 活动中 | 与当前 Span 同时相关的自动 Action ID 数组;允许多个点击 Action 生命周期重叠。注意 Action Span 自身的同名字段是单个 string。 |
103
+ | `device.id` | string | Device 插件开启 | SDK 生成的匿名设备关联 ID。默认仅在本次插件生命周期内稳定;`persistentId: true` 时写入 localStorage,从而跨页面和 Session 保持。 |
104
+ | `browser.viewport.width` | number | 浏览器环境 | 当前 CSS viewport 宽度,单位 CSS px,来源 `window.innerWidth`;窗口 resize/屏幕旋转后更新到后续 Span。 |
105
+ | `browser.viewport.height` | number | 浏览器环境 | 当前 CSS viewport 高度,单位 CSS px,来源 `window.innerHeight`。 |
106
+ | `browser.screen.width` | number | 浏览器提供 `window.screen` 时 | 当前屏幕宽度,单位 CSS px;不是物理像素,不能直接推导设备分辨率。 |
107
+ | `browser.screen.height` | number | 浏览器提供 `window.screen` 时 | 当前屏幕高度,单位 CSS px;不是当前网页可用区域高度。 |
108
+ | `network.effective_type` | string | Network Information API 支持 | 浏览器估算的有效网络类型,常见为 `slow-2g`、`2g`、`3g`、`4g`。它反映体验模型,不等同于真实无线制式。 |
109
+ | `network.connection_type` | string | 浏览器提供 `connection.type` 时 | 浏览器返回的原始连接类型,例如 `wifi`、`cellular`、`ethernet`;多数 Safari/Firefox 环境可能缺失。 |
110
+ | `network.downlink` | number | Network Information API 支持 | 浏览器估算的下行带宽,单位 Mbps,通常经过舍入;网络变化后更新到后续 Span。 |
111
+ | `network.rtt` | number | Network Information API 支持 | 浏览器估算的往返时延,单位 ms,通常经过舍入;不是当前某个 Resource 请求的实测 RTT。 |
112
+ | `network.save_data` | boolean | Network Information API 支持 | 用户是否开启节省流量偏好;`true` 可用于解释图片降质或资源加载策略差异。 |
113
+
114
+ 默认 `context.attributes.page()` 返回空对象,不附加独立页面属性。页面地址使用 View 创建时冻结并经过 `redactUrl` 的 `view.url`,低基数路由聚合使用 `view.url_path_group`;业务需要额外页面维度时可自定义该 Hook。
115
+
116
+ ## RUM 公共分类字段
117
+
118
+ | 字段 | 类型 | 条件 | 来源与详细说明 |
119
+ | ---------------- | ------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
120
+ | `span_type` | string | 所有 SDK 原生 RUM Span | 稳定的 RUM 一级分类:`session`、`view`、`resource`、`error`、`vital`、`long_task`、`action`、`websocket` 或 `custom`。 |
121
+ | `outcome.type` | string | 所有 SDK 原生 RUM Span | 归一结果:`success`、`warning`、`error`、`timeout` 或 `abort`。Fetch/XHR 主动取消使用 `abort`。 |
122
+ | `outcome.reason` | string | 需要解释非正常结果时 | 当前内置值包括 `network`、`network_timeout`、`http_4xx`、`http_5xx`、`blank_screen` 和 `csp`。正常结果以及可由领域字段完整表达的结果不写该字段。 |
123
+
124
+ `outcome.type` 是 RUM 查询维度,OTLP `status` 是 OpenTelemetry 状态,二者用途不同。例如 Web Vital 评级不佳时为 `outcome.type=warning`,但不会把 OTLP Status 设置为 `ERROR`。
26
125
 
27
126
  ## Span 清单
28
127
 
29
- | Span 名 | `event.type` | 关键字段 |
30
- | --- | --- | --- |
31
- | `browser.session` | `session` | `event.phase=start\|rotate\|end`、`session.lifecycle.reason`、`session.previous_id` |
32
- | `browser.view` | `view` | `event.phase=start\|update\|end`、`view.version`、`view.started_at`、`view.loading_type`、`view.loading_time`、`view.end_reason` |
33
- | `browser.resource` | `resource` | `url.full`、`resource.type`、HTTP 状态、体积和 Resource Timing 阶段 |
34
- | `browser.error` | `error` | `error.source=window.error`、`error.message`、代码位置;完整异常写入标准 exception event |
35
- | `browser.unhandledrejection` | `error` | `error.source=unhandledrejection`、`error.message`、标准 exception event |
36
- | `browser.resource_error` | `error` | `error.source=resource`、`url.full`、`html.tag` |
37
- | `browser.web_vital` | `vital` | `vital.metric`、`vital.value`、`vital.rating`、`vital.id` 和 attribution |
38
- | `action.click` | `action` | `action.loading_time`、目标和 `action.frustration.type`;不含资源/错误/长任务计数 |
39
- | `action.custom` | `action` | 手动 Action 名称和属性 |
40
- | `browser.blank_screen` | `error` | 白屏采样点、比例、根节点和原因 |
41
- | `browser.long_task` | `long_task` | Long Task/LoAF 原始耗时;LoAF 脚本和旧 API attribution span event;仅 LoAF 带原生 blocking duration |
42
- | `csp.violation` | `error` | CSP violation 原始字段;不做指纹或客户端节流 |
43
- | `browser.websocket` | `websocket` | `event.phase=connect\|open\|error\|close`、`websocket.connection.id`、关闭码;不采集消息 |
44
- | `custom.<name>` | `custom` | 手动自定义事件属性和可选异常 |
45
-
46
- ## View 本地语义
47
-
48
- `view.loading_time`、CLS、INP、Action Loading Time、挫败信号和白屏必须依赖浏览器活动窗口或 DOM/Performance API,在 SDK 本地计算后作为事件语义上报。View 的每次 start/update/end 都增加 `view.version`;服务端应按 `view.id + view.version` 幂等合并,并容忍乱序到达。
49
-
50
- ## 服务端派生要求
51
-
52
- - 使用 `event.id` 去重。
53
- - 通过 `session.id`、`view.id`、`action.id` 关联事件。
54
- - 从原始事件计算 View/Session 时长、资源/错误/Action 数量和错误率。
55
- - 从 `vital.value`、资源/长任务耗时计算 Histogram 与分位数。
56
- - 在服务端生成错误指纹、错误组和风暴控制,不在浏览器丢弃原始错误。
128
+ | Span 名 | Kind | `span_type` | 领域分类字段 | 默认状态/入口 | 表达的事件 |
129
+ | ---------------------------- | -------- | ----------- | --------------------------------- | ------------------------------ | -------------------------------------------------- |
130
+ | `browser.session` | INTERNAL | `session` | `session.phase` | 始终随 SDK 启动 | Session 创建、轮换和结束生命周期。 |
131
+ | `browser.view` | INTERNAL | `view` | `view.phase`、`view.source` | 自动;可切为手动 View | 初始页面或 SPA View 的 start/update/end 快照。 |
132
+ | `browser.resource` | CLIENT | `resource` | `resource.type` | 请求、静态资源默认开启 | Fetch、XHR 或静态资源加载。 |
133
+ | `browser.error` | INTERNAL | `error` | `error.source=window.error` | 错误采集默认开启 | `window.error` 捕获的 JavaScript 运行时错误。 |
134
+ | `browser.unhandledrejection` | INTERNAL | `error` | `error.source=unhandledrejection` | 错误采集默认开启 | 未处理的 Promise rejection。 |
135
+ | `browser.resource_error` | INTERNAL | `error` | `error.source=resource` | 错误采集默认开启 | script、img、link、media 等元素资源加载失败。 |
136
+ | `browser.web_vital` | INTERNAL | `vital` | `vital.metric` | 默认开启 | 单项用户体验指标及归因。 |
137
+ | `action.click` | INTERNAL | `action` | `action.type=click` | 自动 Action 默认开启 | 自动点击 Action 及其页面活动、错误和挫败归因。 |
138
+ | `action.custom` | INTERNAL | `action` | `action.type=custom` | `reportAction` | 主动上报的业务 Action。 |
139
+ | `browser.blank_screen` | INTERNAL | `error` | `blank_screen.reason` | 默认开启 | 视口九宫格连续检测确认的白屏。 |
140
+ | `browser.long_task` | INTERNAL | `long_task` | `long_task.entry_type` | `tracking.longTask`,默认关闭 | Long Animation Frame,或不支持时回退的 Long Task。 |
141
+ | `csp.violation` | INTERNAL | `error` | `error.source=csp` | `tracking.cspViolation`,默认关闭 | 浏览器 `securitypolicyviolation` 事件。 |
142
+ | `browser.websocket` | CLIENT | `websocket` | `websocket.phase` | `tracking.websocket`,默认关闭 | 同一 WebSocket 连接的四类生命周期事件。 |
143
+ | `custom.<name>` | INTERNAL | `custom` | Span 名 | `reportCustomEvent` | 主动上报的业务事件。 |
144
+
145
+ ## Session 字段
146
+
147
+ 适用于 `browser.session`。Session 默认在 15 分钟无活动后过期,并受 4 小时最大生命周期限制。
148
+
149
+ | 字段 | 类型 | 条件/取值 | 来源与详细说明 |
150
+ | -------------------------- | ------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
151
+ | `session.phase` | string | `start`、`rotate`、`end` | `start` 表示没有可复用记录时创建;`rotate` 表示旧 Session 到期后创建新 Session;`end` 表示当前 Session 失效。 |
152
+ | `session.id` | string | 所有阶段 | 当前生命周期事件所描述的 Session ID。`end` 事件写旧 ID,`rotate` 事件写新 ID。 |
153
+ | `session.start_time` | number | 所有阶段,epoch ms | 该 Session 最初创建时间。`end` 时仍保留原始开始时间,不是结束时间。 |
154
+ | `session.type` | string | 所有阶段,固定 `user` | 表示按真实用户浏览活动划分的 Session。 |
155
+ | `session.has_replay` | boolean | 所有阶段,固定 `false` | 明确当前 SDK 没有为该 Session 关联回放数据。 |
156
+ | `session.lifecycle.reason` | string | 所有阶段 | `init`:初始化时创建;`inactivity`:15 分钟无活动;`maxLifetime`:达到 4 小时上限;`external`:共享存储被删除、替换或记录无效,导致本 Tab 当前 Session 失效。 |
157
+ | `session.previous_id` | string | `rotate` 且能识别旧 Session 时 | 新 Session 的前一个 ID,用于串联因 `inactivity` 或 `maxLifetime` 发生的轮换。首次 `start` 通常缺失。 |
158
+
159
+ Session Span 允许没有 `view.id`:SDK 先建立 Session,再创建初始 View;结束 Session 时也会先结束当前 View。
160
+
161
+ ## View 字段
162
+
163
+ 适用于 `browser.view`。同一 View 会产生多条版本递增的生命周期快照,而不是一条持续到页面离开的长 Span。
164
+
165
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
166
+ | -------------------------- | ------ | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
167
+ | `view.phase` | string | `start`、`update`、`end` | `start` 创建 View;`update` 写入自动/手动 Loading Time 或名称更新;`end` 关闭 View。 |
168
+ | `view.source` | string | 所有阶段 | 创建来源会沿用到该 View 后续事件:`load`、`manual`、`pushState`、`replaceState`、`popstate`、`hashchange`、`bfCache`、`sessionRenewal`。 |
169
+ | `view.id` | string | 所有阶段 | View 关联 ID。同一 View 的 start/update/end 使用相同值,可与该 View 内其他 Span 关联。 |
170
+ | `view.version` | number | 从 1 递增 | 每次 `emitViewEvent` 递增;用于恢复同一 View 生命周期快照的先后顺序。 |
171
+ | `view.started_at` | number | epoch ms | View 开始时间。初始 View 使用 `performance.timeOrigin`,路由/BFCache/续建 View 使用创建时刻。 |
172
+ | `view.name` | string | 所有阶段 | 默认取 `view.url_path_group`,也可由 `startView({ name })` 或 `setViewName` 设置。 |
173
+ | `view.url` | string | 所有阶段 | 创建 View 时的 URL,经 `redactUrl` 脱敏;在该 View 生命周期内保持不变。 |
174
+ | `view.url_path_group` | string | 所有阶段 | 低基数路由分组。数字 ID、UUID、长十六进制段默认折叠为 `:id`,用于稳定聚合动态路由。 |
175
+ | `view.loading_type` | string | 所有阶段 | `initial_load`、`route_change`、`bf_cache` 或 `session_renewal`,含义见运行时公共属性。 |
176
+ | `view.loading_time` | number | 计算完成后,ms | 从 `view.started_at` 到页面活动稳定的耗时。初始加载同时等待 load event 和页面活动,以较晚者为准;可由 `setViewLoadingTime()` 手动结束。 |
177
+ | `view.loading_time.source` | string | 有 `view.loading_time` 时 | `auto` 表示 SDK 自动观察页面活动;`manual` 表示业务调用 `setViewLoadingTime()`。 |
178
+ | `view.end_reason` | string | 仅 `end` | 结束原因:路由来源值、`manual`、`bfcache`、`pagehide`、`session_expired` 或 `shutdown`。它说明为何关闭旧 View,不是新 View 的加载类型。 |
179
+ | `url.previous` | string | 所有阶段 | 创建 View 时记录的前序 URL,经 `redactUrl` 脱敏;初始 View 通常为空字符串。 |
180
+ | `document.referrer` | string | 仅 `initial_load` | `document.referrer` 经 `redactUrl` 脱敏;没有来源页面时为空字符串。 |
181
+ | `view.first_byte` | number | 仅初始 View 且 Navigation Timing 有值,相对 timeOrigin ms | `PerformanceNavigationTiming.responseStart`,表示导航开始到收到响应首字节的时间。 |
182
+ | `view.dom_interactive` | number | 同上 | `domInteractive`,表示 HTML 解析完成、文档进入 interactive 状态的时间点。 |
183
+ | `view.dom_content_loaded` | number | 同上 | `domContentLoadedEventEnd`,表示 DOMContentLoaded 事件处理完成的时间点。 |
184
+ | `view.dom_complete` | number | 同上 | `domComplete`,表示文档及其依赖资源处理完成并进入 complete 状态的时间点。 |
185
+ | `view.load_event` | number | 同上 | `loadEventEnd`,表示 window load 事件处理完成的时间点。值为 `0` 或非有限数时不写入。 |
186
+
187
+ 只有 pathname 或具有路由意义的 hash path 变化才自动创建新 View;仅 query 或锚点变化不会创建,因此不能假设每次地址栏变化都有新的 `view.id`。
188
+
189
+ ## 请求与静态资源字段
190
+
191
+ 适用于 `browser.resource`。Fetch/XHR 由请求插件建 Span,再合并匹配的 Resource Timing;静态资源由 Resource Observer 直接建 Span。
192
+
193
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
194
+ | --------------------------------- | ------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
195
+ | `url.full` | string | 有有效请求/资源 URL | 绝对 URL,经 `redactUrl` 脱敏。用于定位请求目标;不要假设 query 中仍保留原始参数。 |
196
+ | `server.address` | string | URL 可解析 | URL 的 `hostname`,不含端口。相对 URL 会基于当前页面地址解析。 |
197
+ | `server.port` | number | URL 显式包含端口 | URL 的显式端口号。使用协议默认端口且 URL 未写端口时缺失。 |
198
+ | `resource.type` | string | 必有 | Fetch/XHR 为 `fetch`/`xhr`;静态资源使用 `PerformanceResourceTiming.initiatorType`,为空时为 `other`,常见还有 `script`、`link`、`img`、`css`。 |
199
+ | `http.request.method` | string | Fetch/XHR | 归一为大写的 HTTP 方法,例如 `GET`、`POST`。静态资源通常没有可用的请求方法,因此缺失。 |
200
+ | `http.response.status_code` | number | 获得真实 HTTP Response | HTTP 响应状态,只写大于 `0` 的有效状态码。abort、timeout、网络失败和 opaque Response 没有可用状态码时缺失,不使用 `0` 代替。 |
201
+ | `resource.size` | number | 静态资源 Span 且浏览器提供 `transferSize` | `transferSize`,单位 bytes,通常包含响应头和编码后的响应体;受 Timing-Allow-Origin 和缓存影响,可能为 `0`。Fetch/XHR 合并 Resource Timing 时当前不会复制该字段,应改用 encoded/decoded size 判断响应体规模。 |
202
+ | `resource.protocol` | string | 浏览器提供 `nextHopProtocol` | 实际传输协议,例如 `h2`、`h3`、`http/1.1`;浏览器无法判断时可能返回空字符串。 |
203
+ | `resource.cache.hit` | boolean | SDK 能推断命中缓存时 | 只在 `deliveryType=cache`,或 `transferSize=0` 且 `decodedBodySize>0` 时写 `true`。没有该字段表示“无法确认命中”,不是明确的 `false`。 |
204
+ | `resource.delivery_type` | string | 浏览器支持 `deliveryType` | 浏览器报告的资源交付方式;原值为空时归一为 `other`。具体枚举随浏览器 Resource Timing 实现演进。 |
205
+ | `resource.render_blocking_status` | string | 浏览器支持 `renderBlockingStatus` | 资源是否阻塞渲染,常见为 `blocking` 或 `non-blocking`,适合定位影响首屏的 CSS/脚本。 |
206
+ | `resource.encoded_body_size` | number | 有 Resource Timing | 编码/压缩后的响应体大小,单位 bytes,不包含响应头。跨域且没有 Timing-Allow-Origin 时可能为 `0`。 |
207
+ | `resource.decoded_body_size` | number | 有 Resource Timing | 解码/解压后的响应体大小,单位 bytes,可与 encoded size 对比压缩收益。 |
208
+
209
+ 网络阶段字段均为 number、单位 ms。每个 `*.start` 相对该 Resource Entry 的 `startTime`,每个 `*.duration` 为对应阶段结束值减开始值:
210
+
211
+ | 字段 | 条件 | 计算口径与使用方式 |
212
+ | ------------------------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------ |
213
+ | `resource.redirect.start` | 存在合法重定向时间且同源/TAO 可见 | `redirectStart - entry.startTime`,表示重定向阶段开始偏移。 |
214
+ | `resource.redirect.duration` | 同上 | `redirectEnd - redirectStart`,表示全部可见重定向耗时。 |
215
+ | `resource.worker.start` | Service Worker 在 fetch 之前介入 | `workerStart - entry.startTime`,表示 Service Worker 启动偏移。 |
216
+ | `resource.worker.duration` | 同上 | `fetchStart - workerStart`,包含 Service Worker 启动及其前置处理时间。 |
217
+ | `resource.dns.start` | 实际发生或浏览器暴露 DNS 阶段 | `domainLookupStart - entry.startTime`。连接复用、缓存或 TAO 限制时可能缺失。 |
218
+ | `resource.dns.duration` | 同上 | `domainLookupEnd - domainLookupStart`,DNS 解析耗时。 |
219
+ | `resource.connect.start` | 实际发生或浏览器暴露连接阶段 | `connectStart - entry.startTime`。连接复用时可能缺失。 |
220
+ | `resource.connect.duration` | 同上 | `connectEnd - connectStart`,包含建立 TCP/其他传输连接以及其中的 TLS 时间。 |
221
+ | `resource.ssl.start` | `secureConnectionStart` 位于连接阶段内 | `secureConnectionStart - entry.startTime`,表示 TLS 握手开始偏移。HTTP 或缺少详细时间时不写。 |
222
+ | `resource.ssl.duration` | 同上 | `connectEnd - secureConnectionStart`,TLS 握手耗时。 |
223
+ | `resource.first_byte.start` | 网络时间点完整且有序 | `requestStart - entry.startTime`,表示请求发送阶段开始偏移。 |
224
+ | `resource.first_byte.duration` | 同上 | `responseStart - requestStart`,表示从开始发送请求到收到响应首字节的耗时,包含网络和服务端处理。 |
225
+ | `resource.download.start` | 网络时间点完整且有序 | `responseStart - entry.startTime`,表示响应下载开始偏移。 |
226
+ | `resource.download.duration` | 同上 | `responseEnd - responseStart`,表示读取响应数据的耗时。 |
227
+
228
+ 如果公共时间点缺失、不是有限数或顺序异常,SDK 会放弃整组阶段字段,避免产生负耗时。Resource Timing 的跨域详细信息还受 `Timing-Allow-Origin` 响应头限制。
229
+
230
+ 请求结果映射:HTTP `408/504` 为 `outcome.type=timeout,outcome.reason=network_timeout`;其他 `4xx` 为 `error/http_4xx`;其他 `5xx` 为 `error/http_5xx`;Fetch AbortError 或 XHR `abort` 为 `abort` 且不写 reason;Fetch TimeoutError 或 XHR `timeout` 为 `timeout/network_timeout`;其他网络失败为 `error/network`;其余为 `success` 且不写 reason。
231
+
232
+ ## 错误字段
233
+
234
+ 三类自动浏览器错误都设置 `outcome.type=error`、OTLP Status `ERROR`,并记录 `exception` Span Event。错误来源由 `error.source` 表达,不重复写入 `outcome.reason`。
235
+
236
+ | 字段 | 类型 | 适用范围 | 来源与详细说明 |
237
+ | -------------------- | ------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
238
+ | `error.message` | string | 三类自动错误 | 归一后的错误消息。Error 使用 `message`,字符串直接使用,其他值优先 JSON 序列化,失败时转为字符串。资源加载错误消息会包含资源原始 URL,应使用 `redactAttributes` 做额外脱敏。 |
239
+ | `error.handled` | boolean | 三类自动错误 | 当前自动采集固定为 `false`,表示该错误来自未处理的全局错误入口;不代表业务代码完全没有 try/catch。 |
240
+ | `error.source` | string | 三类自动错误/CSP | `window.error`、`unhandledrejection`、`resource`;CSP Span 固定为 `csp`。用于区分采集入口。 |
241
+ | `code.filepath` | string | `browser.error` | `ErrorEvent.filename`,即浏览器报告的脚本文件地址。浏览器未提供或跨域屏蔽时可能为空。 |
242
+ | `code.lineno` | number | `browser.error` | `ErrorEvent.lineno`,错误在脚本中的 1-based 行号;浏览器无法定位时可能为 `0`。 |
243
+ | `code.column` | number | `browser.error` | `ErrorEvent.colno`,错误列号;具体是否 0-based 由浏览器实现决定。 |
244
+ | `error.cross_origin` | boolean | 跨域 `Script error.` | 仅当没有 Error 对象和 filename,且消息为 `Script error.` 时写 `true`,用于识别被同源策略屏蔽详情的脚本错误。 |
245
+ | `url.full` | string | `browser.resource_error` | 加载失败元素的 `src`、`href` 或 `currentSrc`,经 `redactUrl` 脱敏。浏览器拿不到资源地址时可能为空字符串。 |
246
+ | `html.tag` | string | `browser.resource_error` | 失败元素的 `tagName`,浏览器通常返回大写,例如 `SCRIPT`、`IMG`、`LINK`,可用于按资源载体分类。 |
247
+
248
+ `context.attributes.error()` 返回的任意业务 Attribute 会合并到三类自动错误 Span,并统一经过 `redactAttributes`。字段命名和类型由接入方负责。
249
+
250
+ ## Exception Span Event
251
+
252
+ 以下场景可能包含名为 `exception` 的 Span Event:三类自动浏览器错误、Fetch timeout/network reject、Fetch/XHR 同步抛出的 Error、带 `error` 的 `custom.<name>`。主动 abort 不记录 exception。Event 字段由 OpenTelemetry `recordException` 生成:
253
+
254
+ | Event 字段 | 类型 | 条件 | 来源与详细说明 |
255
+ | ---------------------- | ------ | ----------------- | --------------------------------------------------------------------------------------------- |
256
+ | `exception.type` | string | 能识别异常类型 | Error 的 `name`,或 SDK 为非 Error 值补充的类型,例如 `UnhandledRejection`、`ResourceError`。 |
257
+ | `exception.message` | string | 能提取异常消息 | Error message 或归一后的异常文本,用于错误检索和展示。 |
258
+ | `exception.stacktrace` | string | Error 带 stack 时 | 浏览器提供的调用栈。跨域、非 Error rejection 或浏览器安全策略可能导致缺失。 |
259
+
260
+ 请求的 HTTP 非成功状态只设置 Span Attribute/Status,不会自动生成 exception Event;只有实际抛出 Error 时才记录异常。
261
+
262
+ ## Web Vitals 字段
263
+
264
+ `browser.web_vital` 上报 CLS、FCP、INP、LCP 和 TTFB。FCP/LCP/TTFB 由 `web-vitals/attribution` 采集导航级指标;CLS/INP 按 SDK View 边界汇总,View 结束时上报。
265
+
266
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
267
+ | --------------------- | ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
268
+ | `vital.metric` | string | 必有 | 指标名的小写值:`cls`、`fcp`、`inp`、`lcp`、`ttfb`。用于同一 Span 名下区分指标。 |
269
+ | `vital.value` | number | 必有 | 指标值。CLS 是无量纲分数;FCP、INP、LCP、TTFB 单位均为 ms。非有限值不会上报。 |
270
+ | `vital.rating` | string | 必有 | `good`、`needs-improvement` 或 `poor`。当前 good/needs-improvement/poor 分界:CLS `≤0.1/≤0.25/>0.25`;INP `≤200/≤500/>500ms`;FCP `≤1800/≤3000/>3000ms`;LCP `≤2500/≤4000/>4000ms`;TTFB `≤800/≤1800/>1800ms`。 |
271
+ | `vital.id` | string | 必有 | 单条 Vital 的唯一 ID。FCP/LCP/TTFB 沿用 `web-vitals` ID;按 View 汇总的 CLS/INP 由 SDK 生成。 |
272
+
273
+ `vital.rating=good` 映射为 `outcome.type=success`;其他评级映射为 `outcome.type=warning`。具体体验评级由 `vital.rating` 表达,不重复写入 `outcome.reason`。
274
+
275
+ ### LCP Attribution
276
+
277
+ | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
278
+ | ---------------------------------- | ------ | ----------------------- | ---------------------------------------------------------------------------------- |
279
+ | `vital.lcp.url` | string | LCP 是图片等 URL 资源时 | LCP 资源 URL,经 `redactUrl` 脱敏。文本 LCP 没有资源 URL,因此缺失。 |
280
+ | `vital.lcp.target` | string | 能定位 LCP 元素时 | `web-vitals` 生成的目标元素选择器/描述,用于定位拖慢最大内容绘制的 DOM 元素。 |
281
+ | `vital.lcp.element_render_delay` | number | ms | LCP 资源加载完成到元素最终绘制之间的耗时;无独立资源时表示等待元素绘制的主要时间。 |
282
+ | `vital.lcp.resource_load_duration` | number | ms | LCP 资源自身从请求开始到响应结束的下载耗时;文本 LCP 或无独立资源时通常为 `0`。 |
283
+ | `vital.lcp.time_to_first_byte` | number | ms | 从导航开始到主文档响应首字节的时间,是 LCP 总耗时的服务端/网络前置部分。 |
284
+
285
+ ### CLS Attribution
286
+
287
+ | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
288
+ | -------------------------------- | ------ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
289
+ | `vital.cls.largest_shift_target` | string | 能定位元素时 | 对 CLS 贡献最大的单次布局偏移中的首个目标元素描述。按 SDK View 汇总时取最大 Session Window 内最大的单次偏移目标。 |
290
+ | `vital.cls.largest_shift_value` | number | 无量纲 | 上述单次布局偏移的分数,不是整个 `vital.value`;可用于判断 CLS 是否由一次大跳动还是多次小跳动组成。 |
291
+ | `vital.cls.load_state` | string | 当前不产生 | 字段提取逻辑已预留,用于表达最大偏移发生时的文档加载阶段;当前 CLS 由 SDK 按 View 自行汇总,未向归因对象写入 load state,因此 Collector 数据中不会出现。 |
292
+
293
+ CLS 忽略 `hadRecentInput=true` 的偏移,并按“相邻偏移间隔小于 1 秒、窗口最长 5 秒”的 Session Window 规则取最大窗口累计值。View 结束时即使没有布局偏移也会上报 `vital.value=0`。
294
+
295
+ ### INP Attribution
296
+
297
+ | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
298
+ | ------------------------------- | ------ | ---------------- | -------------------------------------------------------------------------------------------------------- |
299
+ | `vital.inp.interaction_target` | string | 能定位交互元素时 | 触发 INP 候选交互的元素描述。SDK 优先 `data-bk-action-name`、`aria-label`、`name`,否则使用小写 tag 名。 |
300
+ | `vital.inp.interaction_type` | string | 必有 | SDK 按 View 汇总时为 Performance Event 名,例如 `click`、`keydown`;用于识别哪类输入产生延迟。 |
301
+ | `vital.inp.input_delay` | number | ms | 从用户输入发生到浏览器开始执行事件处理器的延迟,主要反映主线程此前被其他任务占用。 |
302
+ | `vital.inp.processing_duration` | number | ms | 从事件处理开始到处理结束的耗时,主要反映业务事件处理器本身及同步工作。 |
303
+ | `vital.inp.presentation_delay` | number | ms | 事件处理完成到下一帧呈现的耗时,包含样式、布局、绘制、合成等后续工作。三段之和应近似 `vital.value`。 |
304
+
305
+ INP 只在 View 内至少观察到一次带 `interactionId` 的 Event Timing 时上报;Performance Observer 的 `durationThreshold` 为 40ms,值最大限制为 60,000ms。SDK 保留最慢的 10 个交互候选,并按交互数量选择近似 p98 候选。
306
+
307
+ ### FCP Attribution
308
+
309
+ | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
310
+ | ------------------------------ | ------ | --------- | --------------------------------------------------------------------------------------------------------------------- |
311
+ | `vital.fcp.time_to_first_byte` | number | ms | 导航开始到主文档响应首字节的时间。`FCP - TTFB` 可近似观察首字节后到首次内容绘制的前端阶段。 |
312
+ | `vital.fcp.load_state` | string | 必有 | FCP 发生时的文档加载阶段,例如 `loading`、`dom-interactive`、`dom-content-loaded`、`complete`;越早绘制通常体验越好。 |
313
+
314
+ ### TTFB Attribution
315
+
316
+ | 字段 | 类型 | 单位 | 来源与详细说明 |
317
+ | -------------------------------- | ------ | ---- | ---------------------------------------------------------------------------------- |
318
+ | `vital.ttfb.waiting_duration` | number | ms | 从导航激活到浏览器开始处理请求前的等待时间。重定向和其他浏览器前置处理会增加该值。 |
319
+ | `vital.ttfb.dns_duration` | number | ms | 主文档域名 DNS 解析耗时;命中 DNS 缓存、连接复用或 Service Worker 场景可能为 `0`。 |
320
+ | `vital.ttfb.connection_duration` | number | ms | 建立主文档连接的耗时,通常包含 TCP/QUIC 和 TLS;复用连接时可能为 `0`。 |
321
+ | `vital.ttfb.request_duration` | number | ms | 连接结束到收到响应首字节的剩余时间,包含请求发送、网络往返和服务器处理。 |
322
+
323
+ Attribution 字段受浏览器能力和指标实现影响,缺失不代表指标本身无效。当前 SDK 有意只选取诊断价值较高的标量字段,不上传原始 Performance Entry、DOM 节点或完整归因对象。
324
+
325
+ ## Action 字段
326
+
327
+ | 字段 | 类型 | 自动 Click | 手动 Action | 来源与详细说明 |
328
+ | ------------------------- | -------- | ------------------------ | -------------- | --------------------------------------------------------------------------------------------------------- |
329
+ | `action.id` | string | 必有 | 必有 | 当前 Action 的唯一 ID。自动 Action 活动期间,其他 Span 上的同名运行时字段会是 `string[]`。 |
330
+ | `action.type` | string | 固定 `click` | 固定 `custom` | 区分自动点击和 `reportAction` 主动上报。 |
331
+ | `action.name` | string | `Click on <target>` | payload `name` | 可读名称。自动点击目标名默认来自显式 `data-bk-action-name`,启用文本采集后才会回退到可访问名称/DOM 文本。 |
332
+ | `action.target.name` | string | 必有 | 不写 | 自动点击提取的目标名称,最多 100 字符;默认隐私模式下未显式命名时通常为小写 tag 名。 |
333
+ | `action.target.tag` | string | 必有 | 不写 | 实际点击目标的原始 `tagName`,SDK 转为小写,用于按按钮、链接等元素类型聚合。 |
334
+ | `action.loading_time` | number | 点击后有可观察页面活动时 | 不写 | 单位 ms,从点击发生到相关请求、资源、Long Task、DOM 活动安静的耗时;无页面副作用时不写,而不是 `0`。 |
335
+ | `action.frustration.type` | string[] | 检出挫败信号时 | 不写 | 可包含 `rage_click`、`dead_click`、`error_click`;一次 Action 可同时命中多个值。 |
336
+
337
+ `rage_click` 表示 1 秒内、100px 范围内连续至少三次点击;`dead_click` 表示点击后没有页面活动、输入、滚动或选择等反馈(链接、表单输入等会排除);`error_click` 表示 Action 生命周期内出现错误。有错误或任一挫败信号时为 `outcome.type=warning`,具体类型只由 `action.frustration.type` 表达。
338
+
339
+ `reportAction({ attributes })` 的业务 Attribute 会合并到 `action.custom`,但固定分类和事件字段由 SDK 写入。业务应避免复用本页保留字段名。
340
+
341
+ ## 白屏字段
342
+
343
+ 白屏插件在页面活动稳定后对视口九宫格采样,并在默认 200ms 间隔后再次确认;每个 View 最多上报一次。
344
+
345
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
346
+ | ----------------------------------- | ------- | ------------------ | -------------------------------------------------------------------------------------------------- |
347
+ | `blank_screen.reason` | string | 必有 | `missing_root`:配置的根节点不存在;`empty_viewport`:根节点存在,但有效采样点的空白比例达到阈值。 |
348
+ | `blank_screen.empty_ratio` | number | `0..1` | `empty_sample_count / valid_sample_count`。默认阈值为 `0.8`;根节点缺失时固定为 `1`。 |
349
+ | `blank_screen.sample_count` | number | 必有,当前固定 `9` | 视口 20%、50%、80% 横纵坐标组合形成的九宫格总采样点数。 |
350
+ | `blank_screen.valid_sample_count` | number | 必有 | 参与空白比例计算的点数,等于总采样点减去 ignored 点。为 `0` 时不报告白屏。 |
351
+ | `blank_screen.empty_sample_count` | number | 必有 | 有效采样点中,没有发现根节点内可见内容元素的点数。 |
352
+ | `blank_screen.ignored_sample_count` | number | 必有 | 命中 loading、Skeleton 或业务 `ignoreSelectors` 的点数;这些点从比例分母中排除。 |
353
+ | `blank_screen.root_selector` | string | 必有 | 实际检测使用的根节点 CSS selector,默认 `body`。用于判断是否因挂载点配置错误产生 `missing_root`。 |
354
+ | `blank_screen.root_found` | boolean | 必有 | 是否找到根节点。`false` 与 `reason=missing_root` 对应。 |
355
+ | `blank_screen.center_element` | string | 必有,可能为空 | 视口中心最上层元素的小写 tag,存在 ID 时为 `tag#id`;用于快速判断遮罩、容器或空 body。 |
356
+
357
+ 该 Span 固定为 `outcome.type=error,outcome.reason=blank_screen`,但检测是基于采样点的启发式判断,应结合截图、错误和 View 数据进一步确认。
358
+
359
+ ## Long Task 字段
360
+
361
+ 支持 Long Animation Frame API 时优先采集其脚本归因;否则回退到 Long Tasks API。默认阈值为 50ms。
362
+
363
+ ### Span 顶层字段
364
+
365
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
366
+ | ------------------------------------ | ------ | ------------------------------- | -------------------------------------------------------------------------------------------------- |
367
+ | `long_task.id` | string | 必有 | 当前 Long Task/LoAF 事件的随机唯一 ID,用于关联其 Span Event。 |
368
+ | `long_task.entry_type` | string | 必有 | `long-animation-frame` 或 `long-task`,表示使用的浏览器 Performance Entry 类型。 |
369
+ | `long_task.duration` | number | 必有,ms | 整个 LoAF/Long Task 持续时间,来源 `PerformanceEntry.duration`。 |
370
+ | `long_task.name` | string | 必有 | 浏览器 Performance Entry 的 `name`;Legacy Long Task 常见为 `self` 或跨上下文归因名称。 |
371
+ | `long_task.start_time` | number | 仅 LoAF,相对 timeOrigin ms | LoAF 的 `startTime`。Span 自身开始时间已转换为 epoch,这个字段保留原始 Performance Timeline 坐标。 |
372
+ | `long_task.blocking_duration` | number | 仅 LoAF,ms | 浏览器计算的阻塞时间,表示超出可接受帧预算、真正阻塞交互响应的部分,不等于完整 `duration`。 |
373
+ | `long_task.first_ui_event_timestamp` | number | LoAF 提供时,相对 timeOrigin ms | 该帧内首个 UI Event 的时间点;可判断长帧是否直接阻塞用户输入。 |
374
+ | `long_task.render_start` | number | LoAF 提供时,相对 timeOrigin ms | 浏览器开始本帧渲染阶段的时间点。 |
375
+ | `long_task.style_and_layout_start` | number | LoAF 提供时,相对 timeOrigin ms | 本帧开始样式计算和布局的时间点,可与 `render_start` 分析渲染阶段开销。 |
376
+
377
+ ### `long_task.script` Span Event
378
+
379
+ 每个 LoAF `scripts` 条目生成一个同名 Event;Event 自身时间戳为 `performance.timeOrigin + script.startTime`。
380
+
381
+ | Event 字段 | 类型 | 单位 | 来源与详细说明 |
382
+ | --------------------------------------------------- | ------ | ------------------ | ----------------------------------------------------------------------- |
383
+ | `long_task.script.duration` | number | ms | 当前脚本时序条目的总持续时间。 |
384
+ | `long_task.script.execution_start` | number | 相对 timeOrigin ms | 脚本实际开始执行的时间点,可与 `start_time` 对比调度等待。 |
385
+ | `long_task.script.forced_style_and_layout_duration` | number | ms | 脚本触发同步样式计算/布局的耗时,用于定位 layout thrashing。 |
386
+ | `long_task.script.invoker` | string | - | 浏览器给出的调用来源描述,例如事件处理器、计时器或脚本回调。 |
387
+ | `long_task.script.invoker_type` | string | - | 调用来源类别,具体枚举由 Long Animation Frame API 实现提供。 |
388
+ | `long_task.script.pause_duration` | number | ms | 脚本执行期间暂停的时间,例如同步等待或浏览器内部暂停。 |
389
+ | `long_task.script.source_char_position` | number | 字符偏移 | 脚本函数在源文件中的字符位置;无法定位时可能为浏览器默认值。 |
390
+ | `long_task.script.source_function_name` | string | - | 浏览器识别的源函数名;匿名函数可能为空字符串。 |
391
+ | `long_task.script.source_url` | string | URL | 脚本源 URL,经 `redactUrl` 脱敏;内联或无法定位脚本时可能为空。 |
392
+ | `long_task.script.start_time` | number | 相对 timeOrigin ms | 脚本时序条目开始时间,也是 Event epoch 时间戳的换算来源。 |
393
+ | `long_task.script.window_attribution` | string | - | 脚本所属窗口上下文归因,例如当前窗口或其他 frame;值由浏览器 API 提供。 |
394
+
395
+ ### `long_task.attribution` Span Event
396
+
397
+ Legacy Long Task 的每个 attribution 条目生成一个 Event,Event 时间戳与 Long Task Span 开始时间相同。
398
+
399
+ | Event 字段 | 类型 | 条件 | 来源与详细说明 |
400
+ | -------------------------------------- | ------ | ------------ | --------------------------------------------------------------------------------------- |
401
+ | `long_task.attribution.index` | number | 必有 | attribution 在原数组中的 0-based 序号,用于保留浏览器返回顺序。 |
402
+ | `long_task.attribution.container_id` | string | 浏览器提供时 | 归因容器元素的 ID,常用于定位 iframe。 |
403
+ | `long_task.attribution.container_name` | string | 浏览器提供时 | 归因容器的 name。 |
404
+ | `long_task.attribution.container_src` | string | 浏览器提供时 | 归因容器的 src,经 `redactUrl` 脱敏。 |
405
+ | `long_task.attribution.container_type` | string | 浏览器提供时 | 容器类型,例如 `iframe`,具体值由浏览器 Long Tasks API 提供。 |
406
+ | `long_task.attribution.name` | string | 浏览器提供时 | 归因名称,例如 `self`、`same-origin-ancestor`、`cross-origin-descendant` 等浏览器分类。 |
407
+
408
+ ## CSP 字段
409
+
410
+ 适用于 `csp.violation`,来自浏览器 `SecurityPolicyViolationEvent`。该 Span 固定为 `outcome.type=error,outcome.reason=csp,error.source=csp`。
411
+
412
+ | 字段 | 类型 | 条件 | 来源与详细说明 |
413
+ | ------------------------- | ------ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
414
+ | `csp.blocked_uri` | string | 浏览器提供时 | 被策略阻止的资源地址或 CSP 关键字。HTTP(S)/协议相对 URL 会经 `redactUrl`;`inline`、`eval`、`wasm-eval`、`self` 等关键字保持原值。 |
415
+ | `csp.violated_directive` | string | 必有 | 原策略中被违反的完整 directive 文本,可能包含策略值。 |
416
+ | `csp.effective_directive` | string | 必有 | 浏览器最终用于判定的指令名,例如 `script-src-elem`,更适合低基数聚合。 |
417
+ | `csp.disposition` | string | 必有 | 策略处理方式,通常为 `enforce` 或 `report`;前者实际阻止,后者仅报告。 |
418
+ | `csp.source_file` | string | 能定位触发代码时 | 触发违规的源文件 URL,经 `redactUrl` 脱敏;不一定等于被阻止资源。 |
419
+ | `csp.line_number` | number | 浏览器提供时 | 触发违规代码的行号;无法定位时可能为 `0`。 |
420
+ | `csp.column_number` | number | 浏览器提供时 | 触发违规代码的列号;无法定位时可能为 `0`。 |
421
+ | `csp.status_code` | number | 必有 | 违规文档的 HTTP 状态码,由浏览器事件提供;本地文档或无法确定时可能为 `0`。 |
422
+ | `csp.original_policy` | string | 必有 | 浏览器应用的原始 CSP 策略文本,便于还原规则;可能较长并包含内部域名,应通过 `redactAttributes` 评估脱敏。 |
423
+ | `error.source` | string | 必有,固定 `csp` | 把 CSP 违规纳入统一错误来源维度。 |
424
+
425
+ ## WebSocket 字段
426
+
427
+ 每个被采集的 WebSocket 连接会分别产生 connect/open/error/close 瞬时 Span;四条记录通过 `websocket.connection.id` 关联。
428
+
429
+ | 字段 | 类型 | 条件/取值 | 来源与详细说明 |
430
+ | --------------------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------- |
431
+ | `websocket.phase` | string | 必有 | `connect`:构造 WebSocket;`open`:连接成功;`error`:连接或运行期错误;`close`:关闭。 |
432
+ | `websocket.connection.id` | string | 必有 | SDK 为单个 WebSocket 实例生成的连接 ID,用于串联该连接的所有生命周期 Span。 |
433
+ | `network.protocol.name` | string | 必有,固定 `websocket` | 协议族名称,便于与其他 CLIENT Span 统一按网络协议查询。 |
434
+ | `url.full` | string | 必有 | WebSocket URL 经 `redactUrl` 脱敏;即使 URL 解析失败也保留脱敏后的原字符串。 |
435
+ | `url.scheme` | string | URL 可解析 | `ws` 或 `wss`,由 URL protocol 去除末尾冒号得到。 |
436
+ | `server.address` | string | URL 可解析 | WebSocket URL 的 hostname,不含端口。 |
437
+ | `server.port` | number | URL 显式包含端口 | 显式端口号;协议默认端口未写入 URL 时缺失。 |
438
+ | `websocket.error.phase` | string | 仅 `error` | `connect` 表示 open 前错误;`runtime` 表示连接曾成功打开后发生错误。浏览器 error Event 通常不暴露更详细原因。 |
439
+ | `websocket.close.code` | number | 仅 `close` | `CloseEvent.code`,例如正常关闭常见 `1000`;具体协议语义按 WebSocket Close Code 解释。 |
440
+ | `websocket.close.reason` | string | 仅 `close` | 对端/调用方提供的关闭原因文本,可能为空。该值不是 URL,不经过 `redactUrl`,敏感内容应由 `redactAttributes` 清理。 |
441
+ | `websocket.close.was_clean` | boolean | 仅 `close` | 浏览器判断连接是否完成干净关闭握手;`false` 常见于网络中断或异常终止。 |
442
+
443
+ `error` 阶段设置 `outcome.type=error,outcome.reason=network`;其他阶段为 `outcome.type=success` 且不写 reason。SDK 当前不采集 WebSocket 消息内容、数量或字节数。
444
+
445
+ ## Custom Event 字段
446
+
447
+ `reportCustomEvent({ name, attributes, error })` 创建 `custom.<name>`:
448
+
449
+ | 字段 | 类型 | 条件 | 来源与详细说明 |
450
+ | ----------------- | ------ | ------------------- | ----------------------------------------------------------------------------------------- |
451
+ | `span_type` | string | 必有,固定 `custom` | 将主动业务事件归入 Custom 类别。 |
452
+ | `outcome.type` | string | 必有 | 没有 `error` 时为 `success`;传入 Error 时为 `error`。 |
453
+
454
+ 调用方传入的 `name` 只进入 Span 名 `custom.<name>`,应使用稳定低基数名称,不要放用户 ID、随机值或其他用户输入。Custom Event 还会依次合并 `context.attributes.page()`、`context.attributes.custom()` 和 payload `attributes`,最后统一经过 `redactAttributes`。业务自定义值必须符合 OpenTelemetry Attribute 类型:string、number、boolean 或相应数组;不要传对象、函数或嵌套 JSON。业务应避免覆盖 `span_type`、`outcome.*` 等保留字段。
455
+
456
+ ## 业务扩展与外部 Instrumentation 字段
457
+
458
+ 固定字典无法穷举以下接入方字段:
459
+
460
+ - `context.attributes.page()`:合并到 SDK 创建的多数 Span;未配置时默认返回空对象。
461
+ - `context.attributes.error()`:合并到三类自动错误 Span。
462
+ - `context.attributes.custom()`:合并到 `custom.<name>`。
463
+ - `startView({ attributes })`:合并到该 View 的生命周期 Span 和运行时上下文,但 SDK 会过滤 RUM 保留字段,避免覆盖核心关联关系。
464
+ - `reportAction/reportCustomEvent` 的 payload `attributes`。
465
+ - `useInstrumentation()` 注册的第三方 OpenTelemetry Instrumentation 字段;只要创建时具备采样 Session/View 上下文,也可能进入同一导出链路。
466
+
467
+ 这些字段同样必须是合法 OpenTelemetry Attribute,并会进入全局 `tracking.beforeSend`。SDK API、View 和自定义插件写入的属性会经过 `redactAttributes`;第三方 Instrumentation 自带属性不会自动经过该钩子,具体边界见“上报准入与字段覆盖”。后端建模时应把接入方自定义字段与本页 SDK 稳定字段分开治理。
468
+
469
+ 过滤器会读取第三方 HTTP Instrumentation 常用的 `http.url`,以识别并丢弃指向 SDK Collector 的自身上报请求;BK RUM 内置请求插件实际写入的是 `url.full`,不会主动产生 `http.url`。
470
+
471
+ ## 当前不会出现的字段和信号
472
+
473
+ 当前源码不会产生:
474
+
475
+ - `/v1/metrics`、`/v1/logs` 请求,以及 Counter、Histogram、Gauge、LogRecord。
476
+ - `session.duration`、`view.duration`;持续时间应由服务端根据生命周期事件派生。
477
+ - `vital.cls.load_state`;字段提取代码已预留,但当前按 View 汇总的 CLS 不提供该归因值。
478
+ - Action、Resource、Error、Long Task count;计数和分布应从原始 Span 聚合。
479
+ - 错误 fingerprint/group;错误分组由服务端根据 exception、message、stack 等字段计算。
480
+ - HTTP request/response Body、Header;Trace Context 注入不代表采集请求内容。
481
+ - WebSocket message 内容、数量、字节数。
482
+ - Session Replay 数据。
483
+
484
+ 如果后端存在上述同名字段或信号,它们来自服务端派生、第三方 Instrumentation 或其他数据源,不应归因于本 SDK 的内置插件。