@blueking/open-telemetry 0.0.34 → 0.0.35-beta.1

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 (54) hide show
  1. package/README.md +67 -57
  2. package/dist/bk-rum.global.js +2 -2
  3. package/dist/bk-rum.global.js.map +1 -1
  4. package/dist/core/action-activity.d.ts +5 -1
  5. package/dist/core/action-target.d.ts +19 -0
  6. package/dist/core/config.d.ts +15 -5
  7. package/dist/core/event-time.d.ts +7 -0
  8. package/dist/core/performance-timing.d.ts +13 -0
  9. package/dist/core/plugin.d.ts +37 -2
  10. package/dist/core/processor.d.ts +24 -2
  11. package/dist/core/request-timing.d.ts +3 -2
  12. package/dist/core/runtime-context.d.ts +62 -2
  13. package/dist/core/sdk.d.ts +23 -1
  14. package/dist/core/session-transition.d.ts +19 -0
  15. package/dist/core/trace-context.d.ts +6 -7
  16. package/dist/core/view-location.d.ts +10 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.js +2933 -1505
  19. package/dist/index.js.map +1 -1
  20. package/dist/integrations/vue-router.d.ts +25 -0
  21. package/dist/plugins/action.d.ts +1 -1
  22. package/dist/plugins/blank-screen-detection.d.ts +11 -0
  23. package/dist/plugins/blank-screen.d.ts +10 -18
  24. package/dist/plugins/common.d.ts +4 -2
  25. package/dist/plugins/document-vitals.d.ts +25 -0
  26. package/dist/plugins/page-view.d.ts +1 -1
  27. package/dist/plugins/resource.d.ts +3 -1
  28. package/dist/plugins/session-state.d.ts +14 -2
  29. package/dist/plugins/session-store.d.ts +12 -0
  30. package/dist/plugins/session.d.ts +1 -0
  31. package/dist/plugins/web-vitals-metrics.d.ts +80 -0
  32. package/dist/plugins/web-vitals.d.ts +2 -59
  33. package/dist/schema/attributes.d.ts +45 -0
  34. package/dist/schema/span.d.ts +5 -2
  35. package/package.json +9 -4
  36. package/skills/bk-rum-otele/references/actions.md +54 -37
  37. package/skills/bk-rum-otele/references/api.md +72 -51
  38. package/skills/bk-rum-otele/references/architecture.md +16 -16
  39. package/skills/bk-rum-otele/references/blank-screen.md +72 -142
  40. package/skills/bk-rum-otele/references/capabilities.md +66 -60
  41. package/skills/bk-rum-otele/references/configuration.md +101 -98
  42. package/skills/bk-rum-otele/references/data-model.md +22 -17
  43. package/skills/bk-rum-otele/references/errors-security.md +13 -13
  44. package/skills/bk-rum-otele/references/extensions.md +5 -3
  45. package/skills/bk-rum-otele/references/framework-integration.md +7 -24
  46. package/skills/bk-rum-otele/references/network.md +62 -49
  47. package/skills/bk-rum-otele/references/performance.md +62 -30
  48. package/skills/bk-rum-otele/references/privacy.md +5 -5
  49. package/skills/bk-rum-otele/references/production.md +9 -13
  50. package/skills/bk-rum-otele/references/session-context.md +67 -38
  51. package/skills/bk-rum-otele/references/span-protocol.md +692 -421
  52. package/skills/bk-rum-otele/references/telemetry-reference.md +288 -213
  53. package/skills/bk-rum-otele/references/troubleshooting.md +2 -2
  54. package/skills/bk-rum-otele/references/views-routing.md +103 -27
@@ -8,13 +8,13 @@
8
8
 
9
9
  一条 RUM Span 的信息按以下层级组合。建模时应保持层级分工,不要把所有字段压成一套无差别标签:
