@blueking/open-telemetry 0.0.30 → 0.0.32

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 (27) hide show
  1. package/README.md +61 -24
  2. package/dist/bk-rum.global.js +1 -1
  3. package/dist/bk-rum.global.js.map +1 -1
  4. package/dist/index.js +368 -357
  5. package/dist/index.js.map +1 -1
  6. package/dist/schema/attributes.d.ts +1 -0
  7. package/package.json +1 -1
  8. package/skills/bk-rum-otele/references/actions.md +16 -10
  9. package/skills/bk-rum-otele/references/api.md +5 -2
  10. package/skills/bk-rum-otele/references/architecture.md +2 -2
  11. package/skills/bk-rum-otele/references/blank-screen.md +8 -17
  12. package/skills/bk-rum-otele/references/capabilities.md +2 -2
  13. package/skills/bk-rum-otele/references/configuration.md +4 -4
  14. package/skills/bk-rum-otele/references/data-model.md +14 -14
  15. package/skills/bk-rum-otele/references/errors-security.md +5 -4
  16. package/skills/bk-rum-otele/references/extensions.md +8 -0
  17. package/skills/bk-rum-otele/references/framework-integration.md +1 -1
  18. package/skills/bk-rum-otele/references/getting-started.md +19 -1
  19. package/skills/bk-rum-otele/references/network.md +22 -19
  20. package/skills/bk-rum-otele/references/performance.md +12 -23
  21. package/skills/bk-rum-otele/references/privacy.md +2 -2
  22. package/skills/bk-rum-otele/references/session-context.md +13 -9
  23. package/skills/bk-rum-otele/references/span-protocol.md +265 -100
  24. package/skills/bk-rum-otele/references/telemetry-reference.md +75 -79
  25. package/skills/bk-rum-otele/references/transport-sampling.md +18 -13
  26. package/skills/bk-rum-otele/references/troubleshooting.md +1 -1
  27. package/skills/bk-rum-otele/references/views-routing.md +5 -3
@@ -2,7 +2,7 @@
2
2
 
3
3
  # 遥测字段字典
4
4
 
5
- 本页是当前 SDK 实际产出的 RUM Span、Resource Attribute、Span Attribute 和 Span Event 字典。它面向 Collector 接入、后端建模、查询规则、告警配置和数据验收。SDK 当前只上报 Trace Span,不产出 OpenTelemetry Metric 或 Log。
5
+ 本页是对照 `src/` 手工维护的**当前实现事实**字典,记录 SDK 实际产出的 RUM Span、Resource Attribute、Span Attribute 和 Span Event。它面向 Collector 接入、后端建模、查询规则、告警配置和数据验收。SDK 当前只上报 Trace Span,不产出 OpenTelemetry Metric 或 Log。前后端长期兼容承诺见 [RUM 语义约定](./span-protocol.md)。
6
6
 
7
7
  ## 快速定位
8
8
 
@@ -12,7 +12,7 @@
12
12
  | ---------------------- | --------------------------------------------------------------- | ------------------------------------------------- |
13
13
  | SDK 与应用 Resource | `service.*`、`deployment.environment.name`、`telemetry.sdk.*` | 哪个应用、环境、版本和 SDK 产生了数据? |
14
14
  | RUM 运行时上下文 | `session.id`、`view.id`、`action.id`、`user.id`、设备和网络字段 | 事件属于哪个 Session、View、Action 和用户上下文? |
15
- | 公共分类 | `span_type`、`outcome.type`、`outcome.reason` | 这是什么信号,结果是否正常,失败属于哪类原因? |
15
+ | 公共分类 | `span_type`、`outcome.type` | 这是什么信号,结果是否正常? |
16
16
  | 领域属性 | `resource.*`、`error.*`、`vital.*`、`long_task.*` 等 | 具体发生了什么,耗时、来源和诊断细节是什么? |
17
17
  | OTLP Envelope 与 Event | `traceId`、`spanId`、时间戳、`status`、`events` | 如何定位单条记录、关联调用链和读取异常/脚本归因? |
18
18
 
@@ -72,16 +72,14 @@ Resource Attribute 描述产生 Span 的 SDK 实例和运行环境,同一实
72
72
  | `service.version` | string | 配置 `application.version` 时 | 来自应用版本配置,通常填写发布版本或构建号,用于比较发布前后性能和错误变化。 |
73
73
  | `deployment.environment.name` | string | 必有 | 来自 `application.environment`,未配置时为 `production`。用于区分生产、预发布、测试等环境。 |
74
74
  | `session.sample_rate` | number | 必有 | 解析后的 `session.sampleRate`,范围 `0..1`。表示配置的 Session 采样概率,不表示当前某条 Span 的采样结果。 |
75
- | `telemetry.sdk.name` | string | 必有 | 固定为 `@blueking/open-telemetry`,用于识别数据生产 SDK。 |
75
+ | `telemetry.sdk.name` | string | 必有 | 固定为 `blueking`,用于识别蓝鲸浏览器 RUM SDK。 |
76
76
  | `telemetry.sdk.language` | string | 必有 | 固定为 `webjs`,表示浏览器 JavaScript SDK。 |
77
77
  | `telemetry.sdk.version` | string | 必有 | 当前 npm 包版本,用于排查字段能力或采集行为是否受 SDK 版本影响。 |
78
78
  | `user_agent.name` | string | `tracking.device !== false` 且有浏览器环境 | 从 User-Agent 识别,取值 `Edge`、`Chrome`、`Firefox`、`Safari` 或 `Other`。识别不到时为 `Other`。 |
79
79
  | `user_agent.version` | string | 能识别浏览器版本时 | 从 User-Agent 提取的浏览器主版本号,不包含次版本和补丁版本;识别不到时缺失。 |
80
80
  | `user_agent.os.name` | string | `tracking.device !== false` 且有浏览器环境 | 从 User-Agent / User-Agent Client Hints 推断,取值 `iOS`、`Android`、`macOS`、`Windows`、`Linux` 或 `Other`。 |
81
81
  | `device.type` | string | `tracking.device !== false` 且有浏览器环境 | `mobile` 或 `desktop`。根据 `userAgentData.mobile` 或移动端 User-Agent 特征推断,不代表具体硬件型号。 |
82
- | `device.memory_gib` | number | 浏览器支持 `navigator.deviceMemory` 时 | 浏览器提供的近似设备内存容量,单位 GiB。该值通常已分档并可能受隐私策略限制,不应当作精确物理内存。 |
83
-
84
- `tracking.device=false` 时 SDK 构造的 Resource 不写入设备 Resource 字段。Resource 在 SDK 初始化时经过一次 `redactAttributes`,运行期间不会随窗口或网络状态变化。
82
+ `tracking.device=false` 时 SDK 构造的 Resource 不写入设备 Resource 字段。Resource 在 SDK 初始化时经过一次 `redactAttributes`,运行期间不会随窗口或网络状态变化。当前实现不读取 `navigator.deviceMemory` 或逻辑处理器数量,因此不会出现 `device.memory_gib` 一类硬件容量字段。
85
83
 
