@blueking/open-telemetry 0.0.22 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +256 -70
- package/dist/bk-rum.global.js +2 -2
- package/dist/bk-rum.global.js.map +1 -1
- package/dist/core/config.d.ts +4 -2
- package/dist/core/processor.d.ts +2 -2
- package/dist/core/runtime-context.d.ts +4 -0
- package/dist/core/sampling.d.ts +0 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +395 -477
- package/dist/index.js.map +1 -1
- package/dist/plugins/blank-screen.d.ts +1 -1
- package/dist/plugins/common.d.ts +3 -4
- package/dist/plugins/web-vitals.d.ts +0 -5
- package/dist/schema/attributes.d.ts +6 -8
- package/dist/schema/span.d.ts +24 -15
- package/package.json +1 -1
- package/skills/bk-rum-otele/SKILL.md +26 -23
- package/skills/bk-rum-otele/references/actions.md +166 -0
- package/skills/bk-rum-otele/references/api.md +248 -215
- package/skills/bk-rum-otele/references/architecture.md +139 -37
- package/skills/bk-rum-otele/references/blank-screen.md +190 -0
- package/skills/bk-rum-otele/references/capabilities.md +175 -83
- package/skills/bk-rum-otele/references/configuration.md +226 -151
- package/skills/bk-rum-otele/references/data-model.md +156 -24
- package/skills/bk-rum-otele/references/errors-security.md +168 -0
- package/skills/bk-rum-otele/references/extensions.md +236 -0
- package/skills/bk-rum-otele/references/framework-integration.md +318 -75
- package/skills/bk-rum-otele/references/getting-started.md +186 -70
- package/skills/bk-rum-otele/references/network.md +258 -0
- package/skills/bk-rum-otele/references/performance.md +197 -0
- package/skills/bk-rum-otele/references/privacy.md +236 -67
- package/skills/bk-rum-otele/references/production.md +264 -0
- package/skills/bk-rum-otele/references/session-context.md +185 -0
- package/skills/bk-rum-otele/references/telemetry-reference.md +479 -51
- package/skills/bk-rum-otele/references/transport-sampling.md +318 -32
- package/skills/bk-rum-otele/references/troubleshooting.md +341 -151
- package/skills/bk-rum-otele/references/views-routing.md +211 -0
- package/skills/bk-rum-otele/references/concepts.md +0 -60
- package/skills/bk-rum-otele/references/custom-plugin.md +0 -170
- package/skills/bk-rum-otele/references/plugins-basic.md +0 -135
- package/skills/bk-rum-otele/references/plugins-error-security.md +0 -83
- package/skills/bk-rum-otele/references/plugins-experience.md +0 -124
- package/skills/bk-rum-otele/references/plugins-network.md +0 -32
- package/skills/bk-rum-otele/references/plugins.md +0 -62
|
@@ -2,245 +2,435 @@
|
|
|
2
2
|
|
|
3
3
|
# 调试与排障
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
排障建议从“有没有创建有效 Session/View”开始,再看 Span 过滤、批处理和网络出口。只盯 `/v1/rum` 请求很容易把采样、Consent 或关联问题误判成 Collector 故障。
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 最小诊断配置
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
在测试环境临时使用:
|
|
10
10
|
|
|
11
11
|
```ts
|
|
12
|
-
new BkOpenTelemetry({
|
|
12
|
+
const rum = new BkOpenTelemetry({
|
|
13
13
|
application: { name: 'rum-debug' },
|
|
14
|
-
debug: true,
|
|
15
|
-
session: {
|
|
16
|
-
sampleRate: 1,
|
|
17
|
-
},
|
|
18
14
|
transport: {
|
|
19
|
-
endpoint: '
|
|
15
|
+
endpoint: 'https://rum.example.com',
|
|
20
16
|
processor: 'simple',
|
|
21
17
|
},
|
|
18
|
+
session: { sampleRate: 1 },
|
|
19
|
+
debug: true,
|
|
20
|
+
autoStart: false,
|
|
22
21
|
});
|
|
22
|
+
|
|
23
|
+
await rum.start();
|
|
23
24
|
```
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
这个配置的目的:
|
|
27
|
+
|
|
28
|
+
- 采样率 1 排除“Session 未命中”;
|
|
29
|
+
- simple 排除 5 秒批量等待;
|
|
30
|
+
- `debug: true` 在 exporter 前打印 Span,也显示插件初始化和部分丢弃警告;
|
|
31
|
+
- 显式 `await start()` 让启动错误可以被捕获。
|
|
26
32
|
|
|
27
|
-
|
|
28
|
-
- 浏览器 Network 中是否有 `/v1/rum` 请求。
|
|
29
|
-
- 是否被采样丢弃。
|
|
30
|
-
- `enabled` 是否为 `false`。
|
|
33
|
+
生产问题确认后应恢复 batch,避免逐 Span 请求。
|
|
31
34
|
|
|
32
|
-
##
|
|
35
|
+
## 分层定位流程
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
### 1. 确认实例和配置
|
|
35
38
|
|
|
36
39
|
```ts
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
debug: true,
|
|
40
|
-
session: {
|
|
41
|
-
sampleRate: 1,
|
|
42
|
-
},
|
|
43
|
-
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
44
|
-
});
|
|
40
|
+
console.log(rum.config.application);
|
|
41
|
+
console.log(rum.config.transport.endpoint); // 应以 /v1/rum 结尾
|
|
45
42
|
```
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
检查:
|
|
48
45
|
|
|
49
|
-
|
|
46
|
+
- `application.name` 非空;
|
|
47
|
+
- `transport.endpoint` 非空且没有把 `/v1/rum` 手工写两次;
|
|
48
|
+
- 页面只创建了一个实例;
|
|
49
|
+
- 没有 `enabled: false`;
|
|
50
|
+
- 当前实例没有已经 `shutdown()`。
|
|
51
|
+
|
|
52
|
+
### 2. 确认 Consent 与启动
|
|
50
53
|
|
|
51
54
|
```ts
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
56
|
-
});
|
|
55
|
+
console.log(rum.config.trackingConsent);
|
|
56
|
+
await rum.start();
|
|
57
|
+
```
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
`not-granted` 不会安装采集插件。授权后必须调用:
|
|
59
60
|
|
|
60
|
-
|
|
61
|
+
```ts
|
|
62
|
+
await rum.setTrackingConsent('granted');
|
|
61
63
|
```
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
如果使用 `autoStart: true`,构造后立刻调用 `use()` 会抛错;扩展注册请改为 `autoStart: false`。自动启动没有单独暴露 ready Promise,构造后立即同步调用手动事件也不会排队,可能因为 View 尚未建立而被过滤。必须保证首个手动事件不丢时,应使用 `autoStart: false` 并显式 `await rum.start()`。
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
### 3. 确认 Session/View/采样
|
|
66
68
|
|
|
67
69
|
```ts
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
rootSelector: '#app',
|
|
74
|
-
ignoreSelectors: ['.bk-loading', '.skeleton'],
|
|
75
|
-
checkDelay: 5000,
|
|
76
|
-
},
|
|
77
|
-
},
|
|
70
|
+
console.table(rum.getRuntimeAttributes());
|
|
71
|
+
console.log({
|
|
72
|
+
sampled: rum.isSampled(),
|
|
73
|
+
session: rum.isSessionActive(),
|
|
74
|
+
view: rum.isViewActive(),
|
|
78
75
|
});
|
|
79
76
|
```
|
|
80
77
|
|
|
81
|
-
|
|
78
|
+
普通 Span 导出的必要条件:
|
|
79
|
+
|
|
80
|
+
- `isSampled() === true`;
|
|
81
|
+
- 有 `session.id`;
|
|
82
|
+
- 有 `view.id`。
|
|
82
83
|
|
|
83
|
-
|
|
84
|
+
`browser.session` 是唯一可以没有 `view.id` 的内置 Span。
|
|
85
|
+
|
|
86
|
+
manual View 模式下,必须在 Session 建立后调用 `startView()`:
|
|
84
87
|
|
|
85
88
|
```ts
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
89
|
-
tracking: {
|
|
90
|
-
request: {
|
|
91
|
-
excludedUrls: [/\/health(?:\?|$)/, /\/polling\//],
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
});
|
|
89
|
+
await rum.start();
|
|
90
|
+
rum.startView({ name: '首页' });
|
|
95
91
|
```
|
|
96
92
|
|
|
97
|
-
|
|
93
|
+
### 4. 确认 Span 到达 exporter
|
|
98
94
|
|
|
99
|
-
|
|
95
|
+
`debug: true` 会打印:
|
|
100
96
|
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
application: { name: 'rum-debug' },
|
|
104
|
-
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
105
|
-
privacy: {
|
|
106
|
-
redactUrl: url => url.replace(/([?&]token=)[^&]+/g, '$1***'),
|
|
107
|
-
redactAttributes: attributes => {
|
|
108
|
-
const next = { ...attributes };
|
|
109
|
-
delete next['user.email'];
|
|
110
|
-
return next;
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
});
|
|
97
|
+
```text
|
|
98
|
+
[bk-ot][rum] [...ReadableSpan]
|
|
114
99
|
```
|
|
115
100
|
|
|
116
|
-
|
|
101
|
+
如果能看到 Span、看不到网络请求,重点检查 exporter、并发、页面退出和浏览器拦截。如果完全看不到 Span,重点检查 capability 开关、浏览器 API 支持、Session/View/采样和 beforeSend。
|
|
102
|
+
|
|
103
|
+
### 5. 确认网络和 Collector
|
|
104
|
+
|
|
105
|
+
Network 面板过滤 `v1/rum`,检查:
|
|
106
|
+
|
|
107
|
+
- URL、POST、请求体和 `Content-Type`;
|
|
108
|
+
- OPTIONS 预检;
|
|
109
|
+
- `Authorization` 和自定义 header;
|
|
110
|
+
- response status;
|
|
111
|
+
- Console 中 CORS、Mixed Content、CSP、ad blocker 错误;
|
|
112
|
+
- 响应是否真的是 2xx,而非页面网关返回的 30x/HTML。
|
|
117
113
|
|
|
118
|
-
|
|
114
|
+
## 完全没有 `/v1/rum` 请求
|
|
115
|
+
|
|
116
|
+
常见原因与证据:
|
|
117
|
+
|
|
118
|
+
| 原因 | 怎么确认 | 处理 |
|
|
119
|
+
| --- | --- | --- |
|
|
120
|
+
| batch 正在等待 | 调用 `await rum.flush()` | 联调临时 simple;生产保留 batch |
|
|
121
|
+
| 未命中采样 | `rum.isSampled() === false` | 测试环境设 `sampleRate: 1` |
|
|
122
|
+
| 未授权 | `rum.config.trackingConsent` | 授权后调用 `setTrackingConsent('granted')` |
|
|
123
|
+
| 没有 View | `rum.isViewActive() === false` | manual 模式调用 `startView()`;检查 View 插件 |
|
|
124
|
+
| SDK 未启动 | 显式 `await rum.start()` | 捕获启动异常 |
|
|
125
|
+
| 全部被 Hook 丢弃 | 暂时移除两个 beforeSend | 修正返回条件 |
|
|
126
|
+
| 页面没有产生结束 Span | 手动 `reportCustomEvent()` 后 flush | 再定位具体插件 |
|
|
127
|
+
| endpoint 被浏览器阻止 | Console/Network | 修复 HTTPS、CSP、CORS、扩展拦截 |
|
|
128
|
+
|
|
129
|
+
最小探针:
|
|
119
130
|
|
|
120
131
|
```ts
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
124
|
-
tracking: {
|
|
125
|
-
longTask: {
|
|
126
|
-
threshold: 50,
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
});
|
|
132
|
+
rum.reportCustomEvent({ name: 'rum_probe' });
|
|
133
|
+
await rum.flush();
|
|
130
134
|
```
|
|
131
135
|
|
|
132
|
-
|
|
136
|
+
若 `isSampled/session/view` 都为 true,探针仍无 exporter 日志,检查 `tracking.beforeSend` 是否返回 false。
|
|
137
|
+
|
|
138
|
+
## 有 debug Span,但请求失败
|
|
139
|
+
|
|
140
|
+
### CORS
|
|
133
141
|
|
|
134
|
-
|
|
142
|
+
典型表现:OPTIONS 失败、`TypeError: Failed to fetch`、响应在 DevTools 中不可读。
|
|
135
143
|
|
|
136
|
-
|
|
144
|
+
Collector 需要允许页面 origin、POST/OPTIONS 和实际 header。使用 token 时必须允许 `authorization`;自定义 header 也要列入 allow headers。
|
|
137
145
|
|
|
138
|
-
|
|
146
|
+
### URL 错误
|
|
147
|
+
|
|
148
|
+
SDK固定追加 `/v1/rum`。如果配置:
|
|
139
149
|
|
|
140
150
|
```ts
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
endpoint: 'https://rum.example.com/v1/rum'
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
最终是:
|
|
155
|
+
|
|
156
|
+
```text
|
|
157
|
+
https://rum.example.com/v1/rum/v1/rum
|
|
148
158
|
```
|
|
149
159
|
|
|
150
|
-
|
|
160
|
+
应传上报根地址。
|
|
151
161
|
|
|
152
|
-
|
|
162
|
+
### 401/403
|
|
153
163
|
|
|
154
|
-
|
|
164
|
+
检查:
|
|
165
|
+
|
|
166
|
+
- token 是否过期、是否误含 `Bearer ` 前缀;SDK 会自行添加;
|
|
167
|
+
- `headers.Authorization` 是否覆盖了 token 生成的 header;
|
|
168
|
+
- Collector 是否允许浏览器凭证和当前应用/租户;
|
|
169
|
+
- 预检是否允许 Authorization。
|
|
170
|
+
|
|
171
|
+
### 404/405
|
|
172
|
+
|
|
173
|
+
Collector 没有暴露 SDK 约定的 `/v1/rum` POST,或网关路径重写不一致。不要把它改成 `/v1/traces` 除非网关明确把 `/v1/rum` 转发到对应处理器。
|
|
174
|
+
|
|
175
|
+
### 413
|
|
176
|
+
|
|
177
|
+
批量 body 超过网关限制。降低 `maxExportBatchSize`,并确认 Collector body limit。队列大小影响内存与丢弃,不直接限定单个 body 字节数。
|
|
178
|
+
|
|
179
|
+
### 429/502/503/504
|
|
180
|
+
|
|
181
|
+
当前 exporter 会在总体 `timeoutMillis` 内重试,支持 `Retry-After`。持续失败时:
|
|
182
|
+
|
|
183
|
+
- 修复 Collector 容量或限流;
|
|
184
|
+
- 适当降低采样率;
|
|
185
|
+
- 避免同时开启高成本/高事件量能力;
|
|
186
|
+
- 不要仅无限增大客户端 queue 和 timeout。
|
|
187
|
+
|
|
188
|
+
## 手动事件不上报
|
|
189
|
+
|
|
190
|
+
按以下顺序完整排查,不要只检查事件 payload。
|
|
191
|
+
|
|
192
|
+
### 1. 启动与 Consent
|
|
155
193
|
|
|
156
194
|
```ts
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
tracking: {
|
|
161
|
-
action: true,
|
|
162
|
-
longTask: true,
|
|
163
|
-
websocket: true,
|
|
164
|
-
},
|
|
195
|
+
console.log({
|
|
196
|
+
enabled: rum.config.enabled,
|
|
197
|
+
consent: rum.config.trackingConsent,
|
|
165
198
|
});
|
|
166
199
|
```
|
|
167
200
|
|
|
168
|
-
|
|
201
|
+
- `enabled` 必须为 true;
|
|
202
|
+
- Consent 必须为 `granted`;
|
|
203
|
+
- 实例不能已经 shutdown;
|
|
204
|
+
- 默认 autoStart 是异步的,手动事件不会在启动完成前排队。需要确定时序时改用:
|
|
169
205
|
|
|
170
|
-
|
|
206
|
+
```ts
|
|
207
|
+
const rum = new BkOpenTelemetry({
|
|
208
|
+
application: { name: 'rum-debug' },
|
|
209
|
+
transport: { endpoint: 'https://rum.example.com' },
|
|
210
|
+
autoStart: false,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
await rum.start();
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 2. Session、采样和 View
|
|
171
217
|
|
|
172
218
|
```ts
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
user: {
|
|
178
|
-
id: hashUserId(rawUserId),
|
|
179
|
-
},
|
|
180
|
-
},
|
|
219
|
+
console.log({
|
|
220
|
+
sampled: rum.isSampled(),
|
|
221
|
+
session: rum.isSessionActive(),
|
|
222
|
+
view: rum.isViewActive(),
|
|
181
223
|
});
|
|
182
224
|
```
|
|
183
225
|
|
|
184
|
-
|
|
226
|
+
三者对普通手动事件都应为 true。`reportAction()` 和 `reportCustomEvent()` 未采样时直接返回;manual View 未建立时,即使创建 Span 也会在过滤层因缺少 `view.id` 被丢弃。manual 模式应在 `await rum.start()` 后调用一次当前路由的 `startView()`。
|
|
227
|
+
|
|
228
|
+
### 3. Payload 和 Hook
|
|
185
229
|
|
|
186
|
-
|
|
230
|
+
- `name` 类型必须是 string,并建议使用非空、低基数枚举;
|
|
231
|
+
- 当前运行时不拒绝空字符串:`reportCustomEvent({ name: '' })` 会尝试生成名为 `custom.` 的 Span,`reportAction({ name: '' })` 会生成空的 `action.name`,都不会仅因空 name 抛错或丢弃,但数据不可用,不应依赖该行为;
|
|
232
|
+
- attributes 只能使用合法 OTel Attribute 类型;
|
|
233
|
+
- `context.attributes.page/custom` 与 `privacy.redactAttributes` 不应抛错;
|
|
234
|
+
- `tracking.beforeSend` 不能按 name 返回 false;Custom Event 不经过请求级 `request.beforeSend`。
|
|
235
|
+
|
|
236
|
+
### 4. 强制结束 batch 并观察 exporter
|
|
187
237
|
|
|
188
238
|
```ts
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
192
|
-
session: {
|
|
193
|
-
sampleRate: 0.2,
|
|
194
|
-
},
|
|
195
|
-
});
|
|
239
|
+
rum.reportCustomEvent({ name: 'rum_probe' });
|
|
240
|
+
await rum.flush();
|
|
196
241
|
```
|
|
197
242
|
|
|
198
|
-
|
|
243
|
+
临时启用 `debug: true` 并使用 `transport.processor: 'simple'`。若控制台存在 `[bk-ot][rum]` Span 而 Network 没有成功请求,事件创建和过滤已经通过,应转查 exporter/CORS;若没有 debug Span,继续检查前述上下文和 Hook。
|
|
244
|
+
|
|
245
|
+
### 5. 网络与 Collector
|
|
246
|
+
|
|
247
|
+
- URL 是 `<endpoint>/v1/rum`,未重复追加路径;
|
|
248
|
+
- OPTIONS/POST、Content-Type、鉴权和自定义 Header 的 CORS 正确;
|
|
249
|
+
- 返回 2xx,而不是 30x、HTML 错误页或可重试失败;
|
|
250
|
+
- 没有 Mixed Content、CSP、广告拦截器、超时或并发队列问题。
|
|
251
|
+
|
|
252
|
+
如果探针成功、业务事件失败,再比较两者的 name、attributes 和业务 Hook 分支;如果探针也失败,按本页开头的分层流程继续检查通用出口。
|
|
253
|
+
|
|
254
|
+
## Fetch/XHR 没有 Span
|
|
255
|
+
|
|
256
|
+
1. `tracking.request !== false`;
|
|
257
|
+
2. URL 没命中 `excludedUrls`;
|
|
258
|
+
3. `request.beforeSend` 没返回 false;
|
|
259
|
+
4. 请求是 SDK 启动之后发生;
|
|
260
|
+
5. 页面没有第二个实例/第三方库反复覆盖 `fetch` 或 XHR prototype;
|
|
261
|
+
6. SDK 自身 `/v1/rum` 请求会被有意排除;
|
|
262
|
+
7. Span 有 Session/View 并命中采样。
|
|
263
|
+
|
|
264
|
+
`resource.*` 网络阶段缺失不代表请求 Span 丢失。跨域没有 `Timing-Allow-Origin`、浏览器清理 buffer、匹配等待超过 200ms 都可能只保留基础 Fetch/XHR 属性。
|
|
199
265
|
|
|
200
|
-
|
|
266
|
+
## `traceparent` 没有注入
|
|
267
|
+
|
|
268
|
+
这是默认行为。只有 URL 明确命中 `allowedTracingUrls` 才注入,同源也不会自动注入:
|
|
201
269
|
|
|
202
270
|
```ts
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
'biz.scene': 'strategy-create',
|
|
271
|
+
tracking: {
|
|
272
|
+
request: {
|
|
273
|
+
allowedTracingUrls: ['https://api.example.com/'],
|
|
207
274
|
},
|
|
208
|
-
}
|
|
275
|
+
}
|
|
209
276
|
```
|
|
210
277
|
|
|
211
|
-
|
|
278
|
+
跨域还需要服务端 CORS 允许请求头 `traceparent`。如果预检失败,缩小白名单并修复 API 服务的 CORS;不要把所有第三方 URL 加入白名单。
|
|
279
|
+
|
|
280
|
+
## 请求 Span 太多或 View loading 一直不结束
|
|
212
281
|
|
|
213
|
-
|
|
282
|
+
使用两个不同的排除入口:
|
|
214
283
|
|
|
215
284
|
```ts
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
285
|
+
tracking: {
|
|
286
|
+
request: {
|
|
287
|
+
excludedUrls: [/\/rum-noise/],
|
|
288
|
+
},
|
|
289
|
+
view: {
|
|
290
|
+
excludedActivityUrls: [/\/events\/stream/, /\/long-poll/],
|
|
291
|
+
},
|
|
292
|
+
}
|
|
220
293
|
```
|
|
221
294
|
|
|
222
|
-
|
|
295
|
+
- `request.excludedUrls`:完全不采集、不传播、不计活动;
|
|
296
|
+
- `view.excludedActivityUrls`:请求仍可采集,但不延长 View loading time。
|
|
297
|
+
|
|
298
|
+
长轮询、SSE fetch、埋点和永不结束的流式请求通常应配置第二项。
|
|
299
|
+
|
|
300
|
+
## 静态资源字段不完整
|
|
301
|
+
|
|
302
|
+
常见原因:
|
|
303
|
+
|
|
304
|
+
- 浏览器不提供新字段;
|
|
305
|
+
- 跨域资源没有 `Timing-Allow-Origin`,大小和详细时序被限制;
|
|
306
|
+
- Service Worker/cache 让某些阶段为 0;
|
|
307
|
+
- Resource Timing buffer 已满;
|
|
308
|
+
- 条目时间顺序异常,SDK 会省略无效阶段而不是上报负值。
|
|
309
|
+
|
|
310
|
+
先判断 `browser.resource` 是否存在,再判断单个可选字段,不要把“字段缺失”当成“插件未工作”。
|
|
311
|
+
|
|
312
|
+
## Web Vitals 缺失或值不同
|
|
313
|
+
|
|
314
|
+
- 指标依赖浏览器支持和页面生命周期,不保证每个 View 都有五项;
|
|
315
|
+
- LCP/CLS 等在隐藏或 View 结束时定稿;
|
|
316
|
+
- INP 需要真实 interaction;没有交互时可缺失;
|
|
317
|
+
- SPA 每个 View 的聚合边界由 SDK 维护,与只计算整页一次的工具可能不同;
|
|
318
|
+
- BFCache 会创建新的 View loading type;
|
|
319
|
+
- attribution 字段比核心 value 更依赖浏览器能力。
|
|
223
320
|
|
|
224
|
-
|
|
321
|
+
不要用刷新后立刻查看网络来断言缺失;先触发交互、切换可见性或调用 `flush()`。
|
|
225
322
|
|
|
226
|
-
|
|
323
|
+
## Action 名称不符合预期
|
|
324
|
+
|
|
325
|
+
默认 `nameCollection: 'explicit'`:
|
|
326
|
+
|
|
327
|
+
1. 从点击元素和祖先读取 `data-bk-action-name`;
|
|
328
|
+
2. 没有显式名称时使用元素标签名;
|
|
329
|
+
3. 不读取按钮可见文字。
|
|
330
|
+
|
|
331
|
+
推荐补 `data-bk-action-name`。只有确实接受文本隐私风险时才设置 `nameCollection: 'text'`。
|
|
332
|
+
|
|
333
|
+
如果没有 Action:确认点击是主按钮、Action 开启、Session/View 有效,并检查页面是否有覆盖层/Shadow DOM 目标。SDK 最多向上检查 10 层父节点进行部分命名和可交互判断。
|
|
334
|
+
|
|
335
|
+
## Rage/Dead/Error Click 不符合预期
|
|
336
|
+
|
|
337
|
+
- Rage click:1 秒内至少 3 次、位置距离不超过 100px 的点击链;报告会等待连击窗口;
|
|
338
|
+
- Error click:Action 生命周期内捕获到错误活动;
|
|
339
|
+
- Dead click:点击后没有被认为有效的请求、DOM、导航、错误等副作用,并排除输入/选择/滚动等情况;
|
|
340
|
+
- Action 最长默认 10 秒,页面活动安静后还需短暂确认。
|
|
341
|
+
|
|
342
|
+
这些是启发式信号,不是业务失败结论。服务端应保留原始 frustration type,结合 View/资源/错误分析。
|
|
343
|
+
|
|
344
|
+
## 白屏误报
|
|
345
|
+
|
|
346
|
+
按顺序检查:
|
|
347
|
+
|
|
348
|
+
1. `rootSelector` 是否指向实际应用根节点;
|
|
349
|
+
2. 页面是否用 Canvas/WebGL/iframe 等九点 DOM 采样难以识别的渲染方式;
|
|
350
|
+
3. 骨架屏/加载层是否被错误忽略;
|
|
351
|
+
4. 页面布局的主要内容是否避开了九个采样点;
|
|
352
|
+
5. `checkDelay` 是否覆盖真实异步渲染时间;
|
|
353
|
+
6. `threshold` 是否过低。
|
|
227
354
|
|
|
228
355
|
```ts
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
356
|
+
tracking: {
|
|
357
|
+
blankScreen: {
|
|
358
|
+
rootSelector: '#app',
|
|
359
|
+
checkDelay: 2000,
|
|
360
|
+
confirmationDelay: 300,
|
|
361
|
+
threshold: 0.9,
|
|
362
|
+
ignoreSelectors: ['.my-skeleton'],
|
|
363
|
+
},
|
|
236
364
|
}
|
|
237
365
|
```
|
|
238
366
|
|
|
239
|
-
|
|
367
|
+
根节点暂时不存在会被判断为 `missing_root` 候选。每个 View 最多上报一次,修改配置后要创建新 View 才能重新验证。
|
|
240
368
|
|
|
241
|
-
|
|
369
|
+
## Long Task 没数据
|
|
242
370
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
371
|
+
- 默认关闭,需要 `tracking.longTask: true`;
|
|
372
|
+
- 需要 `PerformanceObserver`;
|
|
373
|
+
- 优先 `long-animation-frame`,否则回退 `longtask`;
|
|
374
|
+
- entry duration 必须达到 threshold;
|
|
375
|
+
- 浏览器可能只支持基础 Long Task,没有脚本归因;
|
|
376
|
+
- 页面后台、跨域 iframe 与浏览器实现会限制 attribution。
|
|
377
|
+
|
|
378
|
+
## CSP 没数据
|
|
379
|
+
|
|
380
|
+
- 默认关闭,需要 `tracking.cspViolation: true`;
|
|
381
|
+
- SDK 只能接收页面派发的 `securitypolicyviolation` 事件;
|
|
382
|
+
- Collector 自身被 CSP `connect-src` 阻止时,CSP Span 也无法上报;
|
|
383
|
+
- Report-Only 和强制策略的浏览器行为要用真实浏览器验证;
|
|
384
|
+
- `original_policy` 等字段可能被 `redactAttributes` 删除。
|
|
385
|
+
|
|
386
|
+
## WebSocket 没数据
|
|
387
|
+
|
|
388
|
+
- 默认关闭,需要 `tracking.websocket: true`;
|
|
389
|
+
- 只记录 connect/open/error/close 生命周期,不记录 message;
|
|
390
|
+
- SDK 启动前已经创建的连接无法追溯;
|
|
391
|
+
- 多实例或其他库重复 patch WebSocket 会造成冲突;
|
|
392
|
+
- 连接未关闭时,最终 close Span 需要等事件或 shutdown 逻辑,不能只看刚创建后的网络。
|
|
393
|
+
|
|
394
|
+
## View 重复、缺失或基数过高
|
|
395
|
+
|
|
396
|
+
- query-only 变化不会新建自动 View;
|
|
397
|
+
- pathname 或非纯锚点 hash 变化会触发;
|
|
398
|
+
- Router 同时手动 `startView()` 且使用 auto 会重复;
|
|
399
|
+
- 微前端多个实例会重复;
|
|
400
|
+
- `getPathGroup` 默认仅返回 pathname,不会自动识别 `/orders/123` 动态 ID;
|
|
401
|
+
- `setViewName()` 是改名,不创建新 View;
|
|
402
|
+
- Session 续期和 BFCache 恢复会创建具有特定 loading type 的 View。
|
|
403
|
+
|
|
404
|
+
选择 auto 或 manual 一种边界来源,并配置低基数 path group。
|
|
405
|
+
|
|
406
|
+
## 队列丢数据
|
|
407
|
+
|
|
408
|
+
Batch queue 默认 2048。高事件量页面同时开启 Resource、Long Task、CSP、WebSocket 等能力时可能塞满。表现通常是 debug/OTel diag 中 dropped warning,而不是业务异常。
|
|
409
|
+
|
|
410
|
+
处理优先级:
|
|
411
|
+
|
|
412
|
+
1. 降低 `session.sampleRate`;
|
|
413
|
+
2. 关闭不需要的高量能力;
|
|
414
|
+
3. 排除噪声 URL/活动;
|
|
415
|
+
4. 确认 Collector 性能和网络成功率;
|
|
416
|
+
5. 再评估 queue/batch 大小,避免只增加浏览器内存。
|
|
417
|
+
|
|
418
|
+
## 插件初始化失败
|
|
419
|
+
|
|
420
|
+
PluginManager 会隔离单个插件异常:失败插件不进入 started 列表,其余插件继续。设置 `debug: true` 查看:
|
|
421
|
+
|
|
422
|
+
```text
|
|
423
|
+
[bk-ot] plugin "<name>" init failed
|
|
246
424
|
```
|
|
425
|
+
|
|
426
|
+
自定义插件应在 init 失败前自行清理已经安装的部分监听;因为 init 抛错后 PluginManager 不会为该插件调用 shutdown。
|
|
427
|
+
|
|
428
|
+
## 提交问题时应附带
|
|
429
|
+
|
|
430
|
+
- SDK 版本、浏览器版本、框架/路由模式;
|
|
431
|
+
- 精简后的构造配置(删除 token 和敏感字段);
|
|
432
|
+
- `isSampled/isSessionActive/isViewActive` 结果;
|
|
433
|
+
- `/v1/rum` 请求 URL、status、CORS 信息;
|
|
434
|
+
- debug 模式的 Span name 和关键属性,不要粘贴敏感完整 body;
|
|
435
|
+
- 是否多实例、微前端、Service Worker、代理或浏览器扩展;
|
|
436
|
+
- 最小复现步骤以及预期/实际 Span 名。
|