10
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` | 这是什么信号,结果是否正常? |
16
- | 领域属性 | `resource.*`、`error.*`、`vital.*`、`long_task.*` 等 | 具体发生了什么,耗时、来源和诊断细节是什么? |
17
- | OTLP Envelope 与 Event | `traceId`、`spanId`、时间戳、`status`、`events` | 如何定位单条记录、关联调用链和读取异常/脚本归因? |
11
+ | 层级 | 主要字段 | 适合回答的问题 |
12
+ | ---------------------- | ---------------------------------------------------------------- | ------------------------------------------------- |
13
+ | SDK 与应用 Resource | `service.*`、`deployment.environment.name`、`telemetry.sdk.*` | 哪个应用、环境、版本和 SDK 产生了数据? |
14
+ | RUM 运行时上下文 | `session.id`、`view.id`、`action.ids`、`user.id`、设备和网络字段 | 事件属于哪个 Session、View、Action 和用户上下文? |
15
+ | 公共分类 | `span_type`、`outcome.type` | 这是什么信号,结果是否正常? |
16
+ | 领域属性 | `resource.*`、`error.*`、`vital.*`、`long_task.*` 等 | 具体发生了什么,耗时、来源和诊断细节是什么? |
17
+ | OTLP Envelope 与 Event | `traceId`、`spanId`、时间戳、`status`、`events` | 如何定位单条记录、关联调用链和读取异常/脚本归因? |
18
18
 
19
19
  推荐先用 Resource 字段限定应用和环境,再以 `span_type` 选择信号类型,最后使用领域字段细分。Session/View 聚合优先使用 `session.id`、`view.id`;路由聚合优先使用低基数的 `view.url_template`,不要直接按完整 URL 或原始 path 建立高基数索引。
20
20
 
@@ -42,176 +42,195 @@
42
42
  - SDK 原生 Span 先带入运行时上下文,再由本次事件属性覆盖同名字段,合并结果统一经过 `redactAttributes`。
43
43
  - `reportAction`、`reportCustomEvent` 的 payload Attribute 位于固定 RUM 分类字段之前,不能覆盖 `span_type`、`outcome.*` 和对应事件标识字段。
44
44
  - `startView({ attributes })` 会过滤 SDK 保留字段;这些属性在 View 有效期内成为运行时上下文,并随该 View 的 Span 上报。
45
- - 第三方 Instrumentation 已写入的 Attribute 优先,SDK 只补齐缺失的运行时属性。第三方自身字段不会自动经过 `redactAttributes`,需要在 Instrumentation 配置或全局 `tracking.beforeSend` 中另行治理。
45
+ - 第三方 Instrumentation 已写入的 Attribute 优先,SDK 只补齐缺失的运行时属性。第三方自身字段以及 Event/Link 属性也会在导出前经过 `redactAttributes`。
46
46
 
47
47
  ## OTLP Span Envelope
48
48
 
49
49
  每条 Span 除 RUM Attribute 外还包含 OpenTelemetry 标准字段:
50
50
 
51
- | OTLP 字段 | 类型/格式 | 条件 | 详细说明 |
52
- | ------------------- | ------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
53
- | `traceId` | 32 位十六进制字符串 | 必有 | 16 字节 Trace ID。同一条调用链上的 Span 使用同一个值。注意注入到后端的 `traceparent` 使用的是另一个独立 trace-id,不等于本字段,两者通过 `links` 关联。 |
54
- | `spanId` | 16 位十六进制字符串 | 必有 | 当前 Span 的 8 字节唯一 ID,与 `traceId` 一起唯一定位本次 Span。 |
55
- | `parentSpanId` | 16 位十六进制字符串 | 有活动父 Span 时 | 父 Span ID。没有活动父上下文的 RUM 根 Span不包含该字段;缺失不代表数据异常。 |
56
- | `links` | link[] | 注入或探测到 Trace Header 时 | 关联的其他 Trace。Resource Span 用它指向本次请求对应的后端 Trace,每项含 `traceId`、`spanId`、`traceFlags`。后端可按 `link.trace_id` 反查 RUM Span。 |
57
- | `name` | string | 必有 | 可读的低基数 Span 名称。SDK 根据 `span_type` 和领域字段生成,稳定一级分类仍使用 `span_type` 查询。 |
58
- | `kind` | enum number/string | 必有 | OpenTelemetry Span Kind。SDK 内置值为 `INTERNAL` 或 `CLIENT`;不同 OTLP JSON 实现可能编码为枚举数字或名称。 |
59
- | `startTimeUnixNano` | epoch ns 字符串 | 必有 | Span 开始时间。OTLP JSON 使用十进制字符串保存纳秒整数,避免 JavaScript Number 精度丢失。 |
60
- | `endTimeUnixNano` | epoch ns 字符串 | 必有 | Span 结束时间。瞬时生命周期事件通常与开始时间相同;Resource Span 的差值表示请求或资源加载耗时。 |
61
- | `attributes` | key-value[]/object | 可选 | 本页记录的 Resource 之外的字段位于这里。具体 JSON 形态取决于 Collector/Exporter 是否已将 OTLP KeyValue 数组展开。 |
62
- | `events` | event[] | 可选 | Span 内的时间点事件。当前包括 `exception`、`long_task.script` 和 `long_task.attribution`。每个 Event 有独立时间戳和 Attributes。 |
63
- | `status` | object | 可选 | OpenTelemetry 状态。三类自动浏览器错误、带 Error 的自定义事件和失败请求可能设置 `ERROR`;未设置通常表示 `UNSET`,不等同于业务字段 `outcome.type=success`。白屏、CSP、WebSocket 错误目前只写 RUM Outcome,不设置 OTLP Status。 |
51
+ | OTLP 字段 | 类型/格式 | 条件 | 详细说明 |
52
+ | ------------------- | ------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
53
+ | `traceId` | 32 位十六进制字符串 | 必有 | 16 字节 Trace ID。同一条调用链上的 Span 使用同一个值。注意注入到后端的 `traceparent` 使用的是另一个独立 trace-id,不等于本字段,两者通过 `links` 关联。 |
54
+ | `spanId` | 16 位十六进制字符串 | 必有 | 当前 Span 的 8 字节唯一 ID,与 `traceId` 一起唯一定位本次 Span。 |
55
+ | `parentSpanId` | 16 位十六进制字符串 | 有活动父 Span 时 | 父 Span ID。没有活动父上下文的 RUM 根 Span不包含该字段;缺失不代表数据异常。 |
56
+ | `links` | link[] | 注入或探测到 Trace Header 时 | 关联的其他 Trace。Resource Span 用它指向本次请求对应的后端 Trace,每项含 `traceId`、`spanId`、`traceFlags`。后端可按 `link.trace_id` 反查 RUM Span。 |
57
+ | `name` | string | 必有 | 可读的低基数 Span 名称。SDK 根据 `span_type` 和领域字段生成,稳定一级分类仍使用 `span_type` 查询。 |
58
+ | `kind` | enum number/string | 必有 | OpenTelemetry Span Kind。SDK 内置值为 `INTERNAL` 或 `CLIENT`;不同 OTLP JSON 实现可能编码为枚举数字或名称。 |
59
+ | `startTimeUnixNano` | epoch ns 字符串 | 必有 | Span 开始时间。OTLP JSON 使用十进制字符串保存纳秒整数,避免 JavaScript Number 精度丢失。 |
60
+ | `endTimeUnixNano` | epoch ns 字符串 | 必有 | Span 结束时间。瞬时生命周期事件通常与开始时间相同;Resource Span 的差值表示请求或资源加载耗时。 |
61
+ | `attributes` | key-value[]/object | 可选 | 本页记录的 Resource 之外的字段位于这里。具体 JSON 形态取决于 Collector/Exporter 是否已将 OTLP KeyValue 数组展开。 |
62
+ | `events` | event[] | 可选 | Span 内的时间点事件。当前包括 `exception`、`long_task.script` 和 `long_task.attribution`。每个 Event 有独立时间戳和 Attributes。 |
63
+ | `status` | object | 可选 | OpenTelemetry 状态。三类自动浏览器错误、带 Error 的自定义事件和失败请求可能设置 `ERROR`;未设置通常表示 `UNSET`,不等同于业务字段 `outcome.type=success`。白屏、CSP、WebSocket 错误目前只写 RUM Outcome,不设置 OTLP Status。 |
64
64
 
65
65
  ## Resource Attribute
66
66
 
67
67
  Resource Attribute 描述产生 Span 的 SDK 实例和运行环境,同一实例的所有 Span 共用:
68
68
 
69
- | 字段 | 类型 | 条件 | 来源与详细说明 |
70
- | -------------------------------- | ------ | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
71
- | `service.name` | string | 必有 | 来自 `application.name`。标识被监控的前端应用,是按应用聚合、路由和授权的主维度。 |
72
- | `service.version` | string | 配置 `application.version` 时 | 来自应用版本配置,通常填写发布版本或构建号,用于比较发布前后性能和错误变化。 |
73
- | `deployment.environment.name` | string | 必有 | 来自 `application.environment`,未配置时为 `production`。用于区分生产、预发布、测试等环境。 |
74
- | `session.sample_rate` | number | 必有 | 解析后的 `session.sampleRate`,范围 `0..1`。表示配置的 Session 采样概率,不表示当前某条 Span 的采样结果。 |
75
- | `telemetry.sdk.name` | string | 必有 | 固定为 `blueking`,用于识别蓝鲸浏览器 RUM SDK。 |
76
- | `telemetry.sdk.language` | string | 必有 | 固定为 `webjs`,表示浏览器 JavaScript SDK。 |
77
- | `telemetry.sdk.version` | string | 必有 | 当前 npm 包版本,用于排查字段能力或采集行为是否受 SDK 版本影响。 |
78
- | `user_agent.name` | string | `tracking.device !== false` 且有浏览器环境 | 从 User-Agent 识别,取值 `Edge`、`Chrome`、`Firefox`、`Safari` 或 `Other`。识别不到时为 `Other`。 |
79
- | `user_agent.version` | string | 能识别浏览器版本时 | 从 User-Agent 提取的浏览器主版本号,不包含次版本和补丁版本;识别不到时缺失。 |
80
- | `user_agent.os.name` | string | `tracking.device !== false` 且有浏览器环境 | 从 User-Agent / User-Agent Client Hints 推断,取值 `iOS`、`Android`、`macOS`、`Windows`、`Linux` 或 `Other`。 |
81
- | `device.type` | string | `tracking.device !== false` 且有浏览器环境 | `mobile` 或 `desktop`。根据 `userAgentData.mobile` 或移动端 User-Agent 特征推断,不代表具体硬件型号。 |
69
+ | 字段 | 类型 | 条件 | 来源与详细说明 |
70
+ | ----------------------------- | ------ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
71
+ | `service.name` | string | 必有 | 来自 `application.name`。标识被监控的前端应用,是按应用聚合、路由和授权的主维度。 |
72
+ | `service.version` | string | 配置 `application.version` 时 | 来自应用版本配置,通常填写发布版本或构建号,用于比较发布前后性能和错误变化。 |
73
+ | `deployment.environment.name` | string | 必有 | 来自 `application.environment`,未配置时为 `production`。用于区分生产、预发布、测试等环境。 |
74
+ | `session.sample_rate` | number | 必有 | 解析后的 `session.sampleRate`,范围 `0..1`。表示配置的 Session 采样概率,不表示当前某条 Span 的采样结果。 |
75
+ | `telemetry.sdk.name` | string | 必有 | 固定为 `blueking`,用于识别蓝鲸浏览器 RUM SDK。 |
76
+ | `telemetry.sdk.language` | string | 必有 | 固定为 `webjs`,表示浏览器 JavaScript SDK。 |
77
+ | `telemetry.sdk.version` | string | 必有 | 当前 npm 包版本,用于排查字段能力或采集行为是否受 SDK 版本影响。 |
78
+ | `user_agent.name` | string | `tracking.device !== false` 且有浏览器环境 | 从 User-Agent 识别,取值 `Edge`、`Chrome`、`Firefox`、`Safari` 或 `Other`。识别不到时为 `Other`。 |
79
+ | `user_agent.version` | string | 能识别浏览器版本时 | 从 User-Agent 提取的浏览器主版本号,不包含次版本和补丁版本;识别不到时缺失。 |
80
+ | `user_agent.os.name` | string | `tracking.device !== false` 且有浏览器环境 | 从 User-Agent / User-Agent Client Hints 推断,取值 `iOS`、`Android`、`macOS`、`Windows`、`Linux` 或 `Other`。 |
81
+ | `device.type` | string | `tracking.device !== false` 且有浏览器环境 | `mobile` 或 `desktop`。根据 `userAgentData.mobile` 或移动端 User-Agent 特征推断,不代表具体硬件型号。 |
82
+
82
83
  `tracking.device=false` 时 SDK 构造的 Resource 不写入设备 Resource 字段。Resource 在 SDK 初始化时经过一次 `redactAttributes`,运行期间不会随窗口或网络状态变化。当前实现不读取 `navigator.deviceMemory` 或逻辑处理器数量,因此不会出现 `device.memory_gib` 一类硬件容量字段。
83
84
 
84
85
  ## 运行时公共属性
85
86
 
86
- 普通 Span 创建时会继承创建时刻的运行时上下文;历史事件可按事件发生时间回查当时的 Session、View 和 Action 关联关系。
87
-
88
- | 字段 | 类型 | 条件 | 来源与详细说明 |
89
- | ------------------------- | -------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
90
- | `user.id` | string | 调用 `setUser({ id })` 后 | 业务提供的用户 ID,SDK 原样写入并经过 `redactAttributes`。建议使用不可逆标识,避免直接上传手机号、邮箱等个人信息。 |
91
- | `session.id` | string | Session 有效 | SDK 生成的 Session 关联 ID。15 分钟无活动或 4 小时最大生命周期到期后会更换;同一 Session 的事件可用它聚合。 |
92
- | `session.type` | string | Session 有效 | 当前固定为 `user`,为未来区分其他 Session 类型保留。 |
93
- | `session.has_replay` | boolean | Session 有效 | 当前固定为 `false`,表示 SDK 没有随该 Session 上报 Session Replay 数据。 |
94
- | `view.id` | string | View 有效 | 当前页面视图的关联 ID。首次加载、有效 SPA 路由变化、BFCache 恢复或 Session 续建都会创建新 View。 |
95
- | `view.name` | string | View 有效期内 | 视图名称优先使用 `startView({ name })` 或 `setViewName()` 的显式值,未设置时取 `view.url_template`。 |
96
- | `view.url` | string | View 有效 | 创建 View 时的完整 URL,经 `redactUrl` 脱敏。与当前实时 `location.href` 不一定相同。 |
97
- | `view.url_template` | string | View 有效 | 低基数路由模板。默认把数字 ID、UUID 和长十六进制路径段归一为 `:id`,也可由 `getUrlTemplate` 自定义。 |
98
- | `view.loading_type` | string | View 有效 | View 创建类型:`initial_load` 首次文档加载、`route_change` SPA 路由、`bf_cache` BFCache 恢复、`session_renewal` Session 到期后续建。 |
99
- | `action.id` | string | 自动 Action 活动中 | 当前活动的自动 Action ID。多个点击窗口重叠时取最近一次开始的 Action;Action Span 自身的同名字段也是单个 string。 |
100
- | `device.id` | string | Device 插件开启 | SDK 生成的匿名设备关联 ID。默认仅在本次插件生命周期内稳定;`persistentId: true` 时写入 localStorage,从而跨页面和 Session 保持。 |
101
- | `browser.viewport.width` | number | 浏览器环境 | 当前 CSS viewport 宽度,单位 CSS px,来源 `window.innerWidth`;窗口 resize/屏幕旋转后更新到后续 Span。 |
102
- | `browser.viewport.height` | number | 浏览器环境 | 当前 CSS viewport 高度,单位 CSS px,来源 `window.innerHeight`。 |
103
- | `browser.screen.width` | number | 浏览器提供 `window.screen` 时 | 当前屏幕宽度,单位 CSS px;不是物理像素,不能直接推导设备分辨率。 |
104
- | `browser.screen.height` | number | 浏览器提供 `window.screen` 时 | 当前屏幕高度,单位 CSS px;不是当前网页可用区域高度。 |
105
- | `network.status` | string | 浏览器环境 | 根据 `navigator.onLine` 取 `connected` 或 `not_connected`;表示浏览器判断的联网状态,不保证目标服务实际可达。 |
106
- | `network.effective_type` | string | Network Information API 支持 | 浏览器估算的有效网络类型,常见为 `slow-2g`、`2g`、`3g`、`4g`。它反映体验模型,不等同于真实无线制式。 |
107
- | `network.connection.type` | string | 浏览器提供 `connection.type` 时 | 浏览器返回的原始连接类型,例如 `wifi`、`cellular`、`ethernet`;多数 Safari/Firefox 环境可能缺失。 |
87
+ 普通 Span 创建时会继承创建时刻的 Session/View 运行时上下文;历史事件可按事件发生时间回查。Action 关联只自动补充给 `span_type=resource/error/long_task`,以逐 Action 的有效区间及所属 Session/View 匹配;未声明 `span_type` 的通用 OpenTelemetry Span 不自动推测关联。
88
+
89
+ | 字段 | 类型 | 条件 | 来源与详细说明 |
90
+ | ------------------------- | -------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
91
+ | `user.id` | string | 调用 `setUser({ id })` 后 | 业务提供的用户 ID,SDK 原样写入并经过 `redactAttributes`。建议使用不可逆标识,避免直接上传手机号、邮箱等个人信息。 |
92
+ | `session.id` | string | Session 有效 | SDK 生成的 Session 关联 ID。15 分钟无活动或 4 小时最大生命周期到期后会更换;同一 Session 的事件可用它聚合。 |
93
+ | `session.type` | string | Session 有效 | 当前固定为 `user`,为未来区分其他 Session 类型保留。 |
94
+ | `session.has_replay` | boolean | Session 有效 | 当前固定为 `false`,表示 SDK 没有随该 Session 上报 Session Replay 数据。 |
95
+ | `view.id` | string | View 有效 | 当前页面视图的关联 ID。首次加载、有效 SPA 路由变化、BFCache 恢复或 Session 续建都会创建新 View。 |
96
+ | `view.name` | string | View 有效期内 | 视图名称优先使用 `startView({ name })` 或 `setViewName()` 的显式值,未设置时取 `view.url_template`。 |
97
+ | `view.url` | string | View 有效 | 创建 View 时的完整 URL,经 `redactUrl` 脱敏。与当前实时 `location.href` 不一定相同。 |
98
+ | `view.url_template` | string | View 有效 | 低基数路由模板。默认把数字 ID、UUID 和长十六进制路径段归一为 `:id`,也可由 `getUrlTemplate` 自定义。 |
99
+ | `view.loading_type` | string | View 有效 | View 创建类型:`initial_load` 首次文档加载、`route_change` SPA 路由、`bf_cache` BFCache 恢复、`session_renewal` Session 到期后续建。 |
100
+ | `action.ids` | string[] | Resource/Error/Long Task 命中 Action 区间 | 事件关联的全部 Action ID。允许多个重叠窗口;无关联时不写。已开始请求晚到结束保留原关联,不双写旧 `action.id`。 |
101
+ | `device.id` | string | Device 插件开启 | SDK 生成的匿名设备关联 ID。默认仅在本次插件生命周期内稳定;`persistentId: true` 时写入 localStorage,从而跨页面和 Session 保持。 |
102
+ | `browser.viewport.width` | number | 浏览器环境 | 当前 CSS viewport 宽度,单位 CSS px,来源 `window.innerWidth`;窗口 resize/屏幕旋转后更新到后续 Span。 |
103
+ | `browser.viewport.height` | number | 浏览器环境 | 当前 CSS viewport 高度,单位 CSS px,来源 `window.innerHeight`。 |
104
+ | `browser.screen.width` | number | 浏览器提供 `window.screen` 时 | 当前屏幕宽度,单位 CSS px;不是物理像素,不能直接推导设备分辨率。 |
105
+ | `browser.screen.height` | number | 浏览器提供 `window.screen` 时 | 当前屏幕高度,单位 CSS px;不是当前网页可用区域高度。 |
106
+ | `network.status` | string | 浏览器环境 | 根据 `navigator.onLine` 取 `connected` 或 `not_connected`;表示浏览器判断的联网状态,不保证目标服务实际可达。 |
107
+ | `network.effective_type` | string | Network Information API 支持 | 浏览器估算的有效网络类型,常见为 `slow-2g`、`2g`、`3g`、`4g`。它反映体验模型,不等同于真实无线制式。 |
108
+ | `network.connection.type` | string | 浏览器提供 `connection.type` 时 | 浏览器返回的原始连接类型,例如 `wifi`、`cellular`、`ethernet`;多数 Safari/Firefox 环境可能缺失。 |
108
109
 
109
110
  默认 `context.attributes.page()` 返回空对象,不附加独立页面属性。页面地址使用 View 创建时冻结并经过 `redactUrl` 的 `view.url`,低基数路由聚合使用 `view.url_template`;业务需要额外页面维度时可自定义该 Hook。
110
111
 
111
112
  ## RUM 公共分类字段
112
113
 
113
- | 字段 | 类型 | 条件 | 来源与详细说明 |
114
- | ---------------- | ------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
115
- | `span_type` | string | 所有 SDK 原生 RUM Span | 稳定的 RUM 一级分类:`session`、`view`、`resource`、`error`、`vital`、`long_task`、`action`、`websocket` 或 `custom`。 |
116
- | `outcome.type` | string | 所有 SDK 原生 RUM Span | 归一结果:`success`、`warning`、`error`、`timeout` 或 `abort`。Fetch/XHR 主动取消使用 `abort`。 |
114
+ | 字段 | 类型 | 条件 | 来源与详细说明 |
115
+ | -------------- | ------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
116
+ | `span_type` | string | 所有 SDK 原生 RUM Span | 稳定的 RUM 一级分类:`session`、`view`、`resource`、`error`、`vital`、`long_task`、`action`、`websocket` 或 `custom`。 |
117
+ | `outcome.type` | string | 所有 SDK 原生 RUM Span | 归一结果:`success`、`warning`、`error`、`timeout`、`abort` 或 `unknown`。Fetch/XHR 主动取消使用 `abort`;Resource 无可用状态且无明确失败证据时为 `unknown`。 |
117
118
 
118
119
  `outcome.type` 是 RUM 查询维度,OTLP `status` 是 OpenTelemetry 状态,二者用途不同。例如 Web Vital 评级不佳时为 `outcome.type=warning`,但不会把 OTLP Status 设置为 `ERROR`。当前 `buildRumSpanAttributes()` **不会写入** `outcome.reason`;HTTP 失败用 `http.response.status_code`,错误入口用 `error.source`,白屏用 `blank_screen.reason`,CSP 用 `error.source=csp`。
119
120
 
120
121
  ## Span 清单
121
122
 
122
- | Span 名 | Kind | `span_type` | 领域分类字段 | 默认状态/入口 | 表达的事件 |
123
- | ---------------------------- | -------- | ----------- | --------------------------------- | --------------------------------- | -------------------------------------------------- |
124
- | `session.<phase>` | INTERNAL | `session` | `session.phase` | 始终随 SDK 启动 | Session 创建、轮换和结束生命周期。 |
125
- | `<view.name>` | INTERNAL | `view` | `view.phase` | 自动;可切为手动 View | 初始页面或 SPA View 的 start/update/end 快照。 |
126
- | `<method> <url.template>` | CLIENT | `resource` | `resource.type` | 请求、静态资源默认开启 | Fetch、XHR 或静态资源加载。 |
127
- | `<exception.type>` | INTERNAL | `error` | `error.source=window.error` | 错误采集默认开启 | `window.error` 捕获的 JavaScript 运行时错误。 |
128
- | `<exception.type>` | INTERNAL | `error` | `error.source=unhandledrejection` | 错误采集默认开启 | 未处理的 Promise rejection。 |
129
- | `ResourceError` | INTERNAL | `error` | `error.source=resource` | 错误采集默认开启 | script、img、link、media 等元素资源加载失败。 |
130
- | `<VITAL_METRIC>` | INTERNAL | `vital` | `vital.metric` | 默认开启 | 单项用户体验指标及归因。 |
131
- | `click <target>` | INTERNAL | `action` | `action.type=click` | 自动 Action 默认开启 | 自动点击 Action 及其页面活动、错误和挫败归因。 |
132
- | `<action.name>` | INTERNAL | `action` | `action.type=custom` | `reportAction({ name })` | 主动上报的业务 Action;Span 名使用业务提供的 `action.name`。 |
133
- | `blank_screen.<reason>` | INTERNAL | `error` | `blank_screen.reason` | 默认开启 | 视口九宫格连续检测确认的白屏。 |
134
- | `<long_task.entry_type>` | INTERNAL | `long_task` | `long_task.entry_type` | `tracking.longTask`,默认关闭 | Long Animation Frame,或不支持时回退的 Long Task。 |
135
- | `csp.<effective_directive>` | INTERNAL | `error` | `error.source=csp` | `tracking.cspViolation`,默认关闭 | 浏览器 `securitypolicyviolation` 事件。 |
136
- | `websocket.<phase>` | CLIENT | `websocket` | `websocket.phase` | `tracking.websocket`,默认关闭 | 同一 WebSocket 连接的四类生命周期事件。 |
137
- | `custom.<name>` | INTERNAL | `custom` | Span 名 | `reportCustomEvent` | 主动上报的业务事件。 |
123
+ | Span 名 | Kind | `span_type` | 领域分类字段 | 默认状态/入口 | 表达的事件 |
124
+ | --------------------------- | -------- | ----------- | --------------------------------- | --------------------------------- | ------------------------------------------------------------ |
125
+ | `session.<phase>` | INTERNAL | `session` | `session.phase` | 始终随 SDK 启动 | Session 创建、轮换和结束生命周期。 |
126
+ | `<view.name>` | INTERNAL | `view` | `view.phase` | 自动;可切为手动 View | 初始页面或 SPA View 的 start/update/end 快照。 |
127
+ | `<method> <url.template>` | CLIENT | `resource` | `resource.type` | 请求、静态资源默认开启 | Fetch、XHR 或静态资源加载。 |
128
+ | `<exception.type>` | INTERNAL | `error` | `error.source=window.error` | 错误采集默认开启 | `window.error` 捕获的 JavaScript 运行时错误。 |
129
+ | `<exception.type>` | INTERNAL | `error` | `error.source=unhandledrejection` | 错误采集默认开启 | 未处理的 Promise rejection。 |
130
+ | `ResourceError` | INTERNAL | `error` | `error.source=resource` | 错误采集默认开启 | script、img、link、media 等元素资源加载失败。 |
131
+ | `<VITAL_METRIC>` | INTERNAL | `vital` | `vital.metric` | 默认开启 | 单项用户体验指标及归因。 |
132
+ | `click <target>` | INTERNAL | `action` | `action.type=click` | 自动 Action 默认开启 | 自动点击 Action 及其页面活动、错误和挫败归因。 |
133
+ | `<action.name>` | INTERNAL | `action` | `action.type=custom` | `reportAction({ name })` | 主动上报的业务 Action;Span 名使用业务提供的 `action.name`。 |
134
+ | `blank_screen.<reason>` | INTERNAL | `error` | `blank_screen.reason` | 默认开启 | 视口九宫格连续检测确认的白屏。 |
135
+ | `<long_task.entry_type>` | INTERNAL | `long_task` | `long_task.entry_type` | `tracking.longTask`,默认关闭 | Long Animation Frame,或不支持时回退的 Long Task。 |
136
+ | `csp.<effective_directive>` | INTERNAL | `error` | `error.source=csp` | `tracking.cspViolation`,默认关闭 | 浏览器 `securitypolicyviolation` 事件。 |
137
+ | `websocket.<phase>` | CLIENT | `websocket` | `websocket.phase` | `tracking.websocket`,默认关闭 | 同一 WebSocket 连接的四类生命周期事件。 |
138
+ | `custom.<name>` | INTERNAL | `custom` | Span 名 | `reportCustomEvent` | 主动上报的业务事件。 |
138
139
 
139
140
  Span 名只使用领域分类字段和业务提供的稳定名称。唯一 ID、完整 URL、错误消息、时间戳和数值不参与命名。
140
141
 
141
142
  ## Session 字段
142
143
 
143
- 适用于 `span_type=session`。Session 默认在 15 分钟无活动后过期,并受 4 小时最大生命周期限制。
144
+ `session.phase` 适用于 `span_type=session`,其余 Session 上下文随所属遥测关联。Session 在 15 分钟无有效输入后过期,并受 4 小时最大生命周期限制;页面可见、后台请求不会续期。
145
+
146
+ | 字段 | 类型 | 条件/取值 | 来源与详细说明 |
147
+ | ---------------------------- | ------- | ------------------------ | ------------------------------------------------------------------------------------------------------------- |
148
+ | `session.phase` | string | `start`、`rotate`、`end` | `start` 表示没有可复用记录时创建;`rotate` 表示旧 Session 到期后创建新 Session;`end` 表示当前 Session 失效。 |
149
+ | `session.id` | string | 所有阶段 | 当前生命周期事件所描述的 Session ID。`end` 事件写旧 ID,`rotate` 事件写新 ID。 |
150
+ | `session.type` | string | 所有阶段,固定 `user` | 表示按真实用户浏览活动划分的 Session。 |
151
+ | `session.has_replay` | boolean | 所有阶段,固定 `false` | 明确当前 SDK 没有为该 Session 关联回放数据。 |
152
+ | `session.start_time` | number | epoch ms | 所属 Session 的创建时间,不随续期改变。 |
153
+ | `session.last_activity_time` | number | epoch ms | 所属 Session 的最后有效活动时间。后台请求只携带该值,不更新它。 |
154
+ | `tab.id` | string | 浏览器页面上下文 | 标签页分组标识,优先保存在 sessionStorage;不可用时退回内存。不是 Session ID,也不是结束去重键。 |
144
155
 
145
- | 字段 | 类型 | 条件/取值 | 来源与详细说明 |
146
- | -------------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------- |
147
- | `session.phase` | string | `start`、`rotate`、`end` | `start` 表示没有可复用记录时创建;`rotate` 表示旧 Session 到期后创建新 Session;`end` 表示当前 Session 失效。 |
148
- | `session.id` | string | 所有阶段 | 当前生命周期事件所描述的 Session ID。`end` 事件写旧 ID,`rotate` 事件写新 ID。 |
149
- | `session.type` | string | 所有阶段,固定 `user` | 表示按真实用户浏览活动划分的 Session。 |
150
- | `session.has_replay` | boolean | 所有阶段,固定 `false` | 明确当前 SDK 没有为该 Session 关联回放数据。 |
156
+ Session Span 允许没有 `view.id`,并显式关联它所描述的 Session;旧 end 不得继承新 View。过期原因(`init` / `inactivity` / `maxLifetime` / `external`)只出现在插件内部的 `notifySessionLifecycle` 事件上,**不会**写成 Span Attribute;`session.lifecycle.reason`、`session.previous_id` 当前不上报。
151
157
 
152
- Session Span 允许没有 `view.id`:SDK 先建立 Session,再创建初始 View;结束 Session 时也会先结束当前 View。过期原因(`init` / `inactivity` / `maxLifetime` / `external`)只出现在插件内部的 `notifySessionLifecycle` 事件上,**不会**写成 Span Attribute;`session.start_time`、`session.lifecycle.reason`、`session.previous_id` 当前均不上报。
158
+ `session.end` 仅由提交超时结束的一方发起,Span 时间为逻辑截止时间。其他 Tab 结束自己的 View,不重复发送同一共享 end。接收侧仍需按应用、Session ID、phase 幂等处理重试,并允许缺失 end;迟到请求的接收时间不能延长 Session。
153
159
 
154
160
  ## View 字段
155
161
 
156
162
  适用于 `span_type=view`。同一 View 会产生多条版本递增的生命周期快照,而不是一条持续到页面离开的长 Span。
157
163
 
158
- | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
159
- | -------------------------- | ------ | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
160
- | `view.phase` | string | `start`、`update`、`end` | `start` 创建 View;`update` 写入自动/手动 Loading Time 或名称更新;`end` 关闭 View。 |
161
- | `view.id` | string | 所有阶段 | View 关联 ID。同一 View 的 start/update/end 使用相同值,可与该 View 内其他 Span 关联。 |
162
- | `view.version` | number | 从 1 递增 | 每次 `emitViewEvent` 递增;用于恢复同一 View 生命周期快照的先后顺序。 |
163
- | `view.started_at` | number | epoch ms | View 开始时间。初始 View 使用 `performance.timeOrigin`,路由/BFCache/续建 View 使用创建时刻。 |
164
- | `view.name` | string | View 有效期内 | 优先使用 `startView({ name })` 或 `setViewName()` 的显式值,未设置时取 `view.url_template`。 |
165
- | `view.url` | string | 所有阶段 | 创建 View 时的 URL,经 `redactUrl` 脱敏;在该 View 生命周期内保持不变。 |
166
- | `view.url_template` | string | 所有阶段 | 当前 URL 的低基数路由模板。数字 ID、UUID、长十六进制段默认折叠为 `:id`,用于稳定聚合动态路由。 |
167
- | `view.previous_url_template` | string | 所有阶段 | 前序 URL 的低基数路由模板;使用 `tracking.view.getUrlTemplate` 生成,初始 View 为空字符串。 |
168
- | `view.loading_type` | string | 所有阶段 | `initial_load`、`route_change`、`bf_cache` 或 `session_renewal`,含义见运行时公共属性。 |
169
- | `view.loading_time` | number | 计算完成后,ms | 从 `view.started_at` 到页面活动稳定的耗时。初始加载同时等待 load event 和页面活动,以较晚者为准;可由 `setViewLoadingTime()` 手动结束。 |
170
- | `view.loading_time_source` | string | 有 `view.loading_time` 时 | `auto` 表示 SDK 自动观察页面活动;`manual` 表示业务调用 `setViewLoadingTime()`。 |
171
- | `view.end_reason` | string | 仅 `end` | 结束原因:路由来源值、`manual`、`bfcache`、`pagehide`、`session_expired` 或 `shutdown`。它说明为何关闭旧 View,不是新 View 的加载类型。 |
172
- | `view.previous` | string | 所有阶段 | 创建 View 时记录的前序 URL,经 `redactUrl` 脱敏;初始 View 为空字符串。 |
173
- | `view.referrer` | string | 仅 `initial_load` 且值非空 | `document.referrer` 经 `redactUrl` 脱敏。 |
174
- | `view.first_byte` | number | 仅初始 View 且 Navigation Timing 有值,相对 timeOrigin ms | `PerformanceNavigationTiming.responseStart`,表示导航开始到收到响应首字节的时间。 |
175
- | `view.dom_interactive` | number | 同上 | `domInteractive`,表示 HTML 解析完成、文档进入 interactive 状态的时间点。 |
176
- | `view.dom_content_loaded` | number | 同上 | `domContentLoadedEventEnd`,表示 DOMContentLoaded 事件处理完成的时间点。 |
177
- | `view.dom_complete` | number | 同上 | `domComplete`,表示文档及其依赖资源处理完成并进入 complete 状态的时间点。 |
178
- | `view.load_event` | number | 同上 | `loadEventEnd`,表示 window load 事件处理完成的时间点。值为 `0` 或非有限数时不写入。 |
164
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
165
+ | ---------------------------- | ------ | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
166
+ | `view.phase` | string | `start`、`update`、`end` | `start` 创建 View;`update` 写入指标/上下文或生成周期、隐藏/冻结、flush 检查点;`end` 关闭 View。 |
167
+ | `view.id` | string | 所有阶段 | View 关联 ID。同一 View 的 start/update/end 使用相同值,可与该 View 内其他 Span 关联。 |
168
+ | `view.version` | number | 从 1 递增 | 每次 `emitViewEvent` 递增;用于恢复同一 View 生命周期快照的先后顺序。 |
169
+ | `view.started_at` | number | epoch ms | 初始 View:`performance.timeOrigin`。<br />BFCache:`pageshow` 事件时刻,不可用时采用 SDK 处理时刻兜底。<br />路由/续建 View:创建时刻。 |
170
+ | `view.name` | string | View 有效期内 | 优先使用 `startView({ name })` 或 `setViewName()` 的显式值,未设置时取 `view.url_template`。 |
171
+ | `view.url` | string | 所有阶段 | 经 `redactUrl` 脱敏的 URL;同 View 内 URL 变化按生效时间更新,历史快照保留。 |
172
+ | `view.url_template` | string | 所有阶段 | 当前 URL 的低基数路由模板。数字 ID、UUID、长十六进制段默认折叠为 `:id`,用于稳定聚合动态路由。 |
173
+ | `view.previous_url_template` | string | 所有阶段 | 优先保留旧 View 的 Router 显式模板,否则由 getUrlTemplate 生成;初始 View 为空字符串。 |
174
+ | `view.loading_type` | string | 所有阶段 | `initial_load`、`route_change`、`bf_cache` 或 `session_renewal`,含义见运行时公共属性。 |
175
+ | `view.loading_time` | number | 计算完成后,ms | 从 View 开始到页面活动稳定的耗时;初始加载自动计算时取 load event 与页面活动结束中的较晚者。 |
176
+ | `view.loading_time_source` | string | 有 `view.loading_time` 时 | `auto` 表示 SDK 自动观察页面活动;`manual` 表示业务调用 `setViewLoadingTime()`。 |
177
+ | `view.end_reason` | string | 仅 `end` | 结束原因:路由来源值、`manual`、`bfcache`、`pagehide`、`session_expired` 或 `shutdown`。它说明为何关闭旧 View,不是新 View 的加载类型。 |
178
+ | `view.previous` | string | 所有阶段 | 创建 View 时记录的前序 URL,经 `redactUrl` 脱敏;初始 View 为空字符串。 |
179
+ | `view.referrer` | string | 仅 `initial_load` 且值非空 | `document.referrer` 经 `redactUrl` 脱敏。 |
180
+ | `view.first_byte` | number | 仅初始 View 且 Navigation Timing 有值,相对 timeOrigin ms | `PerformanceNavigationTiming.responseStart`,表示导航开始到收到响应首字节的时间。 |
181
+ | `view.dom_interactive` | number | 同上 | `domInteractive`,表示 HTML 解析完成、文档进入 interactive 状态的时间点。 |
182
+ | `view.dom_content_loaded` | number | 同上 | `domContentLoadedEventEnd`,表示 DOMContentLoaded 事件处理完成的时间点。 |
183
+ | `view.dom_complete` | number | 同上 | `domComplete`,表示文档及其依赖资源处理完成并进入 complete 状态的时间点。 |
184
+ | `view.load_event` | number | 同上 | `loadEventEnd`,表示 window load 事件处理完成的时间点。值为 `0` 或非有限数时不写入。 |
179
185
 
180
186
  只有 pathname 或具有路由意义的 hash path 变化才自动创建新 View;仅 query 或锚点变化不会创建,因此不能假设每次地址栏变化都有新的 `view.id`。
181
187
 
188
+ 新增累计快照字段:
189
+
190
+ | 字段 | 类型/单位 | 语义 |
191
+ | ---------------------------- | ------------ | ----------------------------------------------------------------------------------------- |
192
+ | `view.time_spent` | number,ms | View 开始至本次快照,包含后台时间;不能累加不同版本 |
193
+ | `view.foreground_time` | number,ms | SDK 观察到的 active/passive 累计时间,不补算初始化之前的可见性 |
194
+ | `view.is_active` | boolean | start/update 为 true,end 为 false |
195
+ | `view.page_states` | string,JSON | 最近最多100项 `{state,start}`;state=active/passive/hidden/frozen,start 为相对View起点ms |
196
+ | `view.custom_timings.<name>` | number,ms | 业务里程碑相对View起点时间,同名覆盖 |
197
+
198
+ `routeMode=auto` 默认识别 `#/`/`#!/`;Hash模板基于逻辑路径,原始URL仍默认去除query/hash。`startView({urlTemplate})` 优先采用框架路由定义。首次手动View跨Session时使用有效的新起点,不回填旧文档起点。
199
+
182
200
  ## 请求与静态资源字段