86
84
  ## 运行时公共属性
87
85
 
@@ -91,7 +89,6 @@ Resource Attribute 描述产生 Span 的 SDK 实例和运行环境,同一实
91
89
  | ------------------------- | -------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
92
90
  | `user.id` | string | 调用 `setUser({ id })` 后 | 业务提供的用户 ID,SDK 原样写入并经过 `redactAttributes`。建议使用不可逆标识,避免直接上传手机号、邮箱等个人信息。 |
93
91
  | `session.id` | string | Session 有效 | SDK 生成的 Session 关联 ID。15 分钟无活动或 4 小时最大生命周期到期后会更换;同一 Session 的事件可用它聚合。 |
94
- | `session.start_time` | number | Session 有效 | Session 创建时间,单位 epoch ms。它不会因用户活动续期而变化,可用于计算 Session 相对时间。 |
95
92
  | `session.type` | string | Session 有效 | 当前固定为 `user`,为未来区分其他 Session 类型保留。 |
96
93
  | `session.has_replay` | boolean | Session 有效 | 当前固定为 `false`,表示 SDK 没有随该 Session 上报 Session Replay 数据。 |
97
94
  | `view.id` | string | View 有效 | 当前页面视图的关联 ID。首次加载、有效 SPA 路由变化、BFCache 恢复或 Session 续建都会创建新 View。 |
@@ -99,7 +96,7 @@ Resource Attribute 描述产生 Span 的 SDK 实例和运行环境,同一实
99
96
  | `view.url` | string | View 有效 | 创建 View 时的完整 URL,经 `redactUrl` 脱敏。与当前实时 `location.href` 不一定相同。 |
100
97
  | `view.url_template` | string | View 有效 | 低基数路由模板。默认把数字 ID、UUID 和长十六进制路径段归一为 `:id`,也可由 `getUrlTemplate` 自定义。 |
101
98
  | `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。 |
99
+ | `action.id` | string | 自动 Action 活动中 | 当前活动的自动 Action ID。多个点击窗口重叠时取最近一次开始的 Action;Action Span 自身的同名字段也是单个 string。 |
103
100
  | `device.id` | string | Device 插件开启 | SDK 生成的匿名设备关联 ID。默认仅在本次插件生命周期内稳定;`persistentId: true` 时写入 localStorage,从而跨页面和 Session 保持。 |
104
101
  | `browser.viewport.width` | number | 浏览器环境 | 当前 CSS viewport 宽度,单位 CSS px,来源 `window.innerWidth`;窗口 resize/屏幕旋转后更新到后续 Span。 |
105
102
  | `browser.viewport.height` | number | 浏览器环境 | 当前 CSS viewport 高度,单位 CSS px,来源 `window.innerHeight`。 |
@@ -115,11 +112,10 @@ Resource Attribute 描述产生 Span 的 SDK 实例和运行环境,同一实
115
112
 
116
113
  | 字段 | 类型 | 条件 | 来源与详细说明 |
117
114
  | ---------------- | ------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
118
- | `span_type` | string | 所有 SDK 原生 RUM Span | 稳定的 RUM 一级分类:`session`、`view`、`resource`、`error`、`vital`、`long_task`、`action`、`websocket` 或 `custom`。 |
119
- | `outcome.type` | string | 所有 SDK 原生 RUM Span | 归一结果:`success`、`warning`、`error`、`timeout` 或 `abort`。Fetch/XHR 主动取消使用 `abort`。 |
120
- | `outcome.reason` | string | 需要解释非正常结果时 | 当前内置值包括 `network`、`network_timeout`、`http_4xx`、`http_5xx`、`blank_screen` 和 `csp`。正常结果以及可由领域字段完整表达的结果不写该字段。 |
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`。 |
121
117
 
122
- `outcome.type` 是 RUM 查询维度,OTLP `status` 是 OpenTelemetry 状态,二者用途不同。例如 Web Vital 评级不佳时为 `outcome.type=warning`,但不会把 OTLP Status 设置为 `ERROR`。
118
+ `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`。
123
119
 
124
120
  ## Span 清单
125
121
 
@@ -133,7 +129,7 @@ Resource Attribute 描述产生 Span 的 SDK 实例和运行环境,同一实
133
129
  | `browser.resource_error` | INTERNAL | `error` | `error.source=resource` | 错误采集默认开启 | script、img、link、media 等元素资源加载失败。 |
134
130
  | `browser.web_vital` | INTERNAL | `vital` | `vital.metric` | 默认开启 | 单项用户体验指标及归因。 |
135
131
  | `action.click` | INTERNAL | `action` | `action.type=click` | 自动 Action 默认开启 | 自动点击 Action 及其页面活动、错误和挫败归因。 |
136
- | `action.custom` | INTERNAL | `action` | `action.type=custom` | `reportAction` | 主动上报的业务 Action。 |
132
+ | `action.<name>` | INTERNAL | `action` | `action.type=custom` | `reportAction({ name })` | 主动上报的业务 Action;Span 名是 `action.` 加上业务 name。 |
137
133
  | `browser.blank_screen` | INTERNAL | `error` | `blank_screen.reason` | 默认开启 | 视口九宫格连续检测确认的白屏。 |
138
134
  | `browser.long_task` | INTERNAL | `long_task` | `long_task.entry_type` | `tracking.longTask`,默认关闭 | Long Animation Frame,或不支持时回退的 Long Task。 |
139
135
  | `csp.violation` | INTERNAL | `error` | `error.source=csp` | `tracking.cspViolation`,默认关闭 | 浏览器 `securitypolicyviolation` 事件。 |
@@ -144,17 +140,14 @@ Resource Attribute 描述产生 Span 的 SDK 实例和运行环境,同一实
144
140
 
145
141
  适用于 `browser.session`。Session 默认在 15 分钟无活动后过期,并受 4 小时最大生命周期限制。
146
142
 
147
- | 字段 | 类型 | 条件/取值 | 来源与详细说明 |
148
- | -------------------------- | ------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
149
- | `session.phase` | string | `start`、`rotate`、`end` | `start` 表示没有可复用记录时创建;`rotate` 表示旧 Session 到期后创建新 Session;`end` 表示当前 Session 失效。 |
150
- | `session.id` | string | 所有阶段 | 当前生命周期事件所描述的 Session ID。`end` 事件写旧 ID,`rotate` 事件写新 ID。 |
151
- | `session.start_time` | number | 所有阶段,epoch ms | 该 Session 最初创建时间。`end` 时仍保留原始开始时间,不是结束时间。 |
152
- | `session.type` | string | 所有阶段,固定 `user` | 表示按真实用户浏览活动划分的 Session。 |
153
- | `session.has_replay` | boolean | 所有阶段,固定 `false` | 明确当前 SDK 没有为该 Session 关联回放数据。 |
154
- | `session.lifecycle.reason` | string | 所有阶段 | `init`:初始化时创建;`inactivity`:15 分钟无活动;`maxLifetime`:达到 4 小时上限;`external`:共享存储被删除、替换或记录无效,导致本 Tab 当前 Session 失效。 |
155
- | `session.previous_id` | string | `rotate` 且能识别旧 Session 时 | 新 Session 的前一个 ID,用于串联因 `inactivity` 或 `maxLifetime` 发生的轮换。首次 `start` 通常缺失。 |
143
+ | 字段 | 类型 | 条件/取值 | 来源与详细说明 |
144
+ | -------------------- | ------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------- |
145
+ | `session.phase` | string | `start`、`rotate`、`end` | `start` 表示没有可复用记录时创建;`rotate` 表示旧 Session 到期后创建新 Session;`end` 表示当前 Session 失效。 |
146
+ | `session.id` | string | 所有阶段 | 当前生命周期事件所描述的 Session ID。`end` 事件写旧 ID,`rotate` 事件写新 ID。 |
147
+ | `session.type` | string | 所有阶段,固定 `user` | 表示按真实用户浏览活动划分的 Session。 |
148
+ | `session.has_replay` | boolean | 所有阶段,固定 `false` | 明确当前 SDK 没有为该 Session 关联回放数据。 |
156
149
 
