@blueking/open-telemetry 0.0.30 → 0.0.31
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.
- package/dist/bk-rum.global.js +1 -1
- package/dist/bk-rum.global.js.map +1 -1
- package/dist/index.js +368 -357
- package/dist/index.js.map +1 -1
- package/dist/schema/attributes.d.ts +1 -0
- package/package.json +1 -1
- package/skills/bk-rum-otele/references/actions.md +1 -1
- package/skills/bk-rum-otele/references/data-model.md +3 -1
- package/skills/bk-rum-otele/references/network.md +6 -2
- package/skills/bk-rum-otele/references/privacy.md +1 -1
- package/skills/bk-rum-otele/references/span-protocol.md +247 -83
- package/skills/bk-rum-otele/references/telemetry-reference.md +7 -6
- package/skills/bk-rum-otele/references/views-routing.md +4 -3
|
@@ -45,6 +45,7 @@ export declare const RUM_ATTRIBUTES: {
|
|
|
45
45
|
readonly viewName: "view.name";
|
|
46
46
|
readonly viewPhase: "view.phase";
|
|
47
47
|
readonly viewPrevious: "view.previous";
|
|
48
|
+
readonly viewPreviousUrlTemplate: "view.previous_url_template";
|
|
48
49
|
readonly viewReferrer: "view.referrer";
|
|
49
50
|
readonly viewStartedAt: "view.started_at";
|
|
50
51
|
readonly viewUrl: "view.url";
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@ Action 表示一次用户操作以及操作后引发的页面活动。SDK 默认
|
|
|
10
10
|
|
|
11
11
|
1. 从 Event 取得真实发生时间和 composed target。
|
|
12
12
|
2. 生成 `action.id`,保存当时的 Session/View 上下文。
|
|
13
|
-
3.
|
|
13
|
+
3. 把当前活动的 `action.id` 字符串写入运行时上下文,后续请求、资源、错误和 Long Task 自动关联。多个点击窗口重叠时取最近一次。
|
|
14
14
|
4. 观察请求、DOM Mutation、Resource、Long Task、Error 和部分用户行为。
|
|
15
15
|
5. 发生过页面活动后,等待所有请求完成并连续 100ms 无活动。
|
|
16
16
|
6. 最长等待 `maxDuration`,默认 10 秒。
|
|
@@ -69,7 +69,9 @@ User(业务提供,可变)
|
|
|
69
69
|
- `user.id`:业务方传入,可在 Session 内变化。
|
|
70
70
|
- `session.id`:Session 插件生成,是采样和访问会话边界。
|
|
71
71
|
- `view.id`:每个 View 新生成,是普通 RUM Span 的必要关联字段。
|
|
72
|
-
- `action.id
|
|
72
|
+
- `action.id`:始终是字符串。
|
|
73
|
+
自动 Action 活动窗口内写入当前活动 Action ID,多个点击窗口重叠时取最近一次。
|
|
74
|
+
Action 自身 Span 和手动 Action 各自写入当前 Action ID。
|
|
73
75
|
|
|
74
76
|
普通 Span 没有有效 Session 和 View 时不会导出。Session 生命周期 Span允许没有 View。
|
|
75
77
|
|
|
@@ -43,7 +43,9 @@ Fetch 和 XHR 都生成 `browser.resource`:
|
|
|
43
43
|
| `http.response.status_code` | 获得真实 Response status 时 | `load` 且 `xhr.status>0` 时 |
|
|
44
44
|
| Span Kind | CLIENT | CLIENT |
|
|
45
45
|
|
|
46
|
-
`url.template`
|
|
46
|
+
`url.template` 是给后端按路径聚合用的低基数维度(semconv `url.template`,当前仍是 Development 阶段)。Fetch/XHR 和静态资源 Span 都取 pathname,并把数字 ID、UUID、长十六进制段折叠为 `:id`。例如,`/api/orders/1001` 与 `/api/orders/1002` 都归到 `/api/orders/:id`。
|
|
47
|
+
|
|
48
|
+
需要精确模板时用 `tracking.request.getUrlTemplate` 覆盖。Fetch/XHR 会传入未脱敏 URL,便于按 query 判断路由;静态资源先通过 `redactUrl` 脱敏,再把结果传给该 Hook。返回空值或抛错都回退到默认规则。两点已知代价:纯数字段无法与语义段区分,`/reports/2024/summary` 会变成 `/reports/:id/summary`;模板按 semconv 定义不含 host,跨域同路径会聚到一起,需要区分来源时配合 `server.address`。
|
|
47
49
|
|
|
48
50
|
这套折叠规则与 View 的 `view.url_template` 共用,但入口独立:页面路由和 API 路径的模板规则通常不同,所以 `tracking.view.getUrlTemplate` 与 `tracking.request.getUrlTemplate` 互不影响。
|
|
49
51
|
|
|
@@ -226,6 +228,8 @@ Fetch resolve/reject 和 XHR 终止事件往往早于 Resource Timing Observer
|
|
|
226
228
|
|
|
227
229
|
| 字段 | 说明 |
|
|
228
230
|
| --------------------------------- | ---------------------------------------------------------- |
|
|
231
|
+
| `url.full` | 绝对 URL,经 `redactUrl` 脱敏 |
|
|
232
|
+
| `url.template` | 脱敏后的低基数 pathname;默认折叠数字 ID、UUID 和长十六进制段 |
|
|
229
233
|
| `resource.type` | initiator type |
|
|
230
234
|
| `resource.size` | `decodedBodySize`(解压后 Body Size) |
|
|
231
235
|
| `resource.encoded_body_size` | 编码后 Body Size |
|
|
@@ -306,4 +310,4 @@ Span 名统一为 `browser.websocket`,通过 `websocket.phase` 区分,不使
|
|
|
306
310
|
|
|
307
311
|
检查 URL 是否真正命中 `allowedTracingUrls`、浏览器预检是否成功、服务端是否允许 `traceparent`,以及代理是否删除该 Header。
|
|
308
312
|
|
|
309
|
-
完整字段见[遥测字段字典](./telemetry-reference.md#请求与静态资源字段)。
|
|
313
|
+
完整字段见[遥测字段字典](./telemetry-reference.md#请求与静态资源字段)。产品阶段图见[RUM 语义约定 · 资源加载时序](./span-protocol.md#0x04-资源加载时序)。
|
|
@@ -102,7 +102,7 @@ tracking: {
|
|
|
102
102
|
- `redactUrl`:隐私和敏感数据边界;
|
|
103
103
|
- `getUrlTemplate`:聚合维度和查询基数。
|
|
104
104
|
|
|
105
|
-
请求侧的 `tracking.request.getUrlTemplate` 同理,只生成 `url.template`,不影响 `url.full`
|
|
105
|
+
请求侧的 `tracking.request.getUrlTemplate` 同理,只生成 `url.template`,不影响 `url.full` 的脱敏。Fetch/XHR 会传入**未脱敏**的请求 URL,因此自定义实现不要把 query 里的原值拼进返回的模板。静态资源先通过 `redactUrl` 脱敏,再把结果传给该 Hook,避免模板重新暴露已从 `url.full` 移除的路径信息。
|
|
106
106
|
|
|
107
107
|
未配置 `context.attributes.page` 时默认返回空对象,不存在独立的默认页面属性路径。页面地址统一由经过 `redactUrl` 的 `view.url` 表达,聚合维度使用 `view.url_template`;业务通过该 Hook 添加的属性仍需自行确保不包含敏感信息。
|
|
108
108
|
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
| 状态 | 描述 |
|
|
14
14
|
| -------------------------------------------------------------- | -------------- |
|
|
15
15
|
|  | 已上报,保持现状。 |
|
|
16
|
-
|  | 新补充或字段位置变更。 |
|
|
17
16
|
|  | 已上报,但需要废弃。 |
|
|
17
|
+
|  | 新补充或字段位置变更。 |
|
|
18
18
|
|  | 由后端生成,前端不直接上报。 |
|
|
19
19
|
|
|
20
20
|
原则:
|
|
21
|
-
* Aegis、DataDog 后续统一转成 Otel Span 协议,同领域字段尽量对齐前两个 SDK,需控制字段数量,避免出现需转换 150+
|
|
21
|
+
* Aegis、DataDog 后续统一转成 Otel Span 协议,同领域字段尽量对齐前两个 SDK,需控制字段数量,避免出现需转换 150+ 字段的情况。
|
|
22
22
|
* 控制字段规模:输出可覆盖 Otel & Aegis & DataDog SDK 最简协议,其他不必要字段统一省略,减少初始技术负债(字段一旦放出但没有真正使用,稳定后一旦有需求变更,就有兼容风险)。
|
|
23
23
|
* 指标:Web Vitals 指标由接收端派生,SDK 无需埋点。
|
|
24
24
|
|
|
@@ -115,32 +115,33 @@ Session
|
|
|
115
115
|
| `links[].trace_id` |  | str | 关联 TraceID | |
|
|
116
116
|
| `links[].span_id` |  | str | 关联 SpanID | |
|
|
117
117
|
|
|
118
|
-
**[1] `links[].trace_id`**:满足 `attributesspan_type=resource, attributes.resource.type=xhr` 时,需将前端生成的 TraceID 记录到该字段。
|
|
118
|
+
**[1] `links[].trace_id`**:满足 `attributesspan_type=resource, attributes.resource.type=xhr or fetch` 时,需将前端生成的 TraceID 记录到该字段。
|
|
119
119
|
|
|
120
120
|
|
|
121
|
-
##
|
|
121
|
+
## 0x03 Attributes
|
|
122
122
|
|
|
123
123
|
### a. 基础字段
|
|
124
124
|
|
|
125
|
-
| 字段
|
|
126
|
-
|
|
|
127
|
-
| `attributes.user.id`
|
|
128
|
-
| `attributes.span_type` *[1]*
|
|
129
|
-
| `attributes.outcome.type`
|
|
125
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
126
|
+
| ---------------------------- | ---------------------------------------------------------- | ---- | ------- | ---------------------------------------------- |
|
|
127
|
+
| `attributes.user.id` |  | str | 用户 ID | -- |
|
|
128
|
+
| `attributes.span_type` *[1]* |  | enum | Span 类型 | -- |
|
|
129
|
+
| `attributes.outcome.type` |  | enum | 执行结果 | `success`、`warning`、`error`、`timeout`、`abort`。 |
|
|
130
|
+
|
|
130
131
|
|
|
131
132
|
**[1] `attributes.span_type`**:
|
|
132
133
|
|
|
133
|
-
| 值
|
|
134
|
-
|
|
|
135
|
-
| `session`
|
|
136
|
-
| `view`
|
|
137
|
-
| `resource`
|
|
138
|
-
| `error`
|
|
139
|
-
| `vital`
|
|
140
|
-
| `long_task` | Long Task 或长动画帧。
|
|
141
|
-
| `action`
|
|
142
|
-
| `websocket` | WebSocket 生命周期事件。
|
|
143
|
-
| `custom`
|
|
134
|
+
| 值 | 描述 |
|
|
135
|
+
| ----------- | -------------------- |
|
|
136
|
+
| `session` | Session 创建、轮换或结束。 |
|
|
137
|
+
| `view` | 页面首次加载或路由视图生命周期。 |
|
|
138
|
+
| `resource` | 静态资源、Fetch 或 XHR 请求。 |
|
|
139
|
+
| `error` | 浏览器错误、白屏或 CSP 违规。 |
|
|
140
|
+
| `vital` | Web Vitals 指标。 |
|
|
141
|
+
| `long_task` | Long Task 或长动画帧。 |
|
|
142
|
+
| `action` | 用户交互或主动上报的 Action。 |
|
|
143
|
+
| `websocket` | WebSocket 生命周期事件。 |
|
|
144
|
+
| `custom` | 主动上报的自定义事件。 |
|
|
144
145
|
|
|
145
146
|
### b. [error](https://opentelemetry.io/docs/specs/semconv/registry/attributes/error/)
|
|
146
147
|
|
|
@@ -173,21 +174,29 @@ Session
|
|
|
173
174
|
|
|
174
175
|
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
175
176
|
| ------------------------------------ | -------------------------------------------------------------- | ---- | ------- | ----------------------------------------------------------- |
|
|
176
|
-
| `attributes.network.connection.type` |  |
|
|
177
|
+
| `attributes.network.connection.type` |  | enum | 连接类型 | 直接使用浏览器 `navigator.connection.type` 的原始值;字段不存在时不上报。 |
|
|
177
178
|
| `attributes.network.effective_type` |  | str | 有效网络质量 | -- |
|
|
178
179
|
| `attributes.network.status` |  | enum | 网络连接状态 | `connected`、`not_connected`。 |
|
|
179
180
|
| `attributes.network.protocol.name` |  | enum | 应用层网络协议 | 仅 WebSocket Span 上报,固定为 `websocket`;HTTP Resource Span 不上报。 |
|
|
180
181
|
|
|
181
|
-
**[1] `attributes.network.connection.type
|
|
182
|
+
**[1] `attributes.network.connection.type`**:表示设备当前使用的物理网络连接方式。SDK 直接上报
|
|
183
|
+
[`navigator.connection.type`](https://wicg.github.io/netinfo/#connectiontype-enum);浏览器不支持该 API
|
|
184
|
+
或没有返回 `type` 时不携带该字段。该字段对应 DataDog 的 `connectivity.interfaces` 和 Aegis 的 `netType`。
|
|
182
185
|
|
|
183
186
|
Aegis 将「连接类型」「网络质量」整合成 `netType`(`wifi`、`wired`、`2G`、`3G`、`5G`、`6G`),不推荐这种做法。
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
|
187
|
-
|
|
|
188
|
-
| `
|
|
189
|
-
| `
|
|
190
|
-
| `
|
|
187
|
+
转换 Aegis 数据时,`wifi` 保持不变,`wired` 映射为 `ethernet`,移动网络代际映射为 `cellular`。
|
|
188
|
+
|
|
189
|
+
| 值 | 描述 | 备注 |
|
|
190
|
+
| ---------- | -------- | --------------------------------------- |
|
|
191
|
+
| `bluetooth` | 蓝牙网络 | 通过蓝牙网络连接。 |
|
|
192
|
+
| `cellular` | 蜂窝移动网络 | 不表示具体移动网络代际。 |
|
|
193
|
+
| `ethernet` | 以太网 | Aegis 的 `wired` 映射为该值。 |
|
|
194
|
+
| `mixed` | 混合连接 | 浏览器同时使用多种连接方式。 |
|
|
195
|
+
| `none` | 无网络连接 | 通常与 `network.status=not_connected` 同时出现。 |
|
|
196
|
+
| `other` | 其他连接方式 | 浏览器知道连接类型,但不属于已列出的类型。 |
|
|
197
|
+
| `unknown` | 未知连接方式 | 已建立网络连接,但浏览器无法或不愿提供连接类型。 |
|
|
198
|
+
| `wifi` | Wi-Fi 网络 | 仅表示通过 Wi-Fi 连接,不代表网络一定快。 |
|
|
199
|
+
| `wimax` | WiMAX 网络 | 通过 WiMAX 连接。 |
|
|
191
200
|
|
|
192
201
|
**[2] `attributes.network.effective_type`**:表示浏览器根据延迟和下载速度估算出的实际网络质量,等同与 DataDog(`connectivity.effective_type`)、Aegis(`netType`)。
|
|
193
202
|
|
|
@@ -220,25 +229,26 @@ Aegis 将「连接类型」「网络质量」整合成 `netType`(`wifi`、`wir
|
|
|
220
229
|
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
221
230
|
| ------------------------------------- | -------------------------------------------------------------- | ------ | ----------------------- | --------------------------------------------- |
|
|
222
231
|
| `attributes.view.id` |  | str | 视图 ID | |
|
|
223
|
-
| `attributes.view.name`
|
|
224
|
-
| `attributes.view.loading_type`
|
|
232
|
+
| `attributes.view.name` *[1]* |  | str | 视图名称 | 如 `/apm/home`。 |
|
|
233
|
+
| `attributes.view.loading_type` *[2]* |  | str | 视图加载类型 | -- |
|
|
225
234
|
| `attributes.view.url` |  | str | 视图 URL | 如 `https://example.com/cur`。 |
|
|
226
235
|
| `attributes.view.previous` |  | str | 视图 URL(前一个) | 如 `https://example.com/pre`。 |
|
|
227
|
-
| `attributes.view.
|
|
228
|
-
| `attributes.view.
|
|
236
|
+
| `attributes.view.previous_url_template` |  | str | 前序视图路径模板 | 与 `view.url_template` 使用同一规则;初始 View 为空字符串。 |
|
|
237
|
+
| `attributes.view.referrer` |  | str | 初始来源页面 URL | 仅首次加载且值非空时上报,需进行 URL 脱敏。 |
|
|
238
|
+
| `attributes.view.url_template` *[3]* |  | str | 视图路径分组 | 如 `/apm/home`。 |
|
|
229
239
|
| `attributes.view.loading_time` |  | number | 视图加载耗时(ms) | 加载时间计算完成后上报。 |
|
|
230
|
-
| `attributes.view.loading_time_source` |  | enum | 视图加载耗时来源 | `auto`、`manual`。
|
|
240
|
+
| `attributes.view.loading_time_source` |  | enum | 视图加载耗时来源 | `auto`、`manual`。 |
|
|
231
241
|
| `attributes.view.first_byte` |  | number | 首字节时间(ms) | 仅初始导航存在。 |
|
|
232
242
|
| `attributes.view.dom_interactive` |  | number | DOM 可交互时间(ms) | 仅初始导航存在。 |
|
|
233
243
|
| `attributes.view.dom_content_loaded` |  | number | DOMContentLoaded 时间(ms) | 仅初始导航存在。 |
|
|
234
244
|
| `attributes.view.dom_complete` |  | number | DOM Complete 时间(ms) | 仅初始导航存在。 |
|
|
235
245
|
| `attributes.view.load_event` |  | number | Load Event 时间(ms) | 仅初始导航存在。 |
|
|
236
|
-
| `attributes.view.phase`
|
|
246
|
+
| `attributes.view.phase` *[4]* |  | enum | 视图生命周期阶段 | 枚举值:<br>- start<br>- update<br>- end |
|
|
237
247
|
| `attributes.view.started_at` |  | number | 视图开始时间(ms) | 取 `performance.timeOrigin`。 |
|
|
238
248
|
| `attributes.view.version` |  | int | 视图事件版本号 | 同一 `attributes.view.id` 从 `1` 开始递增,用于排序和幂等合并。 |
|
|
239
249
|
| `attributes.view.end_reason` |  | str | 结束原因 | -- |
|
|
240
250
|
|
|
241
|
-
**[1] `attributes.view.name
|
|
251
|
+
**[1] `attributes.view.name`**:仅由 `startView({ name })` 或 `setViewName` 显式设置;未设置时,展示层可回退到 `view.url_template`。
|
|
242
252
|
|
|
243
253
|
**[2] `attributes.view.loading_type`**:
|
|
244
254
|
|
|
@@ -249,9 +259,9 @@ Aegis 将「连接类型」「网络质量」整合成 `netType`(`wifi`、`wir
|
|
|
249
259
|
| `session_renewal` | 会话续期后重建 |
|
|
250
260
|
| `bf_cache` | 从浏览器 BFCache 恢复 |
|
|
251
261
|
|
|
252
|
-
**[3] `attributes.view.
|
|
262
|
+
**[3] `attributes.view.url_template`**:用于聚合的页面路径。默认把数字 ID、UUID 和长十六进制段替换为 `:id`,也可由 `tracking.view.getUrlTemplate` 自定义。
|
|
253
263
|
|
|
254
|
-
**[
|
|
264
|
+
**[4] `attributes.view.phase`**:当前 View Span 的生命周期阶段,Schema v3 不再用一条长 Span 表达整个 View,而是发送多条瞬时生命周期 Span。
|
|
255
265
|
|
|
256
266
|
|
|
257
267
|
```text
|
|
@@ -358,18 +368,22 @@ View B █████████████
|
|
|
358
368
|
|
|
359
369
|
**[2] 单位**:`xx_size` 为 bytes,`duration` & `start` 为毫秒。
|
|
360
370
|
|
|
371
|
+
**[3] 阶段图**:产品阶段划分见 [0x04 资源加载时序](#0x04-资源加载时序)。
|
|
372
|
+
|
|
361
373
|
### i. action
|
|
362
374
|
|
|
363
|
-
| 字段 | 状态
|
|
364
|
-
| ------------------------------------------ |
|
|
365
|
-
| `attributes.action.id` | 
|
|
366
|
-
| `attributes.action.type` *[
|
|
367
|
-
| `attributes.action.target.name` | 
|
|
368
|
-
| `attributes.action.target.tag` | 
|
|
369
|
-
| `attributes.action.frustration.type` *[
|
|
375
|
+
| 字段 | 状态 | 类型 | 描述 |
|
|
376
|
+
| ------------------------------------------ | ---------------------------------------------------------- | ----- | ------ |
|
|
377
|
+
| `attributes.action.id` |  | str | -- |
|
|
378
|
+
| `attributes.action.type` *[2]* |  | str | 动作类型 |
|
|
379
|
+
| `attributes.action.target.name` |  | str | 目标元素名称 |
|
|
380
|
+
| `attributes.action.target.tag` |  | str | 目标元素标签 |
|
|
381
|
+
| `attributes.action.frustration.type` *[3]* |  | str[] | 挫败类型 |
|
|
370
382
|
|
|
371
383
|
|
|
372
|
-
**[1] `attributes.action.
|
|
384
|
+
**[1] `attributes.action.loading_time`**:`loading_time` 可直接使用外层 `elapsed_time`。
|
|
385
|
+
|
|
386
|
+
**[2] `attributes.action.type`**:
|
|
373
387
|
|
|
374
388
|
| 常见值 | 描述 |
|
|
375
389
|
| -------------------- | ---------------------------------- |
|
|
@@ -383,7 +397,7 @@ View B █████████████
|
|
|
383
397
|
|
|
384
398
|
以上是跨端常见值,不是封闭枚举。蓝鲸 Web 当前产生 `click` 和 `custom`。转换 Aegis 数据时,还可能保留接入方配置的 DOM 事件名。
|
|
385
399
|
|
|
386
|
-
**[
|
|
400
|
+
**[3] `attributes.action.frustration.type`**:
|
|
387
401
|
|
|
388
402
|
| 值 | 描述 |
|
|
389
403
|
| ------------- | ------------------------------------------------------------------------------------ |
|
|
@@ -395,35 +409,36 @@ View B █████████████
|
|
|
395
409
|
|
|
396
410
|
### j. http & [url](https://opentelemetry.io/docs/specs/semconv/registry/attributes/url/) & server
|
|
397
411
|
|
|
398
|
-
| 字段 | 状态
|
|
399
|
-
| -------------------------------------- |
|
|
400
|
-
| `attributes.url.full` | 
|
|
401
|
-
| `attributes.url.scheme` | 
|
|
402
|
-
| `attributes.
|
|
403
|
-
| `attributes.http.
|
|
404
|
-
| `attributes.
|
|
405
|
-
| `attributes.server.
|
|
412
|
+
| 字段 | 状态 | 类型 | 描述 | |
|
|
413
|
+
| -------------------------------------- | ---------------------------------------------------------- | --- | ------ | ---------------------------- |
|
|
414
|
+
| `attributes.url.full` |  | str | 完整 URL | 如 `https://example.com/apm`。 |
|
|
415
|
+
| `attributes.url.scheme` |  | str | 协议 | 如 `ws`、`wss`。 |
|
|
416
|
+
| `attributes.url.template` |  | str | 请求路径 | 如 `/api/users/`。 |
|
|
417
|
+
| `attributes.http.request.method` |  | str | 请求方法 | 如 `GET`、`POST`。 |
|
|
418
|
+
| `attributes.http.response.status_code` |  | int | 返回码 | 如 `200`、`404`。 |
|
|
419
|
+
| `attributes.server.address` |  | str | 地址 | 如 `example.com`。 |
|
|
420
|
+
| `attributes.server.port` |  | int | 端口 | -- |
|
|
406
421
|
|
|
407
422
|
### k. vital
|
|
408
423
|
|
|
409
|
-
| 字段 | 状态
|
|
410
|
-
| --------------------------------------------- |
|
|
411
|
-
| `attributes.vital.id` | 
|
|
412
|
-
| `attributes.vital.metric` | 
|
|
413
|
-
| `attributes.vital.value` | 
|
|
414
|
-
| `attributes.vital.inp.input_delay` | 
|
|
415
|
-
| `attributes.vital.inp.interaction_target` | 
|
|
416
|
-
| `attributes.vital.inp.interaction_type` | 
|
|
417
|
-
| `attributes.vital.inp.processing_duration` | 
|
|
418
|
-
| `attributes.vital.inp.presentation_delay` | 
|
|
419
|
-
| `attributes.vital.lcp.target` | 
|
|
420
|
-
| `attributes.vital.lcp.url` | 
|
|
421
|
-
| `attributes.vital.lcp.resource_load_duration` | 
|
|
422
|
-
| `attributes.vital.lcp.element_render_delay` | 
|
|
423
|
-
| `attributes.vital.ttfb.waiting_duration` | 
|
|
424
|
-
| `attributes.vital.ttfb.dns_duration` | 
|
|
425
|
-
| `attributes.vital.ttfb.connection_duration` | 
|
|
426
|
-
| `attributes.vital.ttfb.request_duration` | 
|
|
424
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
425
|
+
| --------------------------------------------- | ---------------------------------------------------------- | ------ | -------------------- | ------------------------------------ |
|
|
426
|
+
| `attributes.vital.id` |  | str | Vital 唯一标识 | |
|
|
427
|
+
| `attributes.vital.metric` |  | enum | 指标名 | |
|
|
428
|
+
| `attributes.vital.value` |  | number | 指标测量值 | |
|
|
429
|
+
| `attributes.vital.inp.input_delay` |  | number | 输入延迟(ms) | 用户发起交互(如点击)到事件处理器开始执行的等待时间,反映主线程繁忙程度 |
|
|
430
|
+
| `attributes.vital.inp.interaction_target` |  | str | 交互目标元素标识 | 如 `div`。 |
|
|
431
|
+
| `attributes.vital.inp.interaction_type` |  | str | 交互类型 | -- |
|
|
432
|
+
| `attributes.vital.inp.processing_duration` |  | number | 处理耗时(ms) | -- |
|
|
433
|
+
| `attributes.vital.inp.presentation_delay` |  | number | 呈现延迟(ms) | -- |
|
|
434
|
+
| `attributes.vital.lcp.target` |  | str | DOM 选择器 | 如 `div`。 |
|
|
435
|
+
| `attributes.vital.lcp.url` |  | str | 元素对应资源 URL(已脱敏) | -- |
|
|
436
|
+
| `attributes.vital.lcp.resource_load_duration` |  | number | 资源加载耗时(ms) | -- |
|
|
437
|
+
| `attributes.vital.lcp.element_render_delay` |  | number | 元素渲染延迟(ms) | -- |
|
|
438
|
+
| `attributes.vital.ttfb.waiting_duration` |  | number | 请求就绪后的等待耗时(ms) | -- |
|
|
439
|
+
| `attributes.vital.ttfb.dns_duration` |  | number | DNS 解析耗时(ms) | -- |
|
|
440
|
+
| `attributes.vital.ttfb.connection_duration` |  | number | TCP + TLS 连接建立耗时(ms) | -- |
|
|
441
|
+
| `attributes.vital.ttfb.request_duration` |  | number | 请求发送后等待首字节耗时(ms) | -- |
|
|
427
442
|
|
|
428
443
|
**[1] `attributes.vital.metric`**:
|
|
429
444
|
|
|
@@ -437,7 +452,9 @@ View B █████████████
|
|
|
437
452
|
|
|
438
453
|
**[2] `attributes.vital.value`**:CLS 单位为 `1`,FCP、INP、LCP、TTFB 单位为 `ms`。
|
|
439
454
|
|
|
440
|
-
**[3] `attributes.vital.
|
|
455
|
+
**[3] `attributes.vital.cls.largest_shift_value` & `attributes.vital.cls.largest_shift_target`**:Aegis & DataDog 无采集,废弃。
|
|
456
|
+
|
|
457
|
+
**[4] `attributes.vital.inp.interaction_type`**:交互类型。
|
|
441
458
|
|
|
442
459
|
| 值 | 描述 |
|
|
443
460
|
| ------------- | ------------- |
|
|
@@ -446,21 +463,23 @@ View B █████████████
|
|
|
446
463
|
| `pointerdown` | 点击(鼠标、触屏、触控笔) |
|
|
447
464
|
| `pointerup` | 松开 |
|
|
448
465
|
|
|
449
|
-
**[
|
|
466
|
+
**[5] `attributes.vital.inp.processing_duration`**:事件处理回调(如 click handler)本身的执行时间,JS 逻辑过重时这个值会变大。
|
|
467
|
+
|
|
468
|
+
**[6] `attributes.vital.inp.presentation_delay`**:回调操作完成之后到该帧最终显示在用户屏幕上所需的时间。
|
|
450
469
|
|
|
451
|
-
**[
|
|
470
|
+
**[7] `attributes.vital.lcp.element_render_delay`**:LCP 元素资源加载完成后,到浏览器真正渲染该元素之间的等待时间(主要由主线程阻塞(长任务/JS 执行)导致)。
|
|
452
471
|
|
|
453
|
-
**[
|
|
472
|
+
**[8] `attributes.vital.lcp.resource_load_duration`**:LCP 元素依赖的外部资源(图片/字体等)从请求到下载完成的时间(如果 LCP 是纯文本节点,此项可能缺失),用于排查 CDN/网络/资源体积问题。
|
|
454
473
|
|
|
455
|
-
**[
|
|
474
|
+
**[9] `attributes.vital.lcp.time_to_first_byte`**:从导航开始到收到首字节的耗时(LCP ≈ `time_to_first_byte` + `resource_load_duration` + `element_render_delay`)。
|
|
456
475
|
|
|
457
|
-
**[
|
|
476
|
+
**[10] `attributes.vital.ttfb.waiting_duration`**:页面激活到浏览器开始 Fetch,或开始启动 Service Worker 前的时间(包含重定向及浏览器前置处理)。
|
|
458
477
|
|
|
459
|
-
**[
|
|
478
|
+
**[11] `attributes.vital.ttfb.dns_duration`**:解析慢通常由 DNS 服务器延迟、复杂 CNAME 链或本地 DNS 缓存失效导致(多国/多地域部署时此值可能偏高)。
|
|
460
479
|
|
|
461
|
-
**[
|
|
480
|
+
**[12] `attributes.vital.ttfb.connection_duration`**:TCP / QUIC 建连及 TLS 协商,连接复用时通常为 `0`。
|
|
462
481
|
|
|
463
|
-
**[
|
|
482
|
+
**[13] `attributes.vital.ttfb.request_duration`**:建连结束到收到首字节,包含调度空档、请求发送、网络 RTT 和服务端处理。
|
|
464
483
|
|
|
465
484
|
|
|
466
485
|
### l. blank_screen
|
|
@@ -477,7 +496,7 @@ View B █████████████
|
|
|
477
496
|
| 值 | 描述 |
|
|
478
497
|
| ---------------- | --------------------------------------------------------------------------------------- |
|
|
479
498
|
| `empty_viewport` | 配置的采样根元素存在,有效采样点的空白比例达到白屏阈值。 |
|
|
480
|
-
| `missing_root` |
|
|
499
|
+
| `missing_root` | 未找到 `root_selector` 指定的根元素,SDK 回退到 `body`(不可用时使用 `documentElement`)检测,且回退检测仍达到白屏阈值。 |
|
|
481
500
|
|
|
482
501
|
### m. longtask
|
|
483
502
|
|
|
@@ -501,3 +520,148 @@ View B █████████████
|
|
|
501
520
|
### n. custom
|
|
502
521
|
|
|
503
522
|
`reportCustomEvent()` 产生 `custom.<name>` Span。
|
|
523
|
+
|
|
524
|
+
## 0x04 资源加载时序
|
|
525
|
+
|
|
526
|
+
本文对照 W3C Resource Timing、Chrome Timing 和 web.dev,并给出 Resource Span 请求时序的产品划分。适用范围是单次 `resource` Span 的阶段图,不含 View 导航瀑布。
|
|
527
|
+
|
|
528
|
+
阶段名称靠近 Chrome Timing。每段时长用已上报的 `attributes.resource.*.duration` 计算,起点用对应的 `start`,单位为毫秒,相对该资源 `startTime`。
|
|
529
|
+
|
|
530
|
+
产品按 `attributes.view.id` 关联 View 生命周期快照后,可用 `attributes.view.previous_url_template` 展示资源所属页面的前序路由。该字段与 `attributes.view.url_template` 使用同一模板规则,初始 View 为空字符串;它不参与 Resource Timing 阶段计算,也不直接写入 `resource` Span。
|
|
531
|
+
|
|
532
|
+
### a. W3C Resource Timing
|
|
533
|
+
|
|
534
|
+
规范记录的是时间点,不是产品上的色块。浏览器按发生顺序打点,产品上的每一段是相邻两点相减。来源:[Resource Timing](https://www.w3.org/TR/resource-timing/)。
|
|
535
|
+
|
|
536
|
+
| 顺序 | 时间点 | 含义 |
|
|
537
|
+
| --- | --- | --- |
|
|
538
|
+
| 1 | `startTime` | 这次取资源开始 |
|
|
539
|
+
| 2 | `redirectStart` | 第一次重定向开始 |
|
|
540
|
+
| 3 | `redirectEnd` | 最后一次重定向的响应收完 |
|
|
541
|
+
| 4 | `workerStart` | Service Worker 开始处理这次请求;未拦截时为 `0` |
|
|
542
|
+
| 5 | `fetchStart` | 重定向结束后,开始取最终资源 |
|
|
543
|
+
| 6 | `domainLookupStart` | DNS 查询开始 |
|
|
544
|
+
| 7 | `domainLookupEnd` | DNS 查询结束 |
|
|
545
|
+
| 8 | `connectStart` | 开始建立到服务器的连接 |
|
|
546
|
+
| 9 | `secureConnectionStart` | TLS 握手开始;非 HTTPS 时为 `0` |
|
|
547
|
+
| 10 | `connectEnd` | 连接建立完成,TLS 包含在内 |
|
|
548
|
+
| 11 | `requestStart` | 开始向服务器发请求 |
|
|
549
|
+
| 12 | `firstInterimResponseStart` | 中间响应,例如 `103` |
|
|
550
|
+
| 13 | `responseStart` | 收到响应首字节 |
|
|
551
|
+
| 14 | `finalResponseHeadersStart` | 最终响应头开始,通常是 `200` |
|
|
552
|
+
| 15 | `responseEnd` | 最后一字节到达,或连接先关闭 |
|
|
553
|
+
|
|
554
|
+
用上面的时间点可以算出这些耗时:
|
|
555
|
+
|
|
556
|
+
| 顺序 | 耗时 | 计算 |
|
|
557
|
+
| --- | --- | --- |
|
|
558
|
+
| 1 | 重定向 | `redirectEnd − redirectStart` |
|
|
559
|
+
| 2 | Service Worker | `fetchStart − workerStart` |
|
|
560
|
+
| 3 | DNS | `domainLookupEnd − domainLookupStart` |
|
|
561
|
+
| 4 | 建立连接(含 TLS) | `connectEnd − connectStart` |
|
|
562
|
+
| 5 | TLS 握手 | `connectEnd − secureConnectionStart` |
|
|
563
|
+
| 6 | 发出请求后等到首字节 | `responseStart − requestStart` |
|
|
564
|
+
| 7 | 接收响应体 | `responseEnd − responseStart` |
|
|
565
|
+
|
|
566
|
+
规范没有排队时间点。跨源资源未通过 Timing-Allow-Origin 检查时,重定向到 `responseStart` 之间的点会变成 `0`,只保留 `startTime`、`fetchStart`、总时长和 `responseEnd`。
|
|
567
|
+
|
|
568
|
+
`workerStart` 是重定向链最终请求上的 Service Worker 开始时间。`fetchStart` 是 post-redirect start。产品上的「后台脚本处理」发生在重定向之后。
|
|
569
|
+
|
|
570
|
+
### b. Chrome Timing
|
|
571
|
+
|
|
572
|
+
Chrome 开发者工具中,点开一条请求的 Timing。一次请求不会出现全部标签。来源:[Chrome 网络面板说明](https://developer.chrome.com/docs/devtools/network/reference)。
|
|
573
|
+
|
|
574
|
+
| 顺序 | Timing 标签 | 含义 |
|
|
575
|
+
| --- | --- | --- |
|
|
576
|
+
| 1 | Queueing | 连接开始前排队:存在更高优先级请求,或同一源连接数已满 |
|
|
577
|
+
| 2 | Stalled | 连接开始后仍可能因 Queueing 同类原因停滞 |
|
|
578
|
+
| 3 | DNS Lookup | 解析域名对应的 IP |
|
|
579
|
+
| 4 | Initial connection | 建立连接,包含 TCP 握手和 TLS,不单列 TLS |
|
|
580
|
+
| 5 | Proxy negotiation | 与代理协商,仅走代理时出现 |
|
|
581
|
+
| 6 | Request sent | 正在发送 HTTP 请求 |
|
|
582
|
+
| 7 | ServiceWorker Preparation | 正在启动 Service Worker |
|
|
583
|
+
| 8 | Request to ServiceWorker | 请求交给 Service Worker |
|
|
584
|
+
| 9 | Waiting (TTFB) | 请求已发出,等待响应首字节。包含一趟网络往返和服务器准备时间 |
|
|
585
|
+
| 10 | Content Download | 读取响应体 |
|
|
586
|
+
|
|
587
|
+
常见可见:Queueing、DNS Lookup、Initial connection、Waiting (TTFB)、Content Download。连接已建立时,DNS Lookup 和 Initial connection 经常为 `0`。
|
|
588
|
+
|
|
589
|
+
Chrome 不单独上报 Queueing / Stalled / Request sent 到 RUM 字段,产品阶段图无法画出这三行。
|
|
590
|
+
|
|
591
|
+
### c. Google web.dev
|
|
592
|
+
|
|
593
|
+
web.dev 讲解同一组时间点,并单独定义页面导航的 Time to First Byte(TTFB,首字节时间)。来源:[Navigation and Resource Timing](https://web.dev/articles/navigation-and-resource-timing)、[TTFB](https://web.dev/articles/ttfb)。
|
|
594
|
+
|
|
595
|
+
| 顺序 | 阶段 | 时间点 | 含义 |
|
|
596
|
+
| --- | --- | --- | --- |
|
|
597
|
+
| 1 | Redirects | `redirectStart` / `redirectEnd` | HTTP 重定向 |
|
|
598
|
+
| 2 | DNS lookup | `domainLookupStart` / `domainLookupEnd` | DNS 解析 |
|
|
599
|
+
| 3 | Connection | `connectStart` → `secureConnectionStart` → `connectEnd` | 建连,HTTPS 时包含 TLS,TLS 耗时 = `connectEnd − secureConnectionStart` |
|
|
600
|
+
| 4 | Fetch | `fetchStart` | 开始取资源,会先查缓存 |
|
|
601
|
+
| 5 | Service worker | `workerStart` | 未拦截时为 `0` |
|
|
602
|
+
| 6 | Request | `requestStart` → `responseStart` | 发出请求到收到首字节 |
|
|
603
|
+
| 7 | Response | `responseStart` → `responseEnd` | 接收响应体 |
|
|
604
|
+
|
|
605
|
+
web.dev 的页面 TTFB 从导航开始算到 `responseStart`,包含:
|
|
606
|
+
|
|
607
|
+
1. 重定向
|
|
608
|
+
2. Service Worker 启动(如有)
|
|
609
|
+
3. DNS
|
|
610
|
+
4. 建连和 TLS
|
|
611
|
+
5. 发出请求直到首字节到达
|
|
612
|
+
|
|
613
|
+
Chrome Timing 的 Waiting (TTFB) 只等于第 `5` 项。Resource Span 的「等待首字节」跟 Chrome 这一行走,对应 `resource.first_byte.duration`。
|
|
614
|
+
|
|
615
|
+
### d. 产品建议
|
|
616
|
+
|
|
617
|
+
始终展示查找服务器、建立连接、加密连接、等待首字节、下载内容。上报了重定向或 Service Worker 时,再增加对应行。
|
|
618
|
+
|
|
619
|
+
时长用 `resource.*.duration`。建立连接需要减去 TLS:W3C 的 `connectEnd − connectStart` 已包含加密,直接展示完整 `connect.duration` 会和下一行重复。无 `ssl` 时使用完整 `connect.duration`。
|
|
620
|
+
|
|
621
|
+
#### 阶段与计算
|
|
622
|
+
|
|
623
|
+
| 顺序 | 产品名 | 出现条件 | 时长 |
|
|
624
|
+
| --- | --- | --- | --- |
|
|
625
|
+
| 1 | 重定向 | 上报了 `redirect.start` 和 `redirect.duration` | `attributes.resource.redirect.duration` |
|
|
626
|
+
| 2 | 后台脚本处理 | 上报了 `worker.start` 和 `worker.duration` | `attributes.resource.worker.duration` |
|
|
627
|
+
| 3 | 查找服务器 | 始终占一行 | `attributes.resource.dns.duration` |
|
|
628
|
+
| 4 | 建立连接 | 始终占一行 | 有 `ssl` 时:`connect.duration − ssl.duration`<br />无 `ssl` 时:`connect.duration` |
|
|
629
|
+
| 5 | 加密连接 | 始终占一行 | `attributes.resource.ssl.duration` |
|
|
630
|
+
| 6 | 等待首字节 | 始终占一行 | `attributes.resource.first_byte.duration` |
|
|
631
|
+
| 7 | 下载内容 | 始终占一行 | `attributes.resource.download.duration` |
|
|
632
|
+
|
|
633
|
+
时间轴上,建立连接画到 `ssl.start`,加密连接从 `ssl.start` 画到 `connect` 结束。
|
|
634
|
+
|
|
635
|
+
#### 说明与用户感受
|
|
636
|
+
|
|
637
|
+
| 阶段 | 说明 | 用户感受 |
|
|
638
|
+
| --- | --- | --- |
|
|
639
|
+
| 重定向 | [a] 浏览器跟随 HTTP 重定向,直到拿到最终 URL,对应 `redirectEnd − redirectStart`<br />[b] 未发生重定向时不上报 | [a] 目标内容还没开始出现<br />[b] 文档请求会延长白屏,接口请求会延长 loading |
|
|
640
|
+
| 后台脚本处理 | [a] Service Worker 拦截并处理该请求的时间,对应 `fetchStart − workerStart`<br />[b] 记录的是重定向之后、最终请求上的处理<br />[c] 未拦截时不上报 | [a] 界面没有单独提示<br />[b] 用户只会感到这次加载更慢,无法分辨是后台脚本在处理 |
|
|
641
|
+
| 查找服务器 | [a] DNS 解析耗时,对应 `domainLookupEnd − domainLookupStart`<br />[b] 解析结果已缓存、或未发起新查询时,可能为 `0` 或不上报 | [a] 内容尚未出现<br />[b] 用户无法感知「正在解析域名」,体验上仍是点了之后没有反应 |
|
|
642
|
+
| 建立连接 | [a] 传输连接中扣除 TLS 后的部分<br />[b] W3C 的 `connectEnd − connectStart` 包含加密,产品用 `connect.duration − ssl.duration`,避免与下一行重复 | [a] 内容尚未出现<br />[b] 用户无法感知「正在建连」,体验上仍是在等待 |
|
|
643
|
+
| 加密连接 | [a] TLS 握手,对应 `connectEnd − secureConnectionStart`<br />[b] 非 HTTPS、或未发生新握手时不上报 | [a] 内容尚未出现<br />[b] 用户无法感知「正在握手」,体验上仍是在等待 |
|
|
644
|
+
| 等待首字节 | [a] 从发出请求到收到响应首字节,对应 `responseStart − requestStart`<br />[b] 包含网络往返和服务端处理,浏览器时序无法拆分<br />[c] 对齐 Chrome Waiting (TTFB),范围小于 web.dev 的页面 TTFB | [a] 本次请求的内容仍不可见:页面持续白屏或停留在旧画面,接口持续 loading<br />[b] 过慢时会感觉页面没有反应 |
|
|
645
|
+
| 下载内容 | [a] 从收到首字节到响应体接收完毕,对应 `responseEnd − responseStart`<br />[b] 耗时主要随体积和带宽变化 | [a] 内容开始出现并逐渐完整,图片、脚本会陆续可见<br />[b] 接口数据会从空状态填到页面上<br />[c] 体积大时,用户能感到「出来了但还在加载」 |
|
|
646
|
+
|
|
647
|
+
等待首字节拆不开服务端处理与网络往返。要判断服务端是否慢,需要结合 Trace 或 [Server Timing](https://www.w3.org/TR/server-timing/)。
|
|
648
|
+
|
|
649
|
+
#### 缺数字段
|
|
650
|
+
|
|
651
|
+
| 上报情况 | 页面展示 |
|
|
652
|
+
| --- | --- |
|
|
653
|
+
| `start` 与 `duration` 都在,且 `duration > 0` | 显示毫秒数,画出色块 |
|
|
654
|
+
| `start` 与 `duration` 都在,且 `duration = 0` | 写 `0` 毫秒。该步骤没有额外耗时 |
|
|
655
|
+
| 缺少 `start` 或 `duration` | 写「没有上报」,不画色块。可能该步骤未发生,也可能跨源不允许查看细分时间 |
|
|
656
|
+
|
|
657
|
+
查找服务器、建立连接、加密连接都没有上报时,写「没有上报」。跨源资源未暴露细分时间时表现相同,不能据此判断连接复用。
|
|
658
|
+
|
|
659
|
+
### e. 参考资料
|
|
660
|
+
|
|
661
|
+
| 来源 | 文档 |
|
|
662
|
+
| --- | --- |
|
|
663
|
+
| W3C | [Resource Timing](https://www.w3.org/TR/resource-timing/) |
|
|
664
|
+
| W3C | [Server Timing](https://www.w3.org/TR/server-timing/) |
|
|
665
|
+
| Chrome | [网络面板 · Timing](https://developer.chrome.com/docs/devtools/network/reference) |
|
|
666
|
+
| web.dev | [Navigation and Resource Timing](https://web.dev/articles/navigation-and-resource-timing) |
|
|
667
|
+
| web.dev | [Time to First Byte](https://web.dev/articles/ttfb) |
|