183
201
 
184
202
  适用于 `span_type=resource`。Fetch/XHR 由请求插件建 Span,再合并匹配的 Resource Timing;静态资源由 Resource Observer 直接建 Span。
185
203
 
186
- | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
187
- | --------------------------------- | ------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
188
- | `url.full` | string | 有有效请求/资源 URL | 绝对 URL,经 `redactUrl` 脱敏。用于定位请求目标;不要假设 query 中仍保留原始参数。 |
189
- | `url.template` | string | 有有效请求/资源 URL | 低基数 path。Fetch/XHR 和静态资源默认把数字 ID、UUID、长十六进制段折叠为 `:id`,例如 `/api/orders/:id`,可由 `tracking.request.getUrlTemplate` 覆盖。静态资源先通过 `redactUrl` 脱敏,再生成模板。按路径聚合时用它,不要用 `url.full`。 |
190
- | `server.address` | string | URL 可解析 | URL 的 `hostname`,不含端口。相对 URL 会基于当前页面地址解析。模板不含 host,跨域同路径会聚到一起,需要区分来源时配合该字段。 |
191
- | `server.port` | number | URL 显式包含端口 | URL 的显式端口号。使用协议默认端口且 URL 未写端口时缺失。 |
192
- | `resource.type` | string | 必有 | Fetch/XHR 为 `fetch`/`xhr`;静态资源使用 `PerformanceResourceTiming.initiatorType`,为空时为 `other`,常见还有 `script`、`link`、`img`、`css`。 |
193
- | `http.request.method` | string | 所有 Resource | Fetch/XHR 归一为实际的大写 HTTP 方法;其他 Resource 固定为 `GET`。 |
194
- | `http.response.status_code` | number | 获得真实 HTTP Response | HTTP 响应状态,只写大于 `0` 的有效状态码。abort、timeout、网络失败和 opaque Response 没有可用状态码时缺失,不使用 `0` 代替。 |
195
- | `resource.size` | number | 有 Resource Timing 详情 | `decodedBodySize`,解压后响应体大小,单位 bytes,不含响应头;缓存命中也能反映真实体积。Fetch/XHR 合并 Resource Timing 后同样会带上。 |
196
- | `resource.protocol` | string | 浏览器提供 `nextHopProtocol` | 实际传输协议,例如 `h2`、`h3`、`http/1.1`;浏览器无法判断时可能返回空字符串。 |
197
- | `resource.cache.hit` | boolean | SDK 能推断命中缓存时 | 只在 `deliveryType=cache`,或 `transferSize=0` 且 `decodedBodySize>0` 时写 `true`。没有该字段表示“无法确认命中”,不是明确的 `false`。 |
198
- | `resource.delivery_type` | string | 浏览器支持 `deliveryType` | 浏览器报告的资源交付方式;原值为空时归一为 `other`。具体枚举随浏览器 Resource Timing 实现演进。 |
199
- | `resource.render_blocking_status` | string | 浏览器支持 `renderBlockingStatus` | 资源是否阻塞渲染,常见为 `blocking` 或 `non-blocking`,适合定位影响首屏的 CSS/脚本。 |
200
- | `resource.encoded_body_size` | number | 有 Resource Timing | 编码/压缩后的响应体大小,单位 bytes,不包含响应头。跨域且没有 Timing-Allow-Origin 时可能为 `0`。 |
201
- | `resource.decoded_body_size` | number | 有 Resource Timing | 解码/解压后的响应体大小,单位 bytes,可与 encoded size 对比压缩收益。 |
202
- | `resource.transfer_size` | number | 有 Resource Timing | `transferSize`,本次网络实际传输字节数(含响应头);受缓存和 Timing-Allow-Origin 影响可能为 `0`,可与 body size 对比判断是否命中缓存。 |
203
-
204
- 命中 `allowedTracingUrls` 的请求还会带一条 Span Link,用于关联后端 Trace。Trace 来源不记在 Span Attributes 上,而是记在 Link Attributes 上:
205
-
206
- | 字段 | 类型 | 条件 | 说明 |
207
- | ----------- | ------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
208
- | `format` | string | 恒有 | 命中的传播格式,取值为 `traceparent`、`sentry-trace`、`b3`、`b3-multi`、`datadog`、`sw8`。 |
209
- | `injected` | boolean | 恒有 | 这条 trace context 是否由 SDK 生成并注入。`true` 表示请求原本没有任何 trace Header;`false` 表示业务已自行传播,SDK 未注入。业务自带合法 `traceparent` 时 `format` 与 SDK 注入同值,只能靠该字段区分。 |
210
- | Header 原名 | string | 该 Header 存在 | 命中格式的原始 Header 名与原始取值,未做补零或进制转换,例如 `traceparent`、`b3`、`x-datadog-trace-id`、`sw8`。仅记录命中格式自己的 Header。 |
211
-
212
- Link 的 `trace_id` / `span_id` 优先取自解析结果;`sw8` 这类无法映射为合法 OTel id 的格式会补一对随机占位 id,此时后端不存在对应 Trace。
213
-
214
- 两点数据口径需要注意:Link Attributes 不经过 `privacy.redactAttributes` 脱敏;`tracestate` 不做记录,它在本链路上没有消费者,且体积最坏可达数 KB。
204
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
205
+ | --------------------------------- | ------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
206
+ | `url.full` | string | 有有效请求/资源 URL | 绝对 URL,经 `redactUrl` 脱敏。用于定位请求目标;不要假设 query 中仍保留原始参数。 |
207
+ | `url.template` | string | 有有效请求/资源 URL | 低基数 path。Fetch/XHR 和静态资源默认把数字 ID、UUID、长十六进制段折叠为 `:id`,例如 `/api/orders/:id`,可由 `tracking.request.getUrlTemplate` 覆盖。静态资源先通过 `redactUrl` 脱敏,再生成模板。按路径聚合时用它,不要用 `url.full`。 |
208
+ | `server.address` | string | URL 可解析 | URL 的 `hostname`,不含端口。相对 URL 按 `document.baseURI` 解析,包含当前页面目录和 `<base href>`。模板不含 host,跨域同路径会聚到一起,需要区分来源时配合该字段。 |
209
+ | `server.port` | number | URL 显式包含端口 | URL 的显式端口号。使用协议默认端口且 URL 未写端口时缺失。 |
210
+ | `resource.type` | string | 必有 | 归一化类型:document/xhr/fetch/beacon/css/js/image/font/media/other。 |
211
+ | `resource.initiator_type` | string | 有原始来源时 | 浏览器原始 initiatorType;XHR 为 xmlhttprequest。 |
212
+ | `http.request.method` | string | 方法已知时 | Fetch/XHR 为实际大写方法;Beacon 为 POST;其他 Timing-only 资源省略,不推测 GET。 |
213
+ | `http.response.status_code` | number | 获得真实 HTTP Response | HTTP 响应状态,只写大于 `0` 的有效状态码。abort、timeout、网络失败和 opaque Response 没有可用状态码时缺失,不使用 `0` 代替。 |
214
+ | `resource.size` | number | 有 Resource Timing 详情 | `decodedBodySize`,解压后响应体大小,单位 bytes,不含响应头;缓存命中也能反映真实体积。Fetch/XHR 合并 Resource Timing 后同样会带上。 |
215
+ | `resource.timing.incomplete` | boolean | Fetch/XHR 没有可用匹配 Timing 时 | 为 `true` 表示使用了回退时间,可能只有响应头到达或终止时间;不能据此推断完整正文已下载。匹配到 Timing 时不写入;跨域 TAO 隐藏详情与该字段含义不同。 |
216
+ | `resource.protocol` | string | 浏览器提供 `nextHopProtocol` | 实际传输协议,例如 `h2`、`h3`、`http/1.1`;浏览器无法判断时可能返回空字符串。 |
217
+ | `resource.cache.hit` | boolean | SDK 能确认 HTTP 缓存命中时 | 先排除有 Service Worker 或其静态路由参与证据的条目;`deliveryType=cache` 时写 `true`。仅当交付类型为空或未提供时,才以 `transferSize=0 && decodedBodySize>0 && requestStart>0 && responseStart>0` 兜底;其他非空交付类型不兜底。字段缺失表示“无法确认命中”,不写 `false`。完整顺序见 [Span 协议注 [3]](./span-protocol.md)。 |
218
+ | `resource.delivery_type` | string | 浏览器支持 `deliveryType` | 浏览器报告的资源交付方式;原值为空时归一为 `other`。具体枚举随浏览器 Resource Timing 实现演进。 |
219
+ | `resource.render_blocking_status` | string | 浏览器支持 `renderBlockingStatus` | 资源是否阻塞渲染,常见为 `blocking` 或 `non-blocking`,适合定位影响首屏的 CSS/脚本。 |
220
+ | `resource.encoded_body_size` | number | 有 Resource Timing | 编码/压缩后的响应体大小,单位 bytes,不包含响应头。跨域且没有 Timing-Allow-Origin 时可能为 `0`。 |
221
+ | `resource.decoded_body_size` | number | 有 Resource Timing | 解码/解压后的响应体大小,单位 bytes,可与 encoded size 对比压缩收益。 |
222
+ | `resource.transfer_size` | number | 有 Resource Timing | `transferSize`,单位 bytes,包含规范估算的响应头开销:本地缓存为 `0`,协商缓存为 `300`,普通网络响应为 encoded size + `300`。受 Timing-Allow-Origin 影响也可能为 `0`,不能单独用于判断缓存命中或精确网络流量。 |
223
+
224
+ 大小字段全部缺失表示没有可用详情,不能补成 `0`。当原生传输量和正文大小均为 `0`、请求与首字节时间均为 `0` 且协议为空时,SDK 会省略这组大小字段;其余情况保留浏览器提供的值。
225
+
226
+ 命中 `allowedTracingUrls` 且能生成或解析合法 OTel 上下文时,请求带一条 Span Link:
227
+
228
+ | 字段 | 类型 | 说明 |
229
+ | --- | --- | --- |
230
+ | `format` | string | traceparent/sentry-trace/b3/b3-multi/datadog。 |
231
+ | `injected` | boolean | true 表示 SDK 生成并注入,false 表示使用业务既有上下文。 |
232
+
233
+ Link 保存规范化 `trace_id` / `span_id`,不上报原始厂商 Header。sw8 或仅采样标记等无法映射为合法 id 时,不生成随机占位 Link,也不额外注入。Link Attributes 统一经过 `privacy.redactAttributes`,全局 `tracking.beforeSend` 可访问导出副本中的 `links` / `events`。`tracestate` 不注入、不记录。
215
234
 