157
- Session Span 允许没有 `view.id`:SDK 先建立 Session,再创建初始 View;结束 Session 时也会先结束当前 View。
150
+ 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
151
 
159
152
  ## View 字段
160
153
 
@@ -168,13 +161,14 @@ Session Span 允许没有 `view.id`:SDK 先建立 Session,再创建初始 Vi
168
161
  | `view.started_at` | number | epoch ms | View 开始时间。初始 View 使用 `performance.timeOrigin`,路由/BFCache/续建 View 使用创建时刻。 |
169
162
  | `view.name` | string | 显式命名后 | 业务可读名称,仅 `startView({ name })` 或 `setViewName()` 后存在;未命名的 View 不带该字段。 |
170
163
  | `view.url` | string | 所有阶段 | 创建 View 时的 URL,经 `redactUrl` 脱敏;在该 View 生命周期内保持不变。 |
171
- | `view.url_template` | string | 所有阶段 | 低基数路由模板。数字 ID、UUID、长十六进制段默认折叠为 `:id`,用于稳定聚合动态路由。 |
164
+ | `view.url_template` | string | 所有阶段 | 当前 URL 的低基数路由模板。数字 ID、UUID、长十六进制段默认折叠为 `:id`,用于稳定聚合动态路由。 |
165
+ | `view.previous_url_template` | string | 所有阶段 | 前序 URL 的低基数路由模板;使用 `tracking.view.getUrlTemplate` 生成,初始 View 为空字符串。 |
172
166
  | `view.loading_type` | string | 所有阶段 | `initial_load`、`route_change`、`bf_cache` 或 `session_renewal`,含义见运行时公共属性。 |
173
167
  | `view.loading_time` | number | 计算完成后,ms | 从 `view.started_at` 到页面活动稳定的耗时。初始加载同时等待 load event 和页面活动,以较晚者为准;可由 `setViewLoadingTime()` 手动结束。 |
174
168
  | `view.loading_time_source` | string | 有 `view.loading_time` 时 | `auto` 表示 SDK 自动观察页面活动;`manual` 表示业务调用 `setViewLoadingTime()`。 |
175
169
  | `view.end_reason` | string | 仅 `end` | 结束原因:路由来源值、`manual`、`bfcache`、`pagehide`、`session_expired` 或 `shutdown`。它说明为何关闭旧 View,不是新 View 的加载类型。 |
176
- | `url.previous` | string | 所有阶段 | 创建 View 时记录的前序 URL,经 `redactUrl` 脱敏;初始 View 通常为空字符串。 |
177
- | `document.referrer` | string | 仅 `initial_load` | `document.referrer` 经 `redactUrl` 脱敏;没有来源页面时为空字符串。 |
170
+ | `view.previous` | string | 所有阶段 | 创建 View 时记录的前序 URL,经 `redactUrl` 脱敏;初始 View 为空字符串。 |
171
+ | `view.referrer` | string | 仅 `initial_load` 且值非空 | `document.referrer` 经 `redactUrl` 脱敏。 |
178
172
  | `view.first_byte` | number | 仅初始 View 且 Navigation Timing 有值,相对 timeOrigin ms | `PerformanceNavigationTiming.responseStart`,表示导航开始到收到响应首字节的时间。 |
179
173
  | `view.dom_interactive` | number | 同上 | `domInteractive`,表示 HTML 解析完成、文档进入 interactive 状态的时间点。 |
180
174
  | `view.dom_content_loaded` | number | 同上 | `domContentLoadedEventEnd`,表示 DOMContentLoaded 事件处理完成的时间点。 |
@@ -190,7 +184,7 @@ Session Span 允许没有 `view.id`:SDK 先建立 Session,再创建初始 Vi
190
184
  | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
191
185
  | --------------------------------- | ------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
192
186
  | `url.full` | string | 有有效请求/资源 URL | 绝对 URL,经 `redactUrl` 脱敏。用于定位请求目标;不要假设 query 中仍保留原始参数。 |
193
- | `url.template` | string | Fetch/XHR | 低基数路由模板,只含 path,例如 `/api/orders/:id`。默认把数字 ID、UUID、长十六进制段折叠为 `:id`,可由 `tracking.request.getUrlTemplate` 覆盖。按 API 路由聚合请求时用它,不要用 `url.full`。静态资源 Span 没有该字段。 |
187
+ | `url.template` | string | 有有效请求/资源 URL | 低基数 path。Fetch/XHR 和静态资源默认把数字 ID、UUID、长十六进制段折叠为 `:id`,例如 `/api/orders/:id`,可由 `tracking.request.getUrlTemplate` 覆盖。静态资源先通过 `redactUrl` 脱敏,再生成模板。按路径聚合时用它,不要用 `url.full`。 |
194
188
  | `server.address` | string | URL 可解析 | URL 的 `hostname`,不含端口。相对 URL 会基于当前页面地址解析。模板不含 host,跨域同路径会聚到一起,需要区分来源时配合该字段。 |
195
189
  | `server.port` | number | URL 显式包含端口 | URL 的显式端口号。使用协议默认端口且 URL 未写端口时缺失。 |
196
190
  | `resource.type` | string | 必有 | Fetch/XHR 为 `fetch`/`xhr`;静态资源使用 `PerformanceResourceTiming.initiatorType`,为空时为 `other`,常见还有 `script`、`link`、`img`、`css`。 |
@@ -238,11 +232,11 @@ Link 的 `trace_id` / `span_id` 优先取自解析结果;`sw8` 这类无法映
238
232
 
239
233
  如果公共时间点缺失、不是有限数或顺序异常,SDK 会放弃整组阶段字段,避免产生负耗时。Resource Timing 的跨域详细信息还受 `Timing-Allow-Origin` 响应头限制。
240
234
 
241
- 请求结果映射: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。
235
+ 请求结果映射(只写 `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。
242
236
 
243
237
  ## 错误字段
244
238
 
245
- 三类自动浏览器错误都设置 `outcome.type=error`、OTLP Status `ERROR`,并记录 `exception` Span Event。错误来源由 `error.source` 表达,不重复写入 `outcome.reason`。
239
+ 三类自动浏览器错误都设置 `outcome.type=error`、OTLP Status `ERROR`,并记录 `exception` Span Event。错误来源由 `error.source` 表达。
246
240
 
247
241
  | 字段 | 类型 | 适用范围 | 来源与详细说明 |
248
242
  | -------------------- | ------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -252,9 +246,11 @@ Link 的 `trace_id` / `span_id` 优先取自解析结果;`sw8` 这类无法映
252
246
  | `code.filepath` | string | `browser.error` | `ErrorEvent.filename`,即浏览器报告的脚本文件地址。浏览器未提供或跨域屏蔽时可能为空。 |
253
247
  | `code.lineno` | number | `browser.error` | `ErrorEvent.lineno`,错误在脚本中的 1-based 行号;浏览器无法定位时可能为 `0`。 |
254
248
  | `code.column` | number | `browser.error` | `ErrorEvent.colno`,错误列号;具体是否 0-based 由浏览器实现决定。 |
255
- | `error.cross_origin` | boolean | 跨域 `Script error.` | 仅当没有 Error 对象和 filename,且消息为 `Script error.` 时写 `true`,用于识别被同源策略屏蔽详情的脚本错误。 |
256
249
  | `url.full` | string | `browser.resource_error` | 加载失败元素的 `src`、`href` 或 `currentSrc`,经 `redactUrl` 脱敏。浏览器拿不到资源地址时可能为空字符串。 |
257
- | `html.tag` | string | `browser.resource_error` | 失败元素的 `tagName`,浏览器通常返回大写,例如 `SCRIPT`、`IMG`、`LINK`,可用于按资源载体分类。 |
250
+
251
+ 当前 **不上报** `error.cross_origin` 或 `html.tag`。跨域脚本错误只能通过 `error.message` 为 `Script error.`、且 `code.filepath` 为空来识别。资源加载失败的元素标签只出现在 `error.message` 里(格式 `Resource load failed: <tag> <原始 URL>`),需要按标签聚合时应在服务端解析该文本。
252
+
253
+ 注意 `browser.resource_error` 的 `error.message` 携带的是 **未脱敏** 的资源 URL(`url.full` 才是脱敏后的值)。有敏感 URL 风险时用 `redactAttributes` 重写 `error.message`。
258
254
 
259
255
  `context.attributes.error()` 返回的任意业务 Attribute 会合并到三类自动错误 Span,并统一经过 `redactAttributes`。字段命名和类型由接入方负责。
260
256
 
@@ -264,7 +260,7 @@ Link 的 `trace_id` / `span_id` 优先取自解析结果;`sw8` 这类无法映
264
260
 
265
261
  | Event 字段 | 类型 | 条件 | 来源与详细说明 |
266
262
  | ---------------------- | ------ | ----------------- | --------------------------------------------------------------------------------------------- |
267
- | `exception.type` | string | 能识别异常类型 | Error 的 `name`,或 SDK 为非 Error 值补充的类型,例如 `UnhandledRejection`、`ResourceError`。 |
263
+ | `exception.type` | string | 能识别异常类型 | Error 的 `name`;非 Error 值时由 SDK 补类型:Promise rejection 为 `UnhandledRejection`,资源错误为 `ResourceError`,`window.error` 抛非 Error 值时为 `window.error`。 |
268
264
  | `exception.message` | string | 能提取异常消息 | Error message 或归一后的异常文本,用于错误检索和展示。 |
269
265
  | `exception.stacktrace` | string | Error 带 stack 时 | 浏览器提供的调用栈。跨域、非 Error rejection 或浏览器安全策略可能导致缺失。 |
270
266
 
@@ -274,53 +270,50 @@ Link 的 `trace_id` / `span_id` 优先取自解析结果;`sw8` 这类无法映
274
270
 
275
271
  `browser.web_vital` 上报 CLS、FCP、INP、LCP 和 TTFB。FCP/LCP/TTFB 由 `web-vitals/attribution` 采集导航级指标;CLS/INP 按 SDK View 边界汇总,View 结束时上报。
276
272
 
277
- | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
278
- | -------------- | ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
279
- | `vital.metric` | string | 必有 | 指标名的小写值:`cls`、`fcp`、`inp`、`lcp`、`ttfb`。用于同一 Span 名下区分指标。 |
280
- | `vital.value` | number | 必有 | 指标值。CLS 是无量纲分数;FCP、INP、LCP、TTFB 单位均为 ms。非有限值不会上报。 |
281
- | `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`。 |
282
- | `vital.id` | string | 必有 | 单条 Vital 的唯一 ID。FCP/LCP/TTFB 沿用 `web-vitals` ID;按 View 汇总的 CLS/INP 由 SDK 生成。 |
273
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
274
+ | -------------- | ------ | --------- | ------------------------------------------------------------------------------------------------------- |
275
+ | `vital.metric` | string | 必有 | 指标名的小写值:`cls`、`fcp`、`inp`、`lcp`、`ttfb`。用于同一 Span 名下区分指标。 |
276
+ | `vital.value` | number | 必有 | 指标值。CLS 是无量纲分数;FCP、INP、LCP、TTFB 单位均为 ms。非有限值不会上报。 |
277
+ | `vital.id` | string | 必有 | 单条 Vital 的唯一 ID。FCP/LCP/TTFB 沿用 `web-vitals` ID;按 View 汇总的 CLS/INP 由 SDK 生成。 |
283
278
 
284
- `vital.rating=good` 映射为 `outcome.type=success`;其他评级映射为 `outcome.type=warning`。具体体验评级由 `vital.rating` 表达,不重复写入 `outcome.reason`。
279
+ `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`。
285
280
 
286
281
  ### LCP Attribution
287
282
 
283
+ `onLCP` 回调会抽取以下字段;缺失表示浏览器或 `web-vitals` 未提供,不代表 LCP 无效。
284
+
288
285
  | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
289
286
  | ---------------------------------- | ------ | ----------------------- | ---------------------------------------------------------------------------------- |
290
287
  | `vital.lcp.url` | string | LCP 是图片等 URL 资源时 | LCP 资源 URL,经 `redactUrl` 脱敏。文本 LCP 没有资源 URL,因此缺失。 |
291
288
  | `vital.lcp.target` | string | 能定位 LCP 元素时 | `web-vitals` 生成的目标元素选择器/描述,用于定位拖慢最大内容绘制的 DOM 元素。 |
292
- | `vital.lcp.element_render_delay` | number | ms | LCP 资源加载完成到元素最终绘制之间的耗时;无独立资源时表示等待元素绘制的主要时间。 |
293
- | `vital.lcp.resource_load_duration` | number | ms | LCP 资源自身从请求开始到响应结束的下载耗时;文本 LCP 或无独立资源时通常为 `0`。 |
294
- | `vital.lcp.time_to_first_byte` | number | ms | 从导航开始到主文档响应首字节的时间,是 LCP 总耗时的服务端/网络前置部分。 |
289
+ | `vital.lcp.element_render_delay` | number | ms | LCP 资源加载完成到元素最终绘制之间的耗时。 |
290
+ | `vital.lcp.resource_load_duration` | number | ms | LCP 资源自身从请求开始到响应结束的下载耗时。 |
291
+
292
+ 当前 **不上报** `vital.lcp.time_to_first_byte`。
295
293
 
296
294
  ### CLS Attribution
297
295
 
298
- | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
299
- | -------------------------------- | ------ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
300
- | `vital.cls.largest_shift_target` | string | 能定位元素时 | 对 CLS 贡献最大的单次布局偏移中的首个目标元素描述。按 SDK View 汇总时取最大 Session Window 内最大的单次偏移目标。 |
301
- | `vital.cls.largest_shift_value` | number | 无量纲 | 上述单次布局偏移的分数,不是整个 `vital.value`;可用于判断 CLS 是否由一次大跳动还是多次小跳动组成。 |
302
- | `vital.cls.load_state` | string | 当前不产生 | 字段提取逻辑已预留,用于表达最大偏移发生时的文档加载阶段;当前 CLS 由 SDK 按 View 自行汇总,未向归因对象写入 load state,因此 Collector 数据中不会出现。 |
296
+ CLS 由 SDK 按 View 自行汇总,上报时 `attribution` 为空对象。因此 `vital.cls.load_state`、`vital.cls.largest_shift_target`、`vital.cls.largest_shift_value` **当前均不产生**。
303
297
 
304
298
  CLS 忽略 `hadRecentInput=true` 的偏移,并按“相邻偏移间隔小于 1 秒、窗口最长 5 秒”的 Session Window 规则取最大窗口累计值。View 结束时即使没有布局偏移也会上报 `vital.value=0`。
305
299
 
306
300
  ### INP Attribution
307
301
 
302
+ View 结束时,SDK 把选中的 p98 候选写入以下字段:
303
+
308
304
  | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
309
305
  | ------------------------------- | ------ | ---------------- | -------------------------------------------------------------------------------------------------------- |
310
306
  | `vital.inp.interaction_target` | string | 能定位交互元素时 | 触发 INP 候选交互的元素描述。SDK 优先 `data-bk-action-name`、`aria-label`、`name`,否则使用小写 tag 名。 |
311
- | `vital.inp.interaction_type` | string | 必有 | SDK 按 View 汇总时为 Performance Event 名,例如 `click`、`keydown`;用于识别哪类输入产生延迟。 |
312
- | `vital.inp.input_delay` | number | ms | 从用户输入发生到浏览器开始执行事件处理器的延迟,主要反映主线程此前被其他任务占用。 |
313
- | `vital.inp.processing_duration` | number | ms | 从事件处理开始到处理结束的耗时,主要反映业务事件处理器本身及同步工作。 |
314
- | `vital.inp.presentation_delay` | number | ms | 事件处理完成到下一帧呈现的耗时,包含样式、布局、绘制、合成等后续工作。三段之和应近似 `vital.value`。 |
307
+ | `vital.inp.interaction_type` | string | 必有 | Performance Event 名,例如 `click`、`keydown`。 |
308
+ | `vital.inp.input_delay` | number | ms | 从用户输入发生到浏览器开始执行事件处理器的延迟。 |
309
+ | `vital.inp.processing_duration` | number | ms | 从事件处理开始到处理结束的耗时。 |
310
+ | `vital.inp.presentation_delay` | number | ms | 事件处理完成到下一帧呈现的耗时。三段之和应近似 `vital.value`。 |
315
311
 
316
312
  INP 只在 View 内至少观察到一次带 `interactionId` 的 Event Timing 时上报;Performance Observer 的 `durationThreshold` 为 40ms,值最大限制为 60,000ms。SDK 保留最慢的 10 个交互候选,并按交互数量选择近似 p98 候选。
317
313
 
318
314
  ### FCP Attribution
319
315
 
320
- | 字段 | 类型 | 单位/条件 | 来源与详细说明 |
321
- | ------------------------------ | ------ | --------- | --------------------------------------------------------------------------------------------------------------------- |
322
- | `vital.fcp.time_to_first_byte` | number | ms | 导航开始到主文档响应首字节的时间。`FCP - TTFB` 可近似观察首字节后到首次内容绘制的前端阶段。 |
323
- | `vital.fcp.load_state` | string | 必有 | FCP 发生时的文档加载阶段,例如 `loading`、`dom-interactive`、`dom-content-loaded`、`complete`;越早绘制通常体验越好。 |
316
+ `onFCP` 只上报公共 `vital.*` 字段。`pickAttribution()` 对 `FCP` 没有抽取分支,因此 **不上报** `vital.fcp.time_to_first_byte` 或 `vital.fcp.load_state`。
324
317
 
325
318
  ### TTFB Attribution
326
319
 
@@ -337,35 +330,31 @@ Attribution 字段受浏览器能力和指标实现影响,缺失不代表指
337
330
 
338
331
  | 字段 | 类型 | 自动 Click | 手动 Action | 来源与详细说明 |
339
332
  | ------------------------- | -------- | ------------------------ | -------------- | --------------------------------------------------------------------------------------------------------- |
340
- | `action.id` | string | 必有 | 必有 | 当前 Action 的唯一 ID。自动 Action 活动期间,其他 Span 上的同名运行时字段会是 `string[]`。 |
333
+ | `action.id` | string | 必有 | 必有 | 当前 Action 的唯一 ID。自动 Action 活动期间,其他 Span 上的同名运行时字段也是单个 string。 |
341
334
  | `action.type` | string | 固定 `click` | 固定 `custom` | 区分自动点击和 `reportAction` 主动上报。 |
342
- | `action.name` | string | `Click on <target>` | payload `name` | 可读名称。自动点击目标名默认来自显式 `data-bk-action-name`,启用文本采集后才会回退到可访问名称/DOM 文本。 |
343
335
  | `action.target.name` | string | 必有 | 不写 | 自动点击提取的目标名称,最多 100 字符;默认隐私模式下未显式命名时通常为小写 tag 名。 |
344
- | `action.target.tag` | string | 必有 | 不写 | 实际点击目标的原始 `tagName`,SDK 转为小写,用于按按钮、链接等元素类型聚合。 |
345
- | `action.loading_time` | number | 点击后有可观察页面活动时 | 不写 | 单位 ms,从点击发生到相关请求、资源、Long Task、DOM 活动安静的耗时;无页面副作用时不写,而不是 `0`。 |
336
+ | `action.target.tag` | string | 必有 | 不写 | 实际点击目标的原始 `tagName`,SDK 转为小写。 |
346
337
  | `action.frustration.type` | string[] | 检出挫败信号时 | 不写 | 可包含 `rage_click`、`dead_click`、`error_click`;一次 Action 可同时命中多个值。 |
347
338
 
339
+ 自动 Action 的可读名称不单独写成 `action.name` Attribute,而是体现在目标字段和 Span 名 `action.click` 上。手动 Action 的 Span 名为 `action.<payload.name>`,`action.type=custom`。点击后若有可观察页面活动,SDK 用 Span 的 `startTimeUnixNano`/`endTimeUnixNano` 表达持续时间,**不上报** `action.loading_time` 属性。无页面副作用时 Span 起止时间相同。
340
+
348
341
  `rage_click` 表示 1 秒内、100px 范围内连续至少三次点击;`dead_click` 表示点击后没有页面活动、输入、滚动或选择等反馈(链接、表单输入等会排除);`error_click` 表示 Action 生命周期内出现错误。有错误或任一挫败信号时为 `outcome.type=warning`,具体类型只由 `action.frustration.type` 表达。
349
342
 
350
- `reportAction({ attributes })` 的业务 Attribute 会合并到 `action.custom`,但固定分类和事件字段由 SDK 写入。业务应避免复用本页保留字段名。
343
+ `reportAction({ attributes })` 的业务 Attribute 会合并到该 Span,但固定分类和事件字段由 SDK 写入。业务应避免复用本页保留字段名。
351
344
 
352
345
  ## 白屏字段
353
346
 
354
347
  白屏插件在页面活动稳定后对视口九宫格采样,并在默认 200ms 间隔后再次确认;每个 View 最多上报一次。
355
348
 
356
- | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
357
- | ----------------------------------- | ------- | ------------------ | -------------------------------------------------------------------------------------------------- |
358
- | `blank_screen.reason` | string | 必有 | `missing_root`:配置的根节点不存在;`empty_viewport`:根节点存在,但有效采样点的空白比例达到阈值。 |
359
- | `blank_screen.empty_ratio` | number | `0..1` | `empty_sample_count / valid_sample_count`。默认阈值为 `0.8`;根节点缺失时固定为 `1`。 |
360
- | `blank_screen.sample_count` | number | 必有,当前固定 `9` | 视口 20%、50%、80% 横纵坐标组合形成的九宫格总采样点数。 |
361
- | `blank_screen.valid_sample_count` | number | 必有 | 参与空白比例计算的点数,等于总采样点减去 ignored 点。为 `0` 时不报告白屏。 |
362
- | `blank_screen.empty_sample_count` | number | 必有 | 有效采样点中,没有发现根节点内可见内容元素的点数。 |
363
- | `blank_screen.ignored_sample_count` | number | 必有 | 命中 loading、Skeleton 或业务 `ignoreSelectors` 的点数;这些点从比例分母中排除。 |
364
- | `blank_screen.root_selector` | string | 必有 | 实际检测使用的根节点 CSS selector,默认 `body`。用于判断是否因挂载点配置错误产生 `missing_root`。 |
365
- | `blank_screen.root_found` | boolean | 必有 | 是否找到根节点。`false` 与 `reason=missing_root` 对应。 |
366
- | `blank_screen.center_element` | string | 必有,可能为空 | 视口中心最上层元素的小写 tag,存在 ID 时为 `tag#id`;用于快速判断遮罩、容器或空 body。 |
349
+ | 字段 | 类型 | 条件/单位 | 来源与详细说明 |
350
+ | ----------------------------- | ------ | ------------------ | -------------------------------------------------------------------------------------------------- |
351
+ | `blank_screen.reason` | string | 必有 | `missing_root`:配置的根节点不存在,检测回退到 `body`/`documentElement`;`empty_viewport`:配置根节点存在。 |
352
+ | `blank_screen.empty_ratio` | number | `0..1` | `emptyCount / validCount`。默认阈值为 `0.8`。根节点缺失时仍是回退后的实际比例,不是固定 `1`。 |
353
+ | `blank_screen.empty_sample_count` | number | 必有 | 有效采样点中,没有发现根节点内可见内容元素的点数。 |
367
354
 
368
- 该 Span 固定为 `outcome.type=error,outcome.reason=blank_screen`,但检测是基于采样点的启发式判断,应结合截图、错误和 View 数据进一步确认。
355
+ 当前 **不上报** `blank_screen.sample_count`、`valid_sample_count`、`ignored_sample_count`、`root_selector`、`root_found`、`center_element`。分母为 0 时不报告白屏。
356
+
357
+ 该 Span 固定为 `span_type=error`、`outcome.type=error`,不写 `outcome.reason`,也不设置 OTLP Status ERROR,不记录 exception Event。检测是基于采样点的启发式判断,应结合错误和 View 数据进一步确认。
369
358
 
370
359
  ## Long Task 字段
371
360
 
@@ -377,14 +366,14 @@ Attribution 字段受浏览器能力和指标实现影响,缺失不代表指
377
366
  | ------------------------------------ | ------ | ------------------------------- | -------------------------------------------------------------------------------------------------- |
378
367
  | `long_task.id` | string | 必有 | 当前 Long Task/LoAF 事件的随机唯一 ID,用于关联其 Span Event。 |
379
368
  | `long_task.entry_type` | string | 必有 | `long-animation-frame` 或 `long-task`,表示使用的浏览器 Performance Entry 类型。 |
380
- | `long_task.duration` | number | 必有,ms | 整个 LoAF/Long Task 持续时间,来源 `PerformanceEntry.duration`。 |
381
369
  | `long_task.name` | string | 必有 | 浏览器 Performance Entry 的 `name`;Legacy Long Task 常见为 `self` 或跨上下文归因名称。 |
382
- | `long_task.start_time` | number | 仅 LoAF,相对 timeOrigin ms | LoAF 的 `startTime`。Span 自身开始时间已转换为 epoch,这个字段保留原始 Performance Timeline 坐标。 |
383
- | `long_task.blocking_duration` | number | 仅 LoAF,ms | 浏览器计算的阻塞时间,表示超出可接受帧预算、真正阻塞交互响应的部分,不等于完整 `duration`。 |
370
+ | `long_task.blocking_duration` | number | 仅 LoAF,ms | 浏览器计算的阻塞时间,表示超出可接受帧预算、真正阻塞交互响应的部分,不等于完整持续时间。 |
384
371
  | `long_task.first_ui_event_timestamp` | number | LoAF 提供时,相对 timeOrigin ms | 该帧内首个 UI Event 的时间点;可判断长帧是否直接阻塞用户输入。 |
385
372
  | `long_task.render_start` | number | LoAF 提供时,相对 timeOrigin ms | 浏览器开始本帧渲染阶段的时间点。 |
386
373
  | `long_task.style_and_layout_start` | number | LoAF 提供时,相对 timeOrigin ms | 本帧开始样式计算和布局的时间点,可与 `render_start` 分析渲染阶段开销。 |
387
374
 
375
+ Span 持续时间就是 `PerformanceEntry.duration`(起止时间已转换为 epoch)。当前 **不上报** `long_task.duration` 或 `long_task.start_time` Attribute;需要原始 Performance Timeline 坐标时,用 `long_task.render_start` 等 LoAF 字段,或从 Span 起始时间减去 Resource 上的 SDK 时间基准。
376
+
388
377
  ### `long_task.script` Span Event
389
378
 
390
379
  每个 LoAF `scripts` 条目生成一个同名 Event;Event 自身时间戳为 `performance.timeOrigin + script.startTime`。
@@ -418,7 +407,7 @@ Legacy Long Task 的每个 attribution 条目生成一个 Event,Event 时间
418
407
 
419
408
  ## CSP 字段
420
409
 
421
- 适用于 `csp.violation`,来自浏览器 `SecurityPolicyViolationEvent`。该 Span 固定为 `outcome.type=error,outcome.reason=csp,error.source=csp`。
410
+ 适用于 `csp.violation`,来自浏览器 `SecurityPolicyViolationEvent`。该 Span 固定为 `span_type=error`、`outcome.type=error`、`error.source=csp`,不写 `outcome.reason`,也不设置 OTLP Status ERROR。
422
411
 
423
412
  | 字段 | 类型 | 条件 | 来源与详细说明 |
424
413
  | ------------------------- | ------ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
@@ -451,7 +440,7 @@ Legacy Long Task 的每个 attribution 条目生成一个 Event,Event 时间
451
440
  | `websocket.close.reason` | string | 仅 `close` | 对端/调用方提供的关闭原因文本,可能为空。该值不是 URL,不经过 `redactUrl`,敏感内容应由 `redactAttributes` 清理。 |
452
441
  | `websocket.close.was_clean` | boolean | 仅 `close` | 浏览器判断连接是否完成干净关闭握手;`false` 常见于网络中断或异常终止。 |
453
442
 
454
- `error` 阶段设置 `outcome.type=error,outcome.reason=network`;其他阶段为 `outcome.type=success` 且不写 reason。SDK 当前不采集 WebSocket 消息内容、数量或字节数。
443
+ `error` 阶段设置 `outcome.type=error`;其他阶段为 `outcome.type=success`。当前不写 `outcome.reason`。SDK 不采集 WebSocket 消息内容、数量或字节数。
455
444
 
456
445
  ## Custom Event 字段
457
446
 
@@ -484,8 +473,15 @@ Legacy Long Task 的每个 attribution 条目生成一个 Event,Event 时间
484
473
  当前源码不会产生:
485
474
 
486
475
  - `/v1/metrics`、`/v1/logs` 请求,以及 Counter、Histogram、Gauge、LogRecord。
487
- - `session.duration`、`view.duration`;持续时间应由服务端根据生命周期事件派生。
488
- - `vital.cls.load_state`;字段提取代码已预留,但当前按 View 汇总的 CLS 不提供该归因值。
476
+ - `session.duration`、`view.duration`、`session.start_time`、`session.lifecycle.reason`、`session.previous_id`。
477
+ - `outcome.reason`;失败细分由领域字段表达。
478
+ - `vital.rating`、`vital.cls.*` 归因、`vital.fcp.*` 归因、`vital.lcp.time_to_first_byte`。
479
+ - `action.name`、`action.loading_time`;手动 Action 的 name 只进入 Span 名 `action.<name>`。
480
+ - `blank_screen.sample_count`、`valid_sample_count`、`ignored_sample_count`、`root_selector`、`root_found`、`center_element`。
481
+ - `long_task.duration`、`long_task.start_time`。
482
+ - `error.cross_origin`、`html.tag`。
483
+ - `device.memory_gib` 及逻辑处理器数字段;Device Resource 只读 UA/UA-CH,不读 `navigator.deviceMemory` 或 `hardwareConcurrency`。
484
+ - `tracestate`;SDK 既不注入也不记录。
489
485
  - Action、Resource、Error、Long Task count;计数和分布应从原始 Span 聚合。
490
486
  - 错误 fingerprint/group;错误分组由服务端根据 exception、message、stack 等字段计算。
491
487
  - HTTP request/response Body、Header;Trace Context 注入不代表采集请求内容。
@@ -38,8 +38,8 @@ https://rum.example.com/collector/v1/rum
38
38
  { "key": "service.name", "value": { "stringValue": "order-center" } },
39
39
  { "key": "session.sample_rate", "value": { "intValue": 1 } },
40
40
  { "key": "telemetry.sdk.language", "value": { "stringValue": "webjs" } },
41
- { "key": "telemetry.sdk.name", "value": { "stringValue": "@blueking/open-telemetry" } },
42
- { "key": "telemetry.sdk.version", "value": { "stringValue": "0.0.22" } }
41
+ { "key": "telemetry.sdk.name", "value": { "stringValue": "blueking" } },
42
+ { "key": "telemetry.sdk.version", "value": { "stringValue": "0.0.29" } }
43
43
  ],
