@blueking/open-telemetry 0.0.29 → 0.0.30
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 +393 -452
- package/dist/index.js.map +1 -1
- package/dist/plugins/blank-screen.d.ts +0 -2
- package/dist/plugins/device.d.ts +0 -1
- package/dist/plugins/web-vitals.d.ts +0 -7
- package/dist/schema/attributes.d.ts +2 -8
- package/dist/schema/span.d.ts +1 -3
- package/package.json +1 -1
- package/skills/bk-rum-otele/SKILL.md +2 -1
- package/skills/bk-rum-otele/references/span-protocol.md +503 -0
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
<!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
|
|
2
|
+
|
|
3
|
+
# RUM 语义约定
|
|
4
|
+
|
|
5
|
+
两份文档不重复维护同一套字段规范:一个记录实现现状,一个定义稳定承诺。
|
|
6
|
+
|
|
7
|
+
「[遥测字段字典](./telemetry-reference.md)」是由代码自动生成的事实清单,完整反映当前 SDK 实际产出的 Span 字段。它回答当前实际上报了哪些字段,其中可以包含新增、灰度和待废弃字段,不代表这些字段都已形成稳定承诺。
|
|
8
|
+
|
|
9
|
+
「RUM 语义约定」是前后端共同遵循的语义契约,围绕 RUM 核心字段定义含义、使用方式、约束和生命周期。字段经过评审并标记为 Stable 后,才成为对外稳定承诺;新增、灰度和废弃状态也在这里管理。
|
|
10
|
+
|
|
11
|
+
如果两份文档对不上,先查「遥测字段字典」确认 SDK 现在上报了什么,再查「RUM 语义约定」确认这是尚未完成的改动,还是实现偏差。代码中出现了某个字段,并不表示它已经稳定;只有在「RUM 语义约定」中标记为 Stable,前后端才需要长期兼容这个字段。
|
|
12
|
+
|
|
13
|
+
| 状态 | 描述 |
|
|
14
|
+
| -------------------------------------------------------------- | -------------- |
|
|
15
|
+
|  | 已上报,保持现状。 |
|
|
16
|
+
|  | 新补充或字段位置变更。 |
|
|
17
|
+
|  | 已上报,但需要废弃。 |
|
|
18
|
+
|  | 由后端生成,前端不直接上报。 |
|
|
19
|
+
|
|
20
|
+
原则:
|
|
21
|
+
* Aegis、DataDog 后续统一转成 Otel Span 协议,同领域字段尽量对齐前两个 SDK,需控制字段数量,避免出现需转换 150+ 字段的情况.
|
|
22
|
+
* 控制字段规模:输出可覆盖 Otel & Aegis & DataDog SDK 最简协议,其他不必要字段统一省略,减少初始技术负债(字段一旦放出但没有真正使用,稳定后一旦有需求变更,就有兼容风险)。
|
|
23
|
+
* 指标:Web Vitals 指标由接收端派生,SDK 无需埋点。
|
|
24
|
+
|
|
25
|
+
## 0x01 用户真实监控模型
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
Session
|
|
29
|
+
└── View
|
|
30
|
+
├── Vital:FCP / LCP / CLS / INP / TTFB
|
|
31
|
+
├── Action
|
|
32
|
+
├── Resource
|
|
33
|
+
├── Error
|
|
34
|
+
└── Long Task
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 0x02 公共字段
|
|
38
|
+
|
|
39
|
+
### a. 顶层字段
|
|
40
|
+
|
|
41
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
42
|
+
| ---------------- | -------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
|
|
43
|
+
| `time` |  | str | 数据上报时间(毫秒时间戳字符串) | -- |
|
|
44
|
+
| `app_name` |  | str | 应用名称 | -- |
|
|
45
|
+
| `bk_biz_id` |  | str | 业务 ID | -- |
|
|
46
|
+
| `trace_id` |  | str | Trace ID | -- |
|
|
47
|
+
| `trace_state` |  | str | Trace 状态 | -- |
|
|
48
|
+
| `span_name` |  | str | Span 名称 | -- |
|
|
49
|
+
| `span_id` |  | str | Span ID | -- |
|
|
50
|
+
| `parent_span_id` |  | str | 父 Span ID | -- |
|
|
51
|
+
| `status` |  | Status | Span 执行状态 | 包含 `code` 和 `message`。 |
|
|
52
|
+
| `kind` |  | enum | [Span 类型](https://opentelemetry.io/zh/docs/concepts/signals/traces/#span-kind) | 枚举值:<br>- 未定义:0<br>- 内部调用:1<br>- 同步被调:2<br>- 同步主调:3<br>- 异步主调:4<br>- 异步被调:5 |
|
|
53
|
+
| `resource` |  | object | 资源信息 | 服务、环境、SDK 等描述信息。 |
|
|
54
|
+
| `events` |  | Event[] | 事件列表 | 异常详情和 Long Task 脚本明细通过 Span Event 承载。 |
|
|
55
|
+
| `links` |  | Link[] | [Span 链接](https://opentelemetry.io/docs/concepts/signals/traces/#span-links) | 链接的存在是为了 Span 同其他 Span 建立关联,从而表明存在因果关系。 |
|
|
56
|
+
| `attributes` |  | object | 属性 | 浏览器、设备、网络、异常等各类语义标签和度量。 |
|
|
57
|
+
| `start_time` |  | int | 开始时间(微秒) | -- |
|
|
58
|
+
| `end_time` |  | int | 结束时间(微秒) | -- |
|
|
59
|
+
| `elapsed_time` |  | int | 耗时(微秒) | -- |
|
|
60
|
+
|
|
61
|
+
### b. Resource
|
|
62
|
+
|
|
63
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
64
|
+
| ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ------ | ----------- | ---------------------------------------------- |
|
|
65
|
+
| `resource.service.name` |  | str | 服务名 | -- |
|
|
66
|
+
| `resource.service.version` |  | str | 版本 | -- |
|
|
67
|
+
| [`resource.deployment.environment.name`](https://opentelemetry.io/docs/specs/semconv/resource/deployment-environment/) |  | str | 环境 | 如 `development`、`production`、`staging`、`test`。 |
|
|
68
|
+
| `resource.session.sample_rate` |  | number | Session 采样率 | 取值范围为 `0`~`1`。 |
|
|
69
|
+
| `resource.telemetry.sdk.version` |  | str | SDK 版本 | -- |
|
|
70
|
+
| [`resource.telemetry.sdk.language`](https://opentelemetry.io/docs/specs/semconv/resource/#telemetry-sdk) |  | enum | 语言 | `webjs`。 |
|
|
71
|
+
| `resource.telemetry.sdk.name` *[1]* |  | str | SDK 名称 | -- |
|
|
72
|
+
| `resource.device.type` |  | enum | 设备类型 | `desktop`、`mobile`、`tablet`、`other`。 |
|
|
73
|
+
| `resource.user_agent.name` |  | str | 代理名称 | 通常指的是浏览器的名称,如 `Chrome`、`Edge`。 |
|
|
74
|
+
| `resource.user_agent.version` |  | str | 代理版本 | 通常指的是浏览器的名称,如 `149`、`151`。 |
|
|
75
|
+
| `resource.user_agent.os.name` |  | str | 操作系统名 | 如 `macOS`、`Windows`、`Android`。 |
|
|
76
|
+
|
|
77
|
+
**[1] `resource.telemetry.sdk.name`**:`blueking`(蓝鲸 Otel SDK,当前值为 @blueking/open-telemetry,需修改。)|aegis(Aegis SDK)。
|
|
78
|
+
|
|
79
|
+
### c. Status
|
|
80
|
+
|
|
81
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
82
|
+
| ---------------- | ---------------------------------------------------------- | --- | ---- | ---------------------------- |
|
|
83
|
+
| `status.code` |  | int | 状态码 | 0(未设置)<br />1(正常)<br />2(异常) |
|
|
84
|
+
| `status.message` |  | str | 状态描述 | 如 `Failed to fetch` |
|
|
85
|
+
|
|
86
|
+
### d. Event
|
|
87
|
+
|
|
88
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
89
|
+
| ----------------------------------------------------------------------- | ---------------------------------------------------------- | ------ | ------------- | -------------------- |
|
|
90
|
+
| `events[].name` *[1]* |  | str | 事件名 | |
|
|
91
|
+
| `events[].timestamp` |  | int | 事件发生时间(微秒) | |
|
|
92
|
+
| `events[].attributes.exception.type` |  | str | 异常类型 | 如 `TypeError`。 |
|
|
93
|
+
| `events[].attributes.exception.message` |  | str | 异常消息 | 如 `Failed to fetch`。 |
|
|
94
|
+
| `events[].attributes.exception.stacktrace` |  | str | 异常堆栈 | |
|
|
95
|
+
| `events[].attributes.long_task.script.duration` |  | number | 脚本耗时(ms) | |
|
|
96
|
+
| `events[].attributes.long_task.script.execution_start` |  | number | 脚本执行开始时间(ms) | |
|
|
97
|
+
| `events[].attributes.long_task.script.forced_style_and_layout_duration` |  | number | 强制样式与布局耗时(ms) | |
|
|
98
|
+
| `events[].attributes.long_task.script.pause_duration` |  | number | 暂停耗时(ms) | |
|
|
99
|
+
| `events[].attributes.long_task.script.source_char_position` |  | number | 源码字符位置 | |
|
|
100
|
+
| `events[].attributes.long_task.script.start_time` |  | number | 脚本开始时间(ms) | |
|
|
101
|
+
| `events[].attributes.long_task.script.invoker` |  | str | 调用方 | |
|
|
102
|
+
| `events[].attributes.long_task.script.invoker_type` |  | str | 调用方类型 | |
|
|
103
|
+
| `events[].attributes.long_task.script.source_function_name` |  | str | 源函数名 | |
|
|
104
|
+
| `events[].attributes.long_task.script.source_url` |  | str | 已脱敏的脚本 URL | |
|
|
105
|
+
| `events[].attributes.long_task.script.window_attribution` |  | str | Window 归因 | |
|
|
106
|
+
|
|
107
|
+
**[1] `events[].name`**:「异常」需将事件名固定为 `exception`。
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### f. Link
|
|
112
|
+
|
|
113
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
114
|
+
| ------------------ | -------------------------------------------------------------- | --- | ---------- | --- |
|
|
115
|
+
| `links[].trace_id` |  | str | 关联 TraceID | |
|
|
116
|
+
| `links[].span_id` |  | str | 关联 SpanID | |
|
|
117
|
+
|
|
118
|
+
**[1] `links[].trace_id`**:满足 `attributesspan_type=resource, attributes.resource.type=xhr` 时,需将前端生成的 TraceID 记录到该字段。
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
## 0x02 Attributes
|
|
122
|
+
|
|
123
|
+
### a. 基础字段
|
|
124
|
+
|
|
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
|
+
|
|
131
|
+
**[1] `attributes.span_type`**:
|
|
132
|
+
|
|
133
|
+
| 值 | 描述 |
|
|
134
|
+
| ---------- | ---------------------- |
|
|
135
|
+
| `session` | Session 创建、轮换或结束。 |
|
|
136
|
+
| `view` | 页面首次加载或路由视图生命周期。 |
|
|
137
|
+
| `resource` | 静态资源、Fetch 或 XHR 请求。 |
|
|
138
|
+
| `error` | 浏览器错误、白屏或 CSP 违规。 |
|
|
139
|
+
| `vital` | Web Vitals 指标。 |
|
|
140
|
+
| `long_task` | Long Task 或长动画帧。 |
|
|
141
|
+
| `action` | 用户交互或主动上报的 Action。 |
|
|
142
|
+
| `websocket` | WebSocket 生命周期事件。 |
|
|
143
|
+
| `custom` | 主动上报的自定义事件。 |
|
|
144
|
+
|
|
145
|
+
### b. [error](https://opentelemetry.io/docs/specs/semconv/registry/attributes/error/)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
149
|
+
| ------------------------------- | ----------------------------------------------------------- | ------- | ---------- | -------------------------------------------------------------------- |
|
|
150
|
+
| `attributes.error.message` |  | str | 错误信息 | -- |
|
|
151
|
+
| `attributes.error.handled` |  | boolean | 错误是否被捕获 | -- |
|
|
152
|
+
| `attributes.error.source` |  | str | 错误来源 | 枚举值:<br/>- window.error(固定值)<br/>- resource<br/>- unhandledrejection |
|
|
153
|
+
| `attributes.code.column` |  | int | 代码列号 | |
|
|
154
|
+
| `attributes.code.filepath` |  | str | 代码文件路径 | |
|
|
155
|
+
| `attributes.code.lineno` |  | int | 代码行号 | |
|
|
156
|
+
|
|
157
|
+
### c. [browser](https://opentelemetry.io/docs/specs/semconv/registry/attributes/browser/)
|
|
158
|
+
|
|
159
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
160
|
+
| ------------------------------------ | ---------------------------------------------------------- | --- | ------- | ---------------------------- |
|
|
161
|
+
| `attributes.browser.screen.height` |  | int | 屏幕尺寸的高度 | Aegis 使用 `sr = 1728 * 1117`。 |
|
|
162
|
+
| `attributes.browser.screen.width` |  | int | 屏幕尺寸的宽度 | -- |
|
|
163
|
+
| `attributes.browser.viewport.height` |  | int | 视口尺寸的高度 | Aegis 使用 `vp = 576 * 918`。 |
|
|
164
|
+
| `attributes.browser.viewport.width` |  | int | 视口尺寸的宽度 | -- |
|
|
165
|
+
|
|
166
|
+
### d. [device](https://opentelemetry.io/docs/specs/semconv/registry/attributes/device/)
|
|
167
|
+
|
|
168
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
169
|
+
| ---------------------- | ---------------------------------------------------------- | --- | ---- | ----------------------------------------- |
|
|
170
|
+
| `attributes.device.id` |  | str | 设备标识 | 如 `fd136680-a37b-45ea-80ee-365bfdc7f82e`。 |
|
|
171
|
+
|
|
172
|
+
### e. [network](https://opentelemetry.io/docs/specs/semconv/registry/attributes/network/)
|
|
173
|
+
|
|
174
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
175
|
+
| ------------------------------------ | -------------------------------------------------------------- | ---- | ------- | ----------------------------------------------------------- |
|
|
176
|
+
| `attributes.network.connection.type` |  | str | 连接类型 | --<br><br> |
|
|
177
|
+
| `attributes.network.effective_type` |  | str | 有效网络质量 | -- |
|
|
178
|
+
| `attributes.network.status` |  | enum | 网络连接状态 | `connected`、`not_connected`。 |
|
|
179
|
+
| `attributes.network.protocol.name` |  | enum | 应用层网络协议 | 仅 WebSocket Span 上报,固定为 `websocket`;HTTP Resource Span 不上报。 |
|
|
180
|
+
|
|
181
|
+
**[1] `attributes.network.connection.type`**:表示设备当前使用的物理网络连接方式,不一定存在,等同与 DataDog(`connectivity.interfaces`)、Aegis(`netType`)。
|
|
182
|
+
|
|
183
|
+
Aegis 将「连接类型」「网络质量」整合成 `netType`(`wifi`、`wired`、`2G`、`3G`、`5G`、`6G`),不推荐这种做法。
|
|
184
|
+
|
|
185
|
+
| 值 | 描述 | 备注 |
|
|
186
|
+
| --------- | ---------- | ----------------------------------- |
|
|
187
|
+
| `wifi` | Wi-Fi 无线网络 | 仅表示通过 Wi-Fi 连接,不代表网络一定快。 |
|
|
188
|
+
| `cell` | 蜂窝移动网络 | 可能是 2G、3G、4G 或 5G,不表示具体代际。 |
|
|
189
|
+
| `wired` | 有线网络 | 通过网线或有线网卡连接,Aegis 的 `wired` 应映射为该值。 |
|
|
190
|
+
| `unknown` | 未知 | 浏览器不支持、无法识别,或者连接方式不在支持范围内;不表示已经断网。 |
|
|
191
|
+
|
|
192
|
+
**[2] `attributes.network.effective_type`**:表示浏览器根据延迟和下载速度估算出的实际网络质量,等同与 DataDog(`connectivity.effective_type`)、Aegis(`netType`)。
|
|
193
|
+
|
|
194
|
+
| 值 | 描述 | 备注 |
|
|
195
|
+
| --------- | ---- | -------------------------- |
|
|
196
|
+
| `slow-2g` | 极慢网络 | 页面和图片加载非常慢,通常只能满足少量文本传输。 |
|
|
197
|
+
| `2g` | 较慢网络 | 简单页面可以打开,图片、脚本和接口请求可能明显缓慢。 |
|
|
198
|
+
| `3g` | 中等网络 | 普通网页基本可用,但大资源和复杂页面仍可能等待。 |
|
|
199
|
+
| `4g` | 较快网络 | 延迟和带宽表现较好,适合大多数 Web 应用。 |
|
|
200
|
+
|
|
201
|
+
### f. session
|
|
202
|
+
|
|
203
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
204
|
+
| ------------------------------------- | ----------------------------------------------------------- | ------- | -------- | ----------------------------------------------- |
|
|
205
|
+
| `attributes.session.has_replay` |  | boolean | 是否回放 | -- |
|
|
206
|
+
| `attributes.session.id` |  | str | 会话 ID | -- |
|
|
207
|
+
| `attributes.session.type` |  | enum | 会话类型 | 当前固定为 `user`。 |
|
|
208
|
+
| `attributes.session.phase` *[1]* |  | enum | 会话生命周期阶段 | -- |
|
|
209
|
+
|
|
210
|
+
**[1] `attributes.session.phase`**:
|
|
211
|
+
|
|
212
|
+
| 值 | 描述 |
|
|
213
|
+
| ------- | ---------------------- |
|
|
214
|
+
| `start` | 创建首个 Session。 |
|
|
215
|
+
| `rotate` | 旧 Session 到期后创建新 Session。 |
|
|
216
|
+
| `end` | 当前 Session 结束。 |
|
|
217
|
+
|
|
218
|
+
### g. view
|
|
219
|
+
|
|
220
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
221
|
+
| ------------------------------------- | -------------------------------------------------------------- | ------ | ----------------------- | --------------------------------------------- |
|
|
222
|
+
| `attributes.view.id` |  | str | 视图 ID | |
|
|
223
|
+
| `attributes.view.name` |  | str | 视图名称 | 如 `/apm/home`。 |
|
|
224
|
+
| `attributes.view.loading_type` |  | str | 视图加载类型 | -- |
|
|
225
|
+
| `attributes.view.url` |  | str | 视图 URL | 如 `https://example.com/cur`。 |
|
|
226
|
+
| `attributes.view.previous` |  | str | 视图 URL(前一个) | 如 `https://example.com/pre`。 |
|
|
227
|
+
| `attributes.view.referrer` |  | str | 初始来源页面 URL | 仅首次加载且值非空时上报,需进行 URL 脱敏。 |
|
|
228
|
+
| `attributes.view.url_path_group` |  | str | 视图路径分组 | 如 `/apm/home`。 |
|
|
229
|
+
| `attributes.view.loading_time` |  | number | 视图加载耗时(ms) | 加载时间计算完成后上报。 |
|
|
230
|
+
| `attributes.view.loading_time_source` |  | enum | 视图加载耗时来源 | `auto`、`manual`。 |
|
|
231
|
+
| `attributes.view.first_byte` |  | number | 首字节时间(ms) | 仅初始导航存在。 |
|
|
232
|
+
| `attributes.view.dom_interactive` |  | number | DOM 可交互时间(ms) | 仅初始导航存在。 |
|
|
233
|
+
| `attributes.view.dom_content_loaded` |  | number | DOMContentLoaded 时间(ms) | 仅初始导航存在。 |
|
|
234
|
+
| `attributes.view.dom_complete` |  | number | DOM Complete 时间(ms) | 仅初始导航存在。 |
|
|
235
|
+
| `attributes.view.load_event` |  | number | Load Event 时间(ms) | 仅初始导航存在。 |
|
|
236
|
+
| `attributes.view.phase` |  | enum | 视图生命周期阶段 | 枚举值:<br>- start<br>- update<br>- end |
|
|
237
|
+
| `attributes.view.started_at` |  | number | 视图开始时间(ms) | 取 `performance.timeOrigin`。 |
|
|
238
|
+
| `attributes.view.version` |  | int | 视图事件版本号 | 同一 `attributes.view.id` 从 `1` 开始递增,用于排序和幂等合并。 |
|
|
239
|
+
| `attributes.view.end_reason` |  | str | 结束原因 | -- |
|
|
240
|
+
|
|
241
|
+
**[1] `attributes.view.name`**:默认取 `view.url_path_group`,也可由 `startView({ name })` 或 `setViewName` 设置。
|
|
242
|
+
|
|
243
|
+
**[2] `attributes.view.loading_type`**:
|
|
244
|
+
|
|
245
|
+
| 值 | 描述 |
|
|
246
|
+
| ----------------- | --------------- |
|
|
247
|
+
| `initial_load` | 首次页面加载(初始导航) |
|
|
248
|
+
| `route_change` | SPA 路由切换 |
|
|
249
|
+
| `session_renewal` | 会话续期后重建 |
|
|
250
|
+
| `bf_cache` | 从浏览器 BFCache 恢复 |
|
|
251
|
+
|
|
252
|
+
**[3] `attributes.view.url_path_group`**:用于聚合的页面路径,默认只是 URL pathname,不会自动将数字、UUID 替换为 `:id`,需要接入方配置分组逻辑。
|
|
253
|
+
|
|
254
|
+
**[3] `attributes.view.phase`**:当前 View Span 的生命周期阶段,Schema v3 不再用一条长 Span 表达整个 View,而是发送多条瞬时生命周期 Span。
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
```text
|
|
258
|
+
逻辑 View:view.id=view-A
|
|
259
|
+
│
|
|
260
|
+
├── Span #1:version=1,phase=start
|
|
261
|
+
│ │
|
|
262
|
+
│ ├── 上报时机:View 创建
|
|
263
|
+
│ ├── view.loading_time = 不存在
|
|
264
|
+
│ ├── view.first_byte = 120 ← 创建时已可读取
|
|
265
|
+
│ ├── view.dom_interactive = 不存在 ← 此时还是 0
|
|
266
|
+
│ ├── view.dom_content_loaded = 不存在
|
|
267
|
+
│ ├── view.dom_complete = 不存在
|
|
268
|
+
│ └── view.load_event = 不存在
|
|
269
|
+
│
|
|
270
|
+
│ SDK 创建 View 时读取一次 PerformanceNavigationTiming。
|
|
271
|
+
│ 只写入当时已经大于 0 的字段。
|
|
272
|
+
│
|
|
273
|
+
├── Span #2:version=2,phase=update
|
|
274
|
+
│ │
|
|
275
|
+
│ ├── 上报时机:Loading Time 计算完成
|
|
276
|
+
│ ├── view.loading_time = 820
|
|
277
|
+
│ ├── view.first_byte = 120
|
|
278
|
+
│ ├── view.dom_interactive = 350
|
|
279
|
+
│ ├── view.dom_content_loaded = 420
|
|
280
|
+
│ ├── view.dom_complete = 680
|
|
281
|
+
│ └── view.load_event = 700
|
|
282
|
+
│
|
|
283
|
+
│ SDK 等待以下两个条件完成:
|
|
284
|
+
│ ├── loadEventEnd 已产生
|
|
285
|
+
│ └── 页面请求、资源和 DOM 活动结束
|
|
286
|
+
│
|
|
287
|
+
│ 然后重新读取 PerformanceNavigationTiming,
|
|
288
|
+
│ 将六个字段一起放入 update Span。
|
|
289
|
+
│
|
|
290
|
+
└── Span #3:version=3,phase=end
|
|
291
|
+
│
|
|
292
|
+
├── 上报时机:路由切换或页面离开
|
|
293
|
+
├── view.loading_time = 820
|
|
294
|
+
├── view.first_byte = 120
|
|
295
|
+
├── view.dom_interactive = 350
|
|
296
|
+
├── view.dom_content_loaded = 420
|
|
297
|
+
├── view.dom_complete = 680
|
|
298
|
+
└── view.load_event = 700
|
|
299
|
+
|
|
300
|
+
end Span 不会重新计算这些字段,
|
|
301
|
+
只是携带 View 当前的最终属性快照。
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
```text
|
|
306
|
+
时间 ───────────────────────────────────────────────────────────>
|
|
307
|
+
|
|
308
|
+
View A ███████████████████████████████│
|
|
309
|
+
├─ 查询订单 Action
|
|
310
|
+
└──── GET /api/orders ─────────┘
|
|
311
|
+
│ 路由切换
|
|
312
|
+
View B ███████████████████████│
|
|
313
|
+
├─ 查询用户 Action
|
|
314
|
+
└── GET /api/users ────┘
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### h. resource
|
|
318
|
+
|
|
319
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
320
|
+
| -------------------------------------------- | ---------------------------------------------------------- | ------- | ------------------- | ----------------------------------------------------------------------- |
|
|
321
|
+
| `attributes.resource.type` |  | enum | 资源类型 | -- |
|
|
322
|
+
| `attributes.resource.size` |  | int | 资源大小 | -- |
|
|
323
|
+
| `attributes.resource.transfer_size` |  | int | 传输大小 | -- |
|
|
324
|
+
| `attributes.resource.decoded_body_size` |  | int | 解码后正文大小 | -- |
|
|
325
|
+
| `attributes.resource.encoded_body_size` |  | int | 编码后正文大小 | -- |
|
|
326
|
+
| `attributes.resource.protocol` |  | str | 传输协议 | 浏览器提供下一跳协议时存在,如 `h2`、`h3`、`http/1.1`。 |
|
|
327
|
+
| `attributes.resource.cache.hit` |  | boolean | 是否缓存命中 | -- |
|
|
328
|
+
| `attributes.resource.delivery_type` |  | str | 交付类型 | 浏览器提供交付类型时存在,如 `cache`、`navigational-prefetch`、`cache-storage`、`other`。 |
|
|
329
|
+
| `attributes.resource.render_blocking_status` |  | enum | 渲染阻塞状态 | 浏览器提供渲染阻塞状态时存在,枚举值为 `blocking`、`non-blocking` |
|
|
330
|
+
| `attributes.resource.redirect.start` |  | number | 重定向开始时间 | -- |
|
|
331
|
+
| `attributes.resource.redirect.duration` |  | number | 重定向耗时 | -- |
|
|
332
|
+
| `attributes.resource.worker.start` |  | number | Service Worker 开始时间 | -- |
|
|
333
|
+
| `attributes.resource.worker.duration` |  | number | Service Worker 耗时 | -- |
|
|
334
|
+
| `attributes.resource.dns.start` |  | number | DNS 查询开始时间 | -- |
|
|
335
|
+
| `attributes.resource.dns.duration` |  | number | DNS 查询耗时 | -- |
|
|
336
|
+
| `attributes.resource.connect.start` |  | number | 传输连接开始时间 | -- |
|
|
337
|
+
| `attributes.resource.connect.duration` |  | number | 传输连接耗时 | -- |
|
|
338
|
+
| `attributes.resource.ssl.start` |  | number | TLS 握手开始时间 | -- |
|
|
339
|
+
| `attributes.resource.ssl.duration` |  | number | TLS 握手耗时 | -- |
|
|
340
|
+
| `attributes.resource.first_byte.start` |  | number | 首字节阶段开始时间 | -- |
|
|
341
|
+
| `attributes.resource.first_byte.duration` |  | number | 首字节耗时 | -- |
|
|
342
|
+
| `attributes.resource.download.start` |  | number | 下载开始时间 | -- |
|
|
343
|
+
| `attributes.resource.download.duration` |  | number | 下载耗时 | -- |
|
|
344
|
+
|
|
345
|
+
**[1] `attributes.resource.type`**:
|
|
346
|
+
|
|
347
|
+
| 值 | 描述 |
|
|
348
|
+
| ------------------ | -------------------------------------------- |
|
|
349
|
+
| `fetch` | Fetch API 请求。 |
|
|
350
|
+
| `xhr` | XMLHttpRequest 请求。 |
|
|
351
|
+
| `script` | `<script>`、模块或 Worker 加载的脚本资源。 |
|
|
352
|
+
| `link` | `<link>` 加载的资源,如样式表、预加载和预取资源。 |
|
|
353
|
+
| `img` / `image` | HTML 或 SVG 图片元素加载的资源。 |
|
|
354
|
+
| `css` | CSS `url()`、`@import` 等规则加载的资源,不表示 CSS 文件本身。 |
|
|
355
|
+
| `iframe` / `frame` | 内嵌页面加载的文档资源。 |
|
|
356
|
+
| `other` | 浏览器未识别发起方式、`initiatorType` 为空或未单列的其他类型。 |
|
|
357
|
+
| ... | .. |
|
|
358
|
+
|
|
359
|
+
**[2] 单位**:`xx_size` 为 bytes,`duration` & `start` 为毫秒。
|
|
360
|
+
|
|
361
|
+
### i. action
|
|
362
|
+
|
|
363
|
+
| 字段 | 状态 | 类型 | 描述 |
|
|
364
|
+
| ------------------------------------------ | ----------------------------------------------------------- | ------ | ---------------------------- |
|
|
365
|
+
| `attributes.action.id` |  | str | -- |
|
|
366
|
+
| `attributes.action.type` *[1]* |  | str | 动作类型 |
|
|
367
|
+
| `attributes.action.target.name` |  | str | 目标元素名称 |
|
|
368
|
+
| `attributes.action.target.tag` |  | str | 目标元素标签 |
|
|
369
|
+
| `attributes.action.frustration.type` *[2]* |  | str[] | 挫败类型 |
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
**[1] `attributes.action.type`**:
|
|
373
|
+
|
|
374
|
+
| 常见值 | 描述 |
|
|
375
|
+
| -------------------- | ---------------------------------- |
|
|
376
|
+
| `click` | 鼠标或指针设备触发的点击,蓝鲸 Web 自动 Action 当前使用该值。 |
|
|
377
|
+
| `custom` | 通过 SDK API 主动上报的自定义 Action。 |
|
|
378
|
+
| `tap` | 触屏设备上的单次轻触。 |
|
|
379
|
+
| `scroll` | 页面或滚动容器的滚动操作。 |
|
|
380
|
+
| `swipe` | 触屏设备上的滑动手势。 |
|
|
381
|
+
| `application_start` | 应用启动,常用于移动端或桌面端。 |
|
|
382
|
+
| `back` | 返回上一页面或上一导航状态,常用于移动端。 |
|
|
383
|
+
|
|
384
|
+
以上是跨端常见值,不是封闭枚举。蓝鲸 Web 当前产生 `click` 和 `custom`。转换 Aegis 数据时,还可能保留接入方配置的 DOM 事件名。
|
|
385
|
+
|
|
386
|
+
**[2] `attributes.action.frustration.type`**:
|
|
387
|
+
|
|
388
|
+
| 值 | 描述 |
|
|
389
|
+
| ------------- | ------------------------------------------------------------------------------------ |
|
|
390
|
+
| `rage_click` | [a] `1 s` 内对同一 DOM 元素连续点击至少 `3` 次,且相邻点击距离不超过 `100 px`。<br />[b] 滚动或文本选择会中断或撤销判定。 |
|
|
391
|
+
| `dead_click` | [a] 点击后未检测到请求、资源加载、长任务、DOM 变化、打开窗口或错误,也没有输入、滚动或文本选择。<br />[b] 链接、文本输入框等难以可靠判断的目标会排除。 |
|
|
392
|
+
| `error_click` | Action 生命周期内检测到前端错误。 |
|
|
393
|
+
|
|
394
|
+
该字段为数组,同一个 Action 可以同时命中多个值;未命中时不写入。消费端应按集合处理,不依赖数组顺序。这些信号是 SDK 的启发式判断,不等同于业务操作失败。
|
|
395
|
+
|
|
396
|
+
### j. http & [url](https://opentelemetry.io/docs/specs/semconv/registry/attributes/url/) & server
|
|
397
|
+
|
|
398
|
+
| 字段 | 状态 | 类型 | 描述 | |
|
|
399
|
+
| -------------------------------------- | ----------------------------------------------------------- | --- | ------- | ---------------------------- |
|
|
400
|
+
| `attributes.url.full` |  | str | 完整 URL | 如 `https://example.com/apm`。 |
|
|
401
|
+
| `attributes.url.scheme` |  | str | 协议 | 如 `ws`、`wss`。 |
|
|
402
|
+
| `attributes.http.request.method` |  | str | 请求方法 | 如 `GET`、`POST`。 |
|
|
403
|
+
| `attributes.http.response.status_code` |  | int | 返回码 | 如 `200`、`404`。 |
|
|
404
|
+
| `attributes.server.address` |  | str | 地址 | 如 `example.com`。 |
|
|
405
|
+
| `attributes.server.port` |  | int | 端口 | -- |
|
|
406
|
+
|
|
407
|
+
### k. vital
|
|
408
|
+
|
|
409
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
410
|
+
| --------------------------------------------- | ----------------------------------------------------------- | ------ | -------------------- | ---------------------------------------------- |
|
|
411
|
+
| `attributes.vital.id` |  | str | Vital 唯一标识 | |
|
|
412
|
+
| `attributes.vital.metric` |  | enum | 指标名 | |
|
|
413
|
+
| `attributes.vital.value` |  | number | 指标测量值 | |
|
|
414
|
+
| `attributes.vital.inp.input_delay` |  | number | 输入延迟(ms) | 用户发起交互(如点击)到事件处理器开始执行的等待时间,反映主线程繁忙程度 |
|
|
415
|
+
| `attributes.vital.inp.interaction_target` |  | str | 交互目标元素标识 | 如 `div`。 |
|
|
416
|
+
| `attributes.vital.inp.interaction_type` |  | str | 交互类型 | -- |
|
|
417
|
+
| `attributes.vital.inp.processing_duration` |  | number | 处理耗时(ms) | -- |
|
|
418
|
+
| `attributes.vital.inp.presentation_delay` |  | number | 呈现延迟(ms) | -- |
|
|
419
|
+
| `attributes.vital.lcp.target` |  | str | DOM 选择器 | 如 `div`。 |
|
|
420
|
+
| `attributes.vital.lcp.url` |  | str | 元素对应资源 URL(已脱敏) | -- |
|
|
421
|
+
| `attributes.vital.lcp.resource_load_duration` |  | number | 资源加载耗时(ms) | -- |
|
|
422
|
+
| `attributes.vital.lcp.element_render_delay` |  | number | 元素渲染延迟(ms) | -- |
|
|
423
|
+
| `attributes.vital.ttfb.waiting_duration` |  | number | 请求就绪后的等待耗时(ms) | -- |
|
|
424
|
+
| `attributes.vital.ttfb.dns_duration` |  | number | DNS 解析耗时(ms) | -- |
|
|
425
|
+
| `attributes.vital.ttfb.connection_duration` |  | number | TCP + TLS 连接建立耗时(ms) | -- |
|
|
426
|
+
| `attributes.vital.ttfb.request_duration` |  | number | 请求发送后等待首字节耗时(ms) | -- |
|
|
427
|
+
|
|
428
|
+
**[1] `attributes.vital.metric`**:
|
|
429
|
+
|
|
430
|
+
| 值 | 描述 | 备注 |
|
|
431
|
+
| ---- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
432
|
+
| cls | [累积布局偏移(Cumulative Layout Shift)](https://web.dev/articles/cls) | 在整个页面生命周期中,每次出现的意外布局变化所导致的最大布局变化得分的累积值,为了提供良好的用户体验,网站的 CLS 得分应控制在 0.1 或更低。 |
|
|
433
|
+
| inp | [交互到下一次绘制(Interaction to Next Paint)](https://web.dev/articles/inp) | 记录用户与页面进行的所有交互的延迟情况,并给出一个综合评分(通常是 P98,忽略极端值),较低的 INP 值意味着页面能够快速响应所有或绝大多数用户交互,INP 值在用户离开页面时会被计算出来。 |
|
|
434
|
+
| lcp | [最大内容绘制(Largest Contentful Paint, LCP)](https://web.dev/articles/lcp) | Core Web Vital 中的一个重要且稳定的指标,测量从页面开始加载,到视窗中可见的最大图像、文本块或视频的渲染时间,用于衡量页面加载的速度(用户感受:页面主要内容出来了)。 |
|
|
435
|
+
| fcp | [首次内容绘制(First Contentful Paint)](https://web.dev/articles/fcp) | 从用户首次访问页面,到页面第一次显示出任何内容的耗时(用户感受:不是白屏了)。 |
|
|
436
|
+
| ttfb | [首字节时间(Time to First Byte)](https://web.dev/articles/ttfb) | 从用户开始导航到页面到响应首字节开始传输之间所经历的时间。 |
|
|
437
|
+
|
|
438
|
+
**[2] `attributes.vital.value`**:CLS 单位为 `1`,FCP、INP、LCP、TTFB 单位为 `ms`。
|
|
439
|
+
|
|
440
|
+
**[3] `attributes.vital.inp.interaction_type`**:交互类型。
|
|
441
|
+
|
|
442
|
+
| 值 | 描述 |
|
|
443
|
+
| ------------- | ------------- |
|
|
444
|
+
| `keyup` | 松开按键 |
|
|
445
|
+
| `keydown` | 按下按键 |
|
|
446
|
+
| `pointerdown` | 点击(鼠标、触屏、触控笔) |
|
|
447
|
+
| `pointerup` | 松开 |
|
|
448
|
+
|
|
449
|
+
**[4] `attributes.vital.inp.processing_duration`**:事件处理回调(如 click handler)本身的执行时间,JS 逻辑过重时这个值会变大。
|
|
450
|
+
|
|
451
|
+
**[5] `attributes.vital.inp.presentation_delay`**:回调操作完成之后到该帧最终显示在用户屏幕上所需的时间。
|
|
452
|
+
|
|
453
|
+
**[6] `attributes.vital.lcp.element_render_delay`**:LCP 元素资源加载完成后,到浏览器真正渲染该元素之间的等待时间(主要由主线程阻塞(长任务/JS 执行)导致)。
|
|
454
|
+
|
|
455
|
+
**[7] `attributes.vital.lcp.resource_load_duration`**:LCP 元素依赖的外部资源(图片/字体等)从请求到下载完成的时间(如果 LCP 是纯文本节点,此项可能缺失),用于排查 CDN/网络/资源体积问题。
|
|
456
|
+
|
|
457
|
+
**[8] `attributes.vital.ttfb.waiting_duration`**:页面激活到浏览器开始 Fetch,或开始启动 Service Worker 前的时间(包含重定向及浏览器前置处理)。
|
|
458
|
+
|
|
459
|
+
**[9] `attributes.vital.ttfb.dns_duration`**:解析慢通常由 DNS 服务器延迟、复杂 CNAME 链或本地 DNS 缓存失效导致(多国/多地域部署时此值可能偏高)。
|
|
460
|
+
|
|
461
|
+
**[10] `attributes.vital.ttfb.connection_duration`**:TCP / QUIC 建连及 TLS 协商,连接复用时通常为 `0`。
|
|
462
|
+
|
|
463
|
+
**[11] `attributes.vital.ttfb.request_duration`**:建连结束到收到首字节,包含调度空档、请求发送、网络 RTT 和服务端处理。
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
### l. blank_screen
|
|
467
|
+
> _**白屏(Blank Screen)**:非 Web 标准指标。页面可见且活动稳定后,SDK 对指定根元素范围内的视口进行采样;排除加载态样本后,如果空白样本占有效样本的比例达到阈值,并在二次检测中仍然成立,则判定为白屏。_
|
|
468
|
+
|
|
469
|
+
| 字段 | 状态 | 类型 | 描述 | 备注 |
|
|
470
|
+
| ---------------------------------------------- | --------------------------------------------------------------- | ------- | ---------------- | ------------------ |
|
|
471
|
+
| `attributes.blank_screen.reason` *[1]* |  | str | 白屏判定原因 | |
|
|
472
|
+
| `attributes.blank_screen.empty_ratio` |  | number | 有效样本中的空白比例 | |
|
|
473
|
+
| `attributes.blank_screen.empty_sample_count` |  | int | 空白采样数 | |
|
|
474
|
+
|
|
475
|
+
**[1] `attributes.blank_screen.reason`**:
|
|
476
|
+
|
|
477
|
+
| 值 | 描述 |
|
|
478
|
+
| ---------------- | --------------------------------------------------------------------------------------- |
|
|
479
|
+
| `empty_viewport` | 配置的采样根元素存在,有效采样点的空白比例达到白屏阈值。 |
|
|
480
|
+
| `missing_root` | 未找到配置的采样根元素,SDK 回退到 `body`(不可用时使用 `documentElement`)检测,且回退检测仍达到白屏阈值。 |
|
|
481
|
+
|
|
482
|
+
### m. longtask
|
|
483
|
+
|
|
484
|
+
| 字段 | 状态 | 类型 | 描述 |
|
|
485
|
+
| ----------------------------------------------- | --------------------------------------------------------------- | ------ | -------------------- |
|
|
486
|
+
| `attributes.long_task.id` |  | str | 长任务或长动画帧 ID |
|
|
487
|
+
| `attributes.long_task.name` |  | str | Performance Entry 名称 |
|
|
488
|
+
| `attributes.long_task.entry_type` *[1]* |  | str | 采集条目类型 |
|
|
489
|
+
| `attributes.long_task.blocking_duration` |  | number | 主线程阻塞耗时(ms) |
|
|
490
|
+
| `attributes.long_task.first_ui_event_timestamp` |  | number | 首个 UI 事件时间(ms) |
|
|
491
|
+
| `attributes.long_task.render_start` |  | number | 渲染阶段开始时间(ms) |
|
|
492
|
+
| `attributes.long_task.style_and_layout_start` |  | number | 样式与布局阶段开始时间(ms) |
|
|
493
|
+
|
|
494
|
+
**[1] `attributes.long_task.entry_type`**:
|
|
495
|
+
|
|
496
|
+
| 值 | 描述 |
|
|
497
|
+
| ------------------------ | ------------------------------------------------------------------- |
|
|
498
|
+
| `long-animation-frame` | 通过 Long Animation Frame API 采集,包含主线程阻塞、渲染、样式与布局阶段以及脚本归因信息。 |
|
|
499
|
+
| `long-task` | 通过 Long Tasks API 采集,用于不支持 Long Animation Frame API 的浏览器,只提供长任务基础信息。 |
|
|
500
|
+
|
|
501
|
+
### n. custom
|
|
502
|
+
|
|
503
|
+
`reportCustomEvent()` 产生 `custom.<name>` Span。
|