216
235
  网络阶段字段均为 number、单位 ms。每个 `*.start` 相对该 Resource Entry 的 `startTime`,每个 `*.duration` 为对应阶段结束值减开始值:
217
236
 
@@ -234,21 +253,32 @@ Link 的 `trace_id` / `span_id` 优先取自解析结果;`sw8` 这类无法映
234
253
 
235
254
  如果公共时间点缺失、不是有限数或顺序异常,SDK 会放弃整组阶段字段,避免产生负耗时。Resource Timing 的跨域详细信息还受 `Timing-Allow-Origin` 响应头限制。
236
255
 
237
- 请求结果映射(只写 `outcome.type`,不写 `outcome.reason`):HTTP `408/504` 为 `timeout`;其他 `4xx`/`5xx` 为 `error`;Fetch AbortError 或 XHR `abort` 为 `abort`;Fetch TimeoutError 或 XHR `timeout` 为 `timeout`;其他网络失败为 `error`;其余为 `success`。细分失败原因请用 `http.response.status_code` 或 Fetch/XHR 的 exception Event。
256
+ 请求结果映射(只写 `outcome.type`,不写 `outcome.reason`):HTTP `408/504` 为 `timeout`;其他 `4xx`/`5xx` 为 `error`;Fetch AbortError 或 XHR `abort` 为 `abort`;Fetch TimeoutError 或 XHR `timeout` 为 `timeout`;其他网络失败为 `error`;无法取得有效 HTTP 状态且无明确失败证据时为 `unknown`;其余有效 HTTP 响应为 `success`。细分失败原因请用 `http.response.status_code` 或 Fetch/XHR 的 exception Event。
257
+
258
+ ## 浏览器原始时间点字段
259
+
260
+ 当前 SDK 保留现有字段的同时,追加 `timing.*` 时间点;完整白名单与浏览器字段映射见 [RUM 语义约定:timing](./span-protocol.md#o-timing)。
261
+
262
+ - resource:读取 `PerformanceResourceTiming` 的 16 个时间点。
263
+ - 初始 view:复用上述 16 个请求时间点,另外读取 `unloadEventStart/End`、`domContentLoadedEventStart/End`、`loadEventStart/End`、`activationStart` 共 7 个专属时间点。
264
+
265
+ 初始 View 每次上报 start/update/end 时,都会重新读取导航时间点,`view.*` 导航字段与 `timing.*` 同步更新。
266
+
267
+ 所有 `timing.*` 仅包含 `start_time`、`*_start` 和 `*_end` 字段,均为相对 `performance.timeOrigin` 的浏览器原始时间点,类型为 number,单位 ms。
238
268
 
239
269
  ## 错误字段
240
270
 
241
271
  三类自动浏览器错误都设置 `outcome.type=error`、OTLP Status `ERROR`,并记录 `exception` Span Event。错误来源由 `error.source` 表达。
242
272
 
243
- | 字段 | 类型 | 适用范围 | 来源与详细说明 |
244
- | -------------------- | ------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
245
- | `error.message` | string | 三类自动错误 | 归一后的错误消息。Error 使用 `message`,字符串直接使用,其他值优先 JSON 序列化,失败时转为字符串。资源加载错误消息会包含资源原始 URL,应使用 `redactAttributes` 做额外脱敏。 |
246
- | `error.handled` | boolean | 三类自动错误 | 当前自动采集固定为 `false`,表示该错误来自未处理的全局错误入口;不代表业务代码完全没有 try/catch。 |
247
- | `error.source` | string | 三类自动错误/CSP | `window.error`、`unhandledrejection`、`resource`;CSP Span 固定为 `csp`。用于区分采集入口。 |
248
- | `code.filepath` | string | `error.source=window.error` | `ErrorEvent.filename`,即浏览器报告的脚本文件地址。浏览器未提供或跨域屏蔽时可能为空。 |
249
- | `code.lineno` | number | `error.source=window.error` | `ErrorEvent.lineno`,错误在脚本中的 1-based 行号;浏览器无法定位时可能为 `0`。 |
250
- | `code.column` | number | `error.source=window.error` | `ErrorEvent.colno`,错误列号;具体是否 0-based 由浏览器实现决定。 |
251
- | `url.full` | string | `error.source=resource` | 加载失败元素的 `src`、`href` 或 `currentSrc`,经 `redactUrl` 脱敏。浏览器拿不到资源地址时可能为空字符串。 |
273
+ | 字段 | 类型 | 适用范围 | 来源与详细说明 |
274
+ | --------------- | ------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
275
+ | `error.message` | string | 三类自动错误 | 归一后的错误消息。Error 使用 `message`,字符串直接使用,其他值优先 JSON 序列化,失败时转为字符串。资源加载错误消息会包含资源原始 URL,应使用 `redactAttributes` 做额外脱敏。 |
276
+ | `error.handled` | boolean | 三类自动错误 | 当前自动采集固定为 `false`,表示该错误来自未处理的全局错误入口;不代表业务代码完全没有 try/catch。 |
277
+ | `error.source` | string | 三类自动错误/CSP | `window.error`、`unhandledrejection`、`resource`;CSP Span 固定为 `csp`。用于区分采集入口。 |
278
+ | `code.filepath` | string | `error.source=window.error` | `ErrorEvent.filename`,即浏览器报告的脚本文件地址。浏览器未提供或跨域屏蔽时可能为空。 |
279
+ | `code.lineno` | number | `error.source=window.error` | `ErrorEvent.lineno`,错误在脚本中的 1-based 行号;浏览器无法定位时可能为 `0`。 |
280
+ | `code.column` | number | `error.source=window.error` | `ErrorEvent.colno`,错误列号;具体是否 0-based 由浏览器实现决定。 |
281
+ | `url.full` | string | `error.source=resource` | 加载失败元素的 `src`、`href` 或 `currentSrc`,经 `redactUrl` 脱敏。浏览器拿不到资源地址时可能为空字符串。 |
252
282
 
253
283
  当前 **不上报** `error.cross_origin` 或 `html.tag`。跨域脚本错误只能通过 `error.message` 为 `Script error.`、且 `code.filepath` 为空来识别。资源加载失败的元素标签只出现在 `error.message` 里(格式 `Resource load failed: <tag> <原始 URL>`),需要按标签聚合时应在服务端解析该文本。
254
284
 
@@ -260,104 +290,150 @@ Link 的 `trace_id` / `span_id` 优先取自解析结果;`sw8` 这类无法映
260
290
 
261
291
  以下场景可能包含名为 `exception` 的 Span Event:三类自动浏览器错误、Fetch timeout/network reject、Fetch/XHR 同步抛出的 Error、带 `error` 的 `custom.<name>`。主动 abort 不记录 exception。Event 字段由 OpenTelemetry `recordException` 生成:
262
292
 
263
- | Event 字段 | 类型 | 条件 | 来源与详细说明 |
264
- | ---------------------- | ------ | ----------------- | --------------------------------------------------------------------------------------------- |
293
+ | Event 字段 | 类型 | 条件 | 来源与详细说明 |
294
+ | ---------------------- | ------ | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
265
295
  | `exception.type` | string | 能识别异常类型 | Error 的 `name`;非 Error 值时由 SDK 补类型:Promise rejection 为 `UnhandledRejection`,资源错误为 `ResourceError`,`window.error` 抛非 Error 值时为 `window.error`。 |
266
- | `exception.message` | string | 能提取异常消息 | Error message 或归一后的异常文本,用于错误检索和展示。 |
267
- | `exception.stacktrace` | string | Error 带 stack 时 | 浏览器提供的调用栈。跨域、非 Error rejection 或浏览器安全策略可能导致缺失。 |
296
+ | `exception.message` | string | 能提取异常消息 | Error message 或归一后的异常文本,用于错误检索和展示。 |
297
+ | `exception.stacktrace` | string | Error 带 stack 时 | 浏览器提供的调用栈。跨域、非 Error rejection 或浏览器安全策略可能导致缺失。 |
268
298
 
269
299
  请求的 HTTP 非成功状态只设置 Span Attribute/Status,不会自动生成 exception Event;只有实际抛出 Error 时才记录异常。
270
300
 
271
301
  ## Web Vitals 字段
272
302
 
273
- `span_type=vital` 上报 CLS、FCP、INP、LCP 和 TTFB。FCP/LCP/TTFB 由 `web-vitals/attribution` 采集导航级指标;CLS/INP 按 SDK View 边界汇总,View 结束时上报。
303
+ `span_type=vital` 上报 CLS、FCP、INP、LCP 和 TTFB。文档 FCP/LCP/TTFB 固定绑定初始 View,BFCache 指标绑定恢复 View;CLS/INP 按 View 时间区间汇总。活跃 CLS/INP 和 LCP 候选变化通过约 3 秒合并检查点更新;flush、hidden、freeze、View 结束、shutdown 及已结束 View 的迟到条目也可产生修订。检查点不是用户活动,3 秒不保证网络送达时间。
274
304
 
275
- | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
276
- | -------------- | ------ | --------- | ------------------------------------------------------------------------------------------------------- |
277
- | `vital.metric` | string | 必有 | 指标名的小写值:`cls`、`fcp`、`inp`、`lcp`、`ttfb`。Span 名使用对应的大写值。 |
278
- | `vital.value` | number | 必有 | 指标值。CLS 是无量纲分数;FCP、INP、LCP、TTFB 单位均为 ms。非有限值不会上报。 |
279
- | `vital.id` | string | 必有 | 单条 Vital 的唯一 ID。FCP/LCP/TTFB 沿用 `web-vitals` ID;按 View 汇总的 CLS/INP 由 SDK 生成。 |
305
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
306
+ | --------------- | ------ | --------- | ------------------------------------------------------------------------------------------ |
307
+ | `vital.metric` | string | 必有 | 指标名的小写值:`cls`、`fcp`、`inp`、`lcp`、`ttfb`。Span 名使用对应的大写值。 |
308
+ | `vital.value` | number | 必有 | 指标值。CLS 是无量纲分数;FCP、INP、LCP、TTFB 单位均为 ms。非有限值不会上报。 |
309
+ | `vital.id` | string | 必有 | SDK 生成的稳定指标 ID;同一作用域内同一指标的修订保持不变。 |
310
+ | `vital.version` | number | 必有 | 从 1 开始递增的快照版本;值、归因、View 上下文均无变化时不重复发送。 |
311
+ | `vital.scope` | string | 必有 | `document`:文档初始指标;`activation`:BFCache 恢复指标;`view`:按 View 汇总的 CLS/INP。 |
280
312
 
281
- `web-vitals` / SDK 内部仍会计算 rating,但 **不会** 写入 `vital.rating`。`rating=good` 映射为 `outcome.type=success`,其余映射为 `outcome.type=warning`。当前分界:CLS `≤0.1/≤0.25`;INP `≤200/≤500ms`;FCP/LCP/TTFB 沿用 `web-vitals` 默认阈值。也不写入 `navigationType`。
313
+ 服务端按 `vital.id` 取最大版本,不能累加各次 value,也不能将每个快照算作新的 View 样本。Span 起止时间为本次快照生成时刻,原 Session/View 身份保持不变;没有 `vital.final`。普通 SPA 路由不会重算文档 FCP/LCP;当前没有 Soft Navigation 指标采集。
282
314
 
283
- ### LCP Attribution
315
+ 所属 View 仍活跃时,每次生成快照前刷新用户、View 名称和业务上下文;结束后冻结最终上下文。文档/恢复指标也使用所属 View 的这份上下文,不改挂后续 View。View 的相对起止时间与 `PerformanceEntry.startTime` 共用时钟,CLS/INP 归属和相对耗时不混用 `Date.now()`;epoch 时间仅用于事件身份关联及 OTLP 时间戳。
284
316
 
285
- `onLCP` 回调会抽取以下字段;缺失表示浏览器或 `web-vitals` 未提供,不代表 LCP 无效。
317
+ 已结束 CLS/INP 状态允许迟到更新 5 分钟,总状态最多 100 个,按 entry.startTime 的半开区间归属。超出保留范围不改挂当前 View。初始化先恢复保留的 View 历史;首次 manual View 或 BFCache 恢复 View 尚未建立时,指标有界等待关联。授权恢复不会重新采集同一文档的首屏指标。flush/hidden 只是检查点,不结束 View 或续期 Session;shutdown 先导出最后已观测值,再断开原生 observer 和监听,无法等待未来才生成的浏览器条目。
286
318
 
287
- | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
288
- | ---------------------------------- | ------ | ----------------------- | ---------------------------------------------------------------------------------- |
289
- | `vital.lcp.url` | string | LCP 是图片等 URL 资源时 | LCP 资源 URL,经 `redactUrl` 脱敏。文本 LCP 没有资源 URL,因此缺失。 |
290
- | `vital.lcp.target` | string | 能定位 LCP 元素时 | `web-vitals` 生成的目标元素选择器/描述,用于定位拖慢最大内容绘制的 DOM 元素。 |
291
- | `vital.lcp.element_render_delay` | number | ms | LCP 资源加载完成到元素最终绘制之间的耗时。 |
292
- | `vital.lcp.resource_load_duration` | number | ms | LCP 资源自身从请求开始到响应结束的下载耗时。 |
319
+ SDK 内部计算 rating,但 **不会** 写入 `vital.rating`。`rating=good` 映射为 `outcome.type=success`,其余映射为 `outcome.type=warning`。当前 good/needs-improvement 上界分别为:CLS `0.1/0.25`;INP `200/500ms`;FCP `1800/3000ms`;LCP `2500/4000ms`;TTFB `800/1800ms`。也不写入 `navigationType`。
293
320
 
294
- 当前 **不上报** `vital.lcp.time_to_first_byte`。
321
+ ### LCP Attribution
322
+
323
+ 原生 LCP observer 保存当前候选,在合并检查点、首次可信交互或生命周期检查点发布;不必等首次交互才有 LCP。以下字段由候选及 Navigation/Resource Timing 计算,缺失不代表 LCP 无效。
324
+
325
+ | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
326
+ | ---------------------------------- | ------ | ----------------------- | --------------------------------------------------------------------------------- |
327
+ | `vital.lcp.url` | string | LCP 是图片等 URL 资源时 | LCP 资源 URL,经 `redactUrl` 脱敏。文本 LCP 没有资源 URL,因此缺失。 |
328
+ | `vital.lcp.target` | string | 能安全定位 LCP 元素时 | 观测候选时按 Action 隐私规则快照 selector;无法安全获取时省略,不回退原始 DOM ID。 |
329
+ | `vital.lcp.element_render_delay` | number | ms | LCP 资源加载完成到元素最终绘制之间的耗时。 |
330
+ | `vital.lcp.resource_load_duration` | number | ms | LCP 资源自身从请求开始到响应结束的下载耗时。 |
331
+ | `vital.lcp.time_to_first_byte` | number | ms | LCP 拆分中的首字节时间。 |
332
+ | `vital.lcp.resource_load_delay` | number | ms | 首字节到 LCP 资源开始加载的延迟。 |
295
333
 
296
334
  ### CLS Attribution
297
335
 
298
- CLS 由 SDK 按 View 自行汇总,上报时 `attribution` 为空对象。因此 `vital.cls.load_state`、`vital.cls.largest_shift_target`、`vital.cls.largest_shift_value` **当前均不产生**。
336
+ CLS 归因选取最大累计窗口内最大的单次 Shift,不会被同窗口后续较小偏移覆盖。来源节点按 previous/current 两矩形的并集面积选择,包含节点消失时的原矩形,不计算包围盒中间的空白。
337
+
338
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
339
+ | --- | --- | --- | --- |
340
+ | `vital.cls.time` | number | ms | 最大窗口内主要 Shift 的时刻,相对所属 View 起点。 |
341
+ | `vital.cls.target_selector` | string | 能安全定位时 | 主要 Shift 中并集受影响面积最大的 source 节点,采用 Action 隐私规则。 |
342
+ | `vital.cls.previous_rect.x/y/width/height` | number | CSS px | 位移前矩形,展开为四个标量。 |
343
+ | `vital.cls.current_rect.x/y/width/height` | number | CSS px | 位移后矩形,展开为四个标量。 |
344
+ | `vital.cls.device_pixel_ratio` | number | 可获取有效 DPR 时 | 捕获主要 Shift 时的设备像素比;矩形属性本身仍为 CSS px。 |
299
345
 
300
- CLS 忽略 `hadRecentInput=true` 的偏移,并按“相邻偏移间隔小于 1 秒、窗口最长 5 秒”的 Session Window 规则取最大窗口累计值。View 结束时即使没有布局偏移也会上报 `vital.value=0`。
346
+ 浏览器/source/安全节点定位不可用时省略相应字段。不产生 `vital.cls.load_state` 或 `vital.cls.largest_shift_*`。
347
+
348
+ CLS 忽略 `hadRecentInput=true` 的偏移,并按“相邻偏移间隔小于 1 秒、窗口最长 5 秒”的 Session Window 规则取最大窗口累计值。浏览器支持 Layout Shift 时可发送 0 值检查点;不支持时不伪造 0。
301
349
 
302
350
  ### INP Attribution
303
351
 
304
- View 结束时,SDK 把选中的 p98 候选写入以下字段:
352
+ 有有效候选时,SDK 将选中的近似 p98 交互写入以下字段:
353
+
354
+ | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
355
+ | ------------------------------- | ------ | -------------------- | -------------------------------------------------------------- |
356
+ | `vital.inp.interaction_target` | string | 能安全定位交互元素时 | Action 显式命名模式的名称或标签回退,不采集整段 DOM 文本。 |
357
+ | `vital.inp.target_selector` | string | 能安全定位交互元素时 | 优先使用交互时已按 Action 隐私规则捕获的 selector。 |
358
+ | `vital.inp.time` | number | ms | 候选归因分组内最早输入时间,相对所属 View 起点。 |
359
+ | `vital.inp.interaction_type` | string | 有候选时 | Performance Event 名,例如 `click`、`keydown`。 |
360
+ | `vital.inp.input_delay` | number | ms | 从用户输入发生到浏览器开始执行事件处理器的延迟。 |
361
+ | `vital.inp.processing_duration` | number | ms | 分组最早处理开始到最晚处理结束的区间,按共同终点裁剪。 |
362
+ | `vital.inp.presentation_delay` | number | ms | 处理结束到共同绘制终点的耗时;三段非负且合计等于 `vital.value`。 |
305
363
 
306
- | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
307
- | ------------------------------- | ------ | ---------------- | -------------------------------------------------------------------------------------------------------- |
308
- | `vital.inp.interaction_target` | string | 能定位交互元素时 | 触发 INP 候选交互的元素描述。SDK 优先 `data-bk-action-name`、`aria-label`、`name`,否则使用小写 tag 名。 |
309
- | `vital.inp.interaction_type` | string | 必有 | Performance Event 名,例如 `click`、`keydown`。 |
310
- | `vital.inp.input_delay` | number | ms | 从用户输入发生到浏览器开始执行事件处理器的延迟。 |
311
- | `vital.inp.processing_duration` | number | ms | 从事件处理开始到处理结束的耗时。 |
312
- | `vital.inp.presentation_delay` | number | ms | 事件处理完成到下一帧呈现的耗时。三段之和应近似 `vital.value`。 |
364
+ INP 候选 observer 阈值为 40ms,另观察 first-input,并以独立低阈值流计数。浏览器支持且明确有交互但无候选时可以发送 0,迟到候选再修订;无交互或不支持时不发送。原生 interactionCount 在 View 结束时冻结,并校正跨边界迟到交互;降级使用 interactionId 范围估算,仍受浏览器条目分辨率限制。保留最慢 10 个候选,选近似 p98;值上限为 60,000ms。
313
365
 
314
- INP 只在 View 内至少观察到一次带 `interactionId` 的 Event Timing 时上报;Performance Observer 的 `durationThreshold` 为 40ms,值最大限制为 60,000ms。SDK 保留最慢的 10 个交互候选,并按交互数量选择近似 p98 候选。
366
+ 分段归因合并同 interactionId 或渲染时刻位于固定参考帧 ±8ms 内的条目;同一批次合并后再裁剪分组,只保留与 10 个候选关联的状态。三段与 60 秒限幅后的值共用终点,避免超长处理使阶段总和大于上报值。交互目标快照只匹配 10 秒内的输入,最多保留 100 项,仅存已通过隐私规则的字符串;目标被路由卸载后仍可使用已有快照,禁止采集的结果不触发 DOM 回退。
315
367
 
316
368
  ### FCP Attribution
317
369
 
318
- `onFCP` 只上报公共 `vital.*` 字段。`pickAttribution()` 对 `FCP` 没有抽取分支,因此 **不上报** `vital.fcp.time_to_first_byte` 或 `vital.fcp.load_state`。
370
+ 原生 Paint Timing 的 FCP 只上报公共 `vital.*` 字段,**不上报** `vital.fcp.time_to_first_byte` 或 `vital.fcp.load_state`。BFCache 恢复的 FCP/LCP 使用双 animation frame 近似恢复绘制时间,不是新的文档首屏。
319
371
 
320
372
  ### TTFB Attribution
321
373
 
322
374
  | 字段 | 类型 | 单位 | 来源与详细说明 |
323
375
  | -------------------------------- | ------ | ---- | ---------------------------------------------------------------------------------- |
324
376
  | `vital.ttfb.waiting_duration` | number | ms | 从导航激活到浏览器开始处理请求前的等待时间。重定向和其他浏览器前置处理会增加该值。 |
377
+ | `vital.ttfb.cache_duration` | number | ms | workerStart/fetchStart 至 domainLookupStart 的阶段耗时;不是缓存命中标记。 |
325
378
  | `vital.ttfb.dns_duration` | number | ms | 主文档域名 DNS 解析耗时;命中 DNS 缓存、连接复用或 Service Worker 场景可能为 `0`。 |
326
379
  | `vital.ttfb.connection_duration` | number | ms | 建立主文档连接的耗时,通常包含 TCP/QUIC 和 TLS;复用连接时可能为 `0`。 |
327
380
  | `vital.ttfb.request_duration` | number | ms | 连接结束到收到响应首字节的剩余时间,包含请求发送、网络往返和服务器处理。 |
328
381
 
382
+ TTFB 按文档 Navigation Timing 的相邻边界计算;prerender 从 activationStart 扣除预渲染时间。五段均裁剪为非负,总和等于 `vital.value`;BFCache 恢复时 TTFB 和五段均为 0。`cache_duration` 不能用于判断 memory/disk cache 命中。
383
+
329
384
  Attribution 字段受浏览器能力和指标实现影响,缺失不代表指标本身无效。当前 SDK 有意只选取诊断价值较高的标量字段,不上传原始 Performance Entry、DOM 节点或完整归因对象。
330
385
 
331
386
  ## Action 字段
332
387
 
333
- | 字段 | 类型 | 自动 Click | 手动 Action | 来源与详细说明 |
334
- | ------------------------- | -------- | ------------------------ | -------------- | --------------------------------------------------------------------------------------------------------- |
335
- | `action.id` | string | 必有 | 必有 | 当前 Action 的唯一 ID。自动 Action 活动期间,其他 Span 上的同名运行时字段也是单个 string。 |
336
- | `action.type` | string | 固定 `click` | 固定 `custom` | 区分自动点击和 `reportAction` 主动上报。 |
337
- | `action.name` | string | `click <target>` | payload `name` | 可读的低基数名称,也是 Span 名。自动点击目标名默认来自显式 `data-bk-action-name`,启用文本采集后才会回退到可访问名称/DOM 文本。 |
338
- | `action.target.name` | string | 必有 | 不写 | 自动点击提取的目标名称,最多 100 字符;默认隐私模式下未显式命名时通常为小写 tag 名。 |
339
- | `action.target.tag` | string | 必有 | 不写 | 实际点击目标的原始 `tagName`,SDK 转为小写。 |
340
- | `action.frustration.type` | string[] | 检出挫败信号时 | 不写 | 可包含 `rage_click`、`dead_click`、`error_click`;一次 Action 可同时命中多个值。 |
341
-
342
- 点击后若有可观察页面活动,SDK 用 Span 的 `startTimeUnixNano`/`endTimeUnixNano` 表达持续时间,**不上报** `action.loading_time` 属性。无页面副作用时 Span 起止时间相同。
343
-
344
- `rage_click` 表示 1 秒内、100px 范围内连续至少三次点击;`dead_click` 表示点击后没有页面活动、输入、滚动或选择等反馈(链接、表单输入等会排除);`error_click` 表示 Action 生命周期内出现错误。有错误或任一挫败信号时为 `outcome.type=warning`,具体类型只由 `action.frustration.type` 表达。
388
+ | 字段 | 类型 | 自动 Click | 手动 Action | 来源与详细说明 |
389
+ | ------------------------- | -------- | ---------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
390
+ | `action.id` | string | 必有 | 必有 | Action 自身的唯一 ID,始终为单个字符串。子事件通过 `action.ids` 数组关联,不再使用同名字段。 |
391
+ | `action.type` | string | 固定 `click` | 固定 `custom` | 区分自动点击和 `reportAction` 主动上报。 |
392
+ | `action.name` | string | `click <target>` | payload `name` | 可读的低基数名称,也是 Span 名。自动点击目标名默认来自显式 `data-bk-action-name`,启用文本采集后才会回退到可访问名称/DOM 文本。 |
393
+ | `action.target.name` | string | 必有 | 不写 | 自动点击提取的目标名称,最多 100 字符;默认隐私模式下未显式命名时通常为小写 tag 名。 |
394
+ | `action.target.tag` | string | 必有 | 不写 | 实际点击目标的原始 `tagName`,SDK 转为小写。 |
395
+ | `action.target.selector` | string | 可定位且隐私允许 | 不写 | 采集时的目标唯一定位结果,最长 512 字符;稳定属性/ID 优先,结构回退。Shadow 边界为非标准 CSS 的 `::shadow` 标记,不保证跨部署稳定。 |
396
+ | `action.target.path` | string[] | 可定位且隐私允许 | 不写 | composedPath 中 Element 的 selector,目标到祖先顺序,最多 10 项、总长 2048 字符;不是原始 DOM 或完整属性。 |
397
+ | `action.target.width` | number | 可测量且隐私允许 | 不写 | 目标宽度,CSS px。 |
398
+ | `action.target.height` | number | 可测量且隐私允许 | 不写 | 目标高度,CSS px。 |
399
+ | `action.position.x` | number | 可测量且隐私允许 | 不写 | 点击相对目标的横坐标,CSS px。 |
400
+ | `action.position.y` | number | 可测量且隐私允许 | 不写 | 点击相对目标的纵坐标,CSS px。 |
401
+ | `action.name_source` | string | 必有 | 不写 | `explicit`、`accessible_name`、`text` 或 `fallback`。默认 explicit;mask 阻止文本/可访问名称但允许显式标签,hidden 目标不创建 Action。 |
402
+ | `action.loading_time` | number | 仅正常稳定时 | 不写 | 从 click 到确认的页面活动稳定终点,单位 **ms**,与 `view.loading_time` 一致;不含尾部安静等待。 |
403
+ | `action.end_reason` | string | 必有 | 不写 | `activity_end`、`no_activity`、`timeout`、`view_change`、`session_expired`、`page_hidden`、`page_exit` 或 `shutdown`。 |
404
+ | `action.frustration.type` | string[] | 检出挫败信号时 | 不写 | 可包含 `rage_click`、`dead_click`、`error_click`;一次 Action 可同时命中多个值。 |
405
+
406
+ Span 的 `startTimeUnixNano`/`endTimeUnixNano` 表达已观察区间,正常结束包含尾部 100ms 确认等待,不等同于 Loading Time。仅 `action.end_reason=activity_end` 时写 `action.loading_time`;无活动、超时、View/Session 边界或隐藏/退出等中断均不写,缺失不能解释为 `0`。Error/Long Task 仅关联,不延长页面活动窗口。
407
+
408
+ `rage_click` 表示 1 秒内、100px 范围内连续至少三次点击,当前仍为各次独立 Action 标记,不合并也不写分组 ID;`dead_click` 表示点击后没有页面活动、输入、滚动或选择等反馈(链接、表单输入等会排除);`error_click` 仅由通过过滤进入 SDK 发送流、且 `action.ids` 包含该 Action 的 Error 触发。有错误或任一挫败信号时为 `outcome.type=warning`,具体类型由 `action.frustration.type` 表达;未命中时不写该数组。Outcome 不等同于业务成功或失败。
409
+
410
+ `action.error.count`、`action.resource.count`、`action.long_task.count` 仍由服务端从子事件 `action.ids` 派生,客户端不写。普通 flush 只发送准备好的 Span,不强行结束活动窗口。自动点击随 View 边界关闭,已经开始的请求晚到仍使用原关联。
345
411
 
346
412
  `reportAction({ attributes })` 的业务 Attribute 会合并到手动 Action Span,但固定分类和事件字段由 SDK 写入。业务应避免复用本页保留字段名。
347
413
 
348
414
  ## 白屏字段
349
415
 
350
- 白屏插件在页面活动稳定后对视口九宫格采样,并在默认 200ms 间隔后再次确认;每个 View 最多上报一次。
351
-
352
- | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
353
- | ----------------------------- | ------ | ------------------ | -------------------------------------------------------------------------------------------------- |
354
- | `blank_screen.reason` | string | 必有 | `missing_root`:配置的根节点不存在,检测回退到 `body`/`documentElement`;`empty_viewport`:配置根节点存在。 |
355
- | `blank_screen.empty_ratio` | number | `0..1` | `emptyCount / validCount`。默认阈值为 `0.8`。根节点缺失时仍是回退后的实际比例,不是固定 `1`。 |
356
- | `blank_screen.empty_sample_count` | number | 必有 | 有效采样点中,没有发现根节点内可见内容元素的点数。 |
357
-
358
- 当前 **不上报** `blank_screen.sample_count`、`valid_sample_count`、`ignored_sample_count`、`root_selector`、`root_found`、`center_element`。分母为 0 时不报告白屏。
359
-
360
- 该 Span 固定为 `span_type=error`、`outcome.type=error`,不写 `outcome.reason`,也不设置 OTLP Status ERROR,不记录 exception Event。检测是基于采样点的启发式判断,应结合错误和 View 数据进一步确认。
416
+ 策略版本2:按View持续监听活动并节流复检,等待文档就绪;候选空白经二次确认,活动变化重置候选。每次持续故障仅一个 detected,恢复后允许再次故障。
417
+
418
+ | 字段 | 类型/条件 | 语义 |
419
+ | ----------------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
420
+ | `blank_screen.phase` | string | detected / recovered / observation |
421
+ | `blank_screen.state` | string | blank / content / loading / unknown |
422
+ | `blank_screen.strategy_version` | number | 当前为2,标明证据算法口径 |
423
+ | `blank_screen.reason` | string | detected: empty_viewport/missing_root;observation: loading_visible/insufficient_evidence/activity_timeout/document_not_ready/detection_unavailable |
424
+ | `blank_screen.trigger` | string | View、页面活动、visible、document_ready等触发来源 |
425
+ | `blank_screen.id` | string,故障及恢复 | 同一次持续故障的关联ID |
426
+ | `blank_screen.first_detected_at` | epoch ms,故障及恢复 | 首次候选空白时刻 |
427
+ | `blank_screen.detected_at` | epoch ms,故障及恢复 | 二次确认时刻 |
428
+ | `blank_screen.recovered_at` | epoch ms,恢复 | 重新观察到内容的时刻 |
429
+ | `blank_screen.duration` | ms,恢复 | 首次候选至恢复;不是两个采样之间每个像素持续空白的证明 |
430
+ | `blank_screen.empty_ratio` | number,有采样结果 | 空白有效点比例 |
431
+ | `blank_screen.empty_sample_count` | number,有采样结果 | 空白点数 |
432
+ | `blank_screen.valid_sample_count` | number,有采样结果 | 可解释的空白/内容点数 |
433
+ | `blank_screen.ignored_sample_count` | number,有采样结果 | loading覆盖点数 |
434
+ | `blank_screen.unknown_sample_count` | number,有采样结果 | 媒体、Shadow DOM或预算不足等未知点数 |
435
+
436
+ 仅 detected 使用 `span_type=error/outcome.type=error`;recovered 使用 custom/success,observation 使用 custom/unknown,后两者不得累计为错误。未知、持续loading和文档未就绪均不伪报白屏;不采集截图、DOM全文、root selector或异常堆栈。`maxWait` 默认10000ms,长等待产生诊断状态并继续有界复检。
361
437
 
362
438
  ## Long Task 字段
363
439
 
@@ -365,15 +441,15 @@ Attribution 字段受浏览器能力和指标实现影响,缺失不代表指
365
441
 
366
442
  ### Span 顶层字段
367
443
 
368
- | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
369
- | ------------------------------------ | ------ | ------------------------------- | -------------------------------------------------------------------------------------------------- |
370
- | `long_task.id` | string | 必有 | 当前 Long Task/LoAF 事件的随机唯一 ID,用于关联其 Span Event。 |
371
- | `long_task.entry_type` | string | 必有 | `long-animation-frame` 或 `long-task`,表示使用的浏览器 Performance Entry 类型。 |
372
- | `long_task.name` | string | 必有 | 浏览器 Performance Entry 的 `name`;Legacy Long Task 常见为 `self` 或跨上下文归因名称。 |
373
- | `long_task.blocking_duration` | number | 仅 LoAF,ms | 浏览器计算的阻塞时间,表示超出可接受帧预算、真正阻塞交互响应的部分,不等于完整持续时间。 |
374
- | `long_task.first_ui_event_timestamp` | number | LoAF 提供时,相对 timeOrigin ms | 该帧内首个 UI Event 的时间点;可判断长帧是否直接阻塞用户输入。 |
375
- | `long_task.render_start` | number | LoAF 提供时,相对 timeOrigin ms | 浏览器开始本帧渲染阶段的时间点。 |
376
- | `long_task.style_and_layout_start` | number | LoAF 提供时,相对 timeOrigin ms | 本帧开始样式计算和布局的时间点,可与 `render_start` 分析渲染阶段开销。 |
444
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
445
+ | ------------------------------------ | ------ | ------------------------------- | ---------------------------------------------------------------------------------------- |
446
+ | `long_task.id` | string | 必有 | 当前 Long Task/LoAF 事件的随机唯一 ID,用于关联其 Span Event。 |
447
+ | `long_task.entry_type` | string | 必有 | `long-animation-frame` 或 `long-task`,表示使用的浏览器 Performance Entry 类型。 |
448
+ | `long_task.name` | string | 必有 | 浏览器 Performance Entry 的 `name`;Legacy Long Task 常见为 `self` 或跨上下文归因名称。 |
449
+ | `long_task.blocking_duration` | number | 仅 LoAF,ms | 浏览器计算的阻塞时间,表示超出可接受帧预算、真正阻塞交互响应的部分,不等于完整持续时间。 |
450
+ | `long_task.first_ui_event_timestamp` | number | LoAF 提供时,相对 timeOrigin ms | 该帧内首个 UI Event 的时间点;可判断长帧是否直接阻塞用户输入。 |
451
+ | `long_task.render_start` | number | LoAF 提供时,相对 timeOrigin ms | 浏览器开始本帧渲染阶段的时间点。 |
452
+ | `long_task.style_and_layout_start` | number | LoAF 提供时,相对 timeOrigin ms | 本帧开始样式计算和布局的时间点,可与 `render_start` 分析渲染阶段开销。 |
377
453
 
378
454
  Span 持续时间就是 `PerformanceEntry.duration`(起止时间已转换为 epoch)。当前 **不上报** `long_task.duration` 或 `long_task.start_time` Attribute;需要原始 Performance Timeline 坐标时,用 `long_task.render_start` 等 LoAF 字段,或从 Span 起始时间减去 Resource 上的 SDK 时间基准。
379
455
 
@@ -467,7 +543,7 @@ Legacy Long Task 的每个 attribution 条目生成一个 Event,Event 时间
467
543
  - `reportAction/reportCustomEvent` 的 payload `attributes`。
468
544
  - `useInstrumentation()` 注册的第三方 OpenTelemetry Instrumentation 字段;只要创建时具备采样 Session/View 上下文,也可能进入同一导出链路。
469
545
 
470
- 这些字段同样必须是合法 OpenTelemetry Attribute,并会进入全局 `tracking.beforeSend`。SDK API、View 和自定义插件写入的属性会经过 `redactAttributes`;第三方 Instrumentation 自带属性不会自动经过该钩子,具体边界见“上报准入与字段覆盖”。后端建模时应把接入方自定义字段与本页 SDK 稳定字段分开治理。
546
+ 这些字段同样必须是合法 OpenTelemetry Attribute,并会进入全局 `tracking.beforeSend`。SDK API、View 和自定义插件写入的属性会经过 `redactAttributes`;第三方 Instrumentation 自带属性及 Event/Link 属性也在最终导出阶段经过该钩子。后端建模时应把接入方自定义字段与本页 SDK 稳定字段分开治理。
471
547
 
472
548
  过滤器会读取第三方 HTTP Instrumentation 常用的 `http.url`,以识别并丢弃指向 SDK Collector 的自身上报请求;BK RUM 内置请求插件实际写入的是 `url.full`,不会主动产生 `http.url`。
473
549
 
@@ -476,16 +552,15 @@ Legacy Long Task 的每个 attribution 条目生成一个 Event,Event 时间
476
552
  当前源码不会产生:
477
553
 
478
554
  - `/v1/metrics`、`/v1/logs` 请求,以及 Counter、Histogram、Gauge、LogRecord。
479
- - `session.duration`、`view.duration`、`session.start_time`、`session.lifecycle.reason`、`session.previous_id`。
555
+ - `session.duration`、`view.duration`、`session.lifecycle.reason`、`session.previous_id`。
480
556
  - `outcome.reason`;失败细分由领域字段表达。
481
- - `vital.rating`、`vital.cls.*` 归因、`vital.fcp.*` 归因、`vital.lcp.time_to_first_byte`。
482
- - `action.loading_time`;持续时间由 Span 起止时间表达。
557
+ - `vital.rating`、`vital.fcp.*` 归因、`vital.cls.load_state`、`vital.cls.largest_shift_*`。
483
558
  - `blank_screen.sample_count`、`valid_sample_count`、`ignored_sample_count`、`root_selector`、`root_found`、`center_element`。
484
559
  - `long_task.duration`、`long_task.start_time`。
485
560
  - `error.cross_origin`、`html.tag`。
486
561
  - `device.memory_gib` 及逻辑处理器数字段;Device Resource 只读 UA/UA-CH,不读 `navigator.deviceMemory` 或 `hardwareConcurrency`。
487
562
  - `tracestate`;SDK 既不注入也不记录。
488
- - Action、Resource、Error、Long Task count;计数和分布应从原始 Span 聚合。
563
+ - Action、Resource、Error、Long Task count,包括 `action.error.count`、`action.resource.count`、`action.long_task.count`;计数和分布应从原始 Span 聚合。
489
564
  - 错误 fingerprint/group;错误分组由服务端根据 exception、message、stack 等字段计算。
490
565
  - HTTP request/response Body、Header;Trace Context 注入不代表采集请求内容。
491
566
  - WebSocket message 内容、数量、字节数。