44
44
  "droppedAttributesCount": 0
45
45
  },
@@ -56,7 +56,6 @@ https://rum.example.com/collector/v1/rum
56
56
  "endTimeUnixNano": "1784592000248000000",
57
57
  "attributes": [
58
58
  { "key": "session.id", "value": { "stringValue": "session-01" } },
59
- { "key": "session.start_time", "value": { "intValue": 1784592000000 } },
60
59
  { "key": "session.type", "value": { "stringValue": "user" } },
61
60
  { "key": "session.has_replay", "value": { "boolValue": false } },
62
61
  { "key": "view.id", "value": { "stringValue": "view-01" } },
@@ -94,6 +93,7 @@ Wire 编码注意点:
94
93
  - Status `code=0` 是 UNSET,ERROR 为 `2`;
95
94
  - `startTimeUnixNano`、`endTimeUnixNano` 和 Event `timeUnixNano` 编码为十进制字符串;
96
95
  - Attribute 不是普通扁平对象,而是 `{ key, value }` 数组;value 使用 `stringValue`、`intValue`、`doubleValue`、`boolValue` 或 `arrayValue`;
96
+ - `session.sample_rate` 在值为整数 `1`/`0` 时常见为 `intValue`,小数采样率(如 `0.2`)为 `doubleValue`;按 number 读取即可;
97
97
  - `traceId` 是 32 位十六进制字符串,`spanId` / `parentSpanId` 是 16 位;没有父 Span 时省略 `parentSpanId`;
98
98
  - `events` 中的 exception/Long Task Event 也使用同样的 Attribute Value 包装;
99
99
  - `flags=257` 是当前 transformer 写出的“本地 sampled Span 且携带 isRemote 有效位”组合值,不要把它当作业务字段;
@@ -239,8 +239,8 @@ transport: {
239
239
 
240
240
  | 项目 | 当前行为 |
241
241
  | --- | --- |
242
- | `timeoutMillis` | 默认 `10000ms`,且必须是大于 0 的有限数值 |
243
- | `concurrencyLimit` | 默认 `30` 个待处理 export Promise |
242
+ | `timeoutMillis` | 不配置时为 `10000ms`,且必须是大于 0 的有限数值 |
243
+ | `concurrencyLimit` | 不配置时为 `30` 个待处理 export Promise |
244
244
  | 可重试 HTTP 状态 | `429`、`502`、`503`、`504` |
245
245
  | 可重试网络错误 | 浏览器 Fetch 的部分 `TypeError` 网络错误 |
246
246
  | 最大重试次数 | 初次请求后最多再尝试 5 次,但不能超过总体超时期限 |
@@ -291,18 +291,23 @@ session: {
291
291
 
292
292
  排查“手动事件没有上报”时,先暂时设置 `sampleRate: 1`。
293
293
 
294
- ## 导出前过滤
294
+ ## 两层拦截:Sampler 与 Filtering Processor
295
295
 
296
- 一个已结束 Span 还需要通过 `FilteringSpanProcessor` 才会进入 simple/batch processor。以下数据会被丢弃:
296
+ 采样和过滤发生在两个不同阶段,排查时要分清:
297
297
 
298
- - 没有命中当前 Session 采样;
299
- - 没有关联有效 Session;
300
- - 除 `browser.session` 外,没有关联有效 View;
301
- - 命中 SDK 自身的 `/v1/rum` 上报地址;
302
- - 被内部插件标记为丢弃;
298
+ **第一层 · Provider Sampler(Span 创建时)。** `WebTracerProvider` 使用 `RumSessionSampler`:Session 未命中采样时返回 `NOT_RECORD`,Span 直接是 non-recording 的,不记录属性也不会触发 `onEnd`。这一层对**所有** Span 生效,包括通过 `useInstrumentation()` 注册的第三方 OpenTelemetry Instrumentation——它们不需要自己判断采样。
299
+
300
+ **第二层 · `FilteringSpanProcessor`(Span 结束时)。** 已结束的 recording Span 还要通过它才进入 simple/batch processor。以下会被丢弃:
301
+
302
+ - 没有关联有效 `session.id`;
303
+ - 除 `browser.session` 外,没有关联有效 `view.id`;
304
+ - 属性里的 `url.full` 或 `http.url` 命中 SDK 自身的 `/v1/rum` 上报地址(后者用于识别第三方 HTTP Instrumentation 产生的自上报请求);
305
+ - 被请求插件的 `request.beforeSend` 标记为丢弃;
303
306
  - 被全局 `tracking.beforeSend` 返回 `false` 拒绝。
304
307
 
305
- 过滤层会在 Span 创建时补齐缺失的运行时和页面属性;Span 结束时执行上述过滤,并在交给 exporter 前移除仅供内部使用的采样标记。详细顺序见[架构与数据流](./architecture.md)。
308
+ 同一个 Processor 还负责在 `onStart` 阶段补齐 Span 尚未显式写入的运行时属性和 `context.attributes.page()`;已有同名属性不会被覆盖。
309
+
310
+ 因此“未采样”和“被过滤”的现象不同:未采样时浏览器里根本没有成形的 Span;被过滤时 Span 已创建但没有进入导出队列,`debug: true` 也不会打印它。详细顺序见[架构与数据流](./architecture.md)。
306
311
 
307
312
  ## CORS 基线
308
313
 
@@ -228,7 +228,7 @@ console.log({
228
228
  ### 3. Payload 和 Hook
229
229
 
230
230
  - `name` 类型必须是 string,并建议使用非空、低基数枚举;
231
- - 当前运行时不拒绝空字符串:`reportCustomEvent({ name: '' })` 会尝试生成名为 `custom.` 的 Span,`reportAction({ name: '' })` 会生成空的 `action.name`,都不会仅因空 name 抛错或丢弃,但数据不可用,不应依赖该行为;
231
+ - 当前运行时不拒绝空字符串:`reportCustomEvent({ name: '' })` 会尝试生成名为 `custom.` 的 Span,`reportAction({ name: '' })` 会生成名为 `action.` 的 Span,都不会仅因空 name 抛错或丢弃,但数据不可用,不应依赖该行为;
232
232
  - attributes 只能使用合法 OTel Attribute 类型;
233
233
  - `context.attributes.page/custom` 与 `privacy.redactAttributes` 不应抛错;
234
234
  - `tracking.beforeSend` 不能按 name 返回 false;Custom Event 不经过请求级 `request.beforeSend`。
@@ -54,7 +54,7 @@ bkOT.startView({
54
54
 
55
55
  ## View 名称和路由模板
56
56
 
57
- 默认 `view.url_template` 取 URL pathname 并把数字 ID、UUID、长十六进制段折叠为 `:id`。请求 Span 的 `url.template` 复用同一套折叠规则,但走独立的 `tracking.request.getUrlTemplate`。
57
+ 默认 `view.url_template` 取 URL pathname 并把数字 ID、UUID、长十六进制段折叠为 `:id`。请求和静态资源 Span 的 `url.template` 复用同一套折叠规则,但走独立的 `tracking.request.getUrlTemplate`。静态资源先通过 `redactUrl` 脱敏,再生成模板。
58
58
 
59
59
  `view.name` 与 `view.url_template` 是两个不同维度:前者是业务给出的可读标签(「订单详情」),后者是路由模板(`/orders/:id`)。**只有显式调用 `startView({ name })` 或 `setViewName()` 时才会上报 `view.name`**,未命名的 View 不带该字段,后端展示时用 `view.name ?? view.url_template` 兜底即可。这样 `view.name` 的存在本身就表示"业务命名过",也不会在每条 Span 上重复一份模板字符串。
60
60
 
@@ -84,8 +84,9 @@ bkOT.setViewName('订单详情-只读');
84
84
 
85
85
  - `view.url`:当前 URL,经 `privacy.redactUrl`。
86
86
  - `view.url_template`:聚合路由模板。
87
- - `url.previous`:前一个原始 URL 经脱敏;初始加载为空字符串。
88
- - `document.referrer`:仅初始自动加载写入并脱敏。
87
+ - `view.previous`:前一个原始 URL 经脱敏;初始加载为空字符串。
88
+ - `view.previous_url_template`:前一个 URL 的聚合路由模板;初始加载为空字符串。
89
+ - `view.referrer`:仅初始自动加载写入并脱敏。
89
90
 
90
91
  用于路由判断的是原始 URL,写入遥测的是脱敏 URL。自定义 `redactUrl` 不会影响是否切换 View。
91
92
 
@@ -143,6 +144,7 @@ Span 名固定为 `browser.view`:
143
144
  - 初始加载:只要能取得 `loadEventEnd`,即使前 100ms 没有其他活动,也可生成 Loading Time;最终取 `loadEventEnd` 与页面活动结束耗时的较大值。
144
145
  - SPA/BFCache/Session Renewal:只有观察到页面活动时才生成自动 Loading Time,取 View 开始到页面活动结束的耗时。
145
146
  - 页面在计算期间变为 hidden:取消自动计算,不上报不可靠结果。
147
+ - **创建 View 时页面已经是 hidden:完全不启动自动计算**,之后回到前台也不会补算。后台标签页预加载、`target=_blank` 打开的页面因此常常没有 `view.loading_time`;这类场景需要 `setViewLoadingTime()` 手动确认。
146
148
 
147
149
  `view.loading_time_source=auto` 表示自动计算。
148
150