@blueking/open-telemetry 0.0.20 → 0.0.21
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 +2 -2
- package/dist/bk-rum.global.js.map +1 -1
- package/dist/index.js +37 -29
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/skills/bk-rum-otele/SKILL.md +6 -2
- package/skills/bk-rum-otele/references/plugins-basic.md +135 -0
- package/skills/bk-rum-otele/references/plugins-error-security.md +86 -0
- package/skills/bk-rum-otele/references/plugins-experience.md +125 -0
- package/skills/bk-rum-otele/references/plugins-network.md +141 -0
- package/skills/bk-rum-otele/references/plugins.md +0 -483
- package/skills/bk-rum-otele/references/telemetry-reference.md +60 -24
|
@@ -60,486 +60,3 @@ new BkOpenTelemetry({
|
|
|
60
60
|
- 需要为请求增加业务字段或过滤请求:配置 `request.beforeSend` / `request.excludedUrls`。
|
|
61
61
|
- 需要分析 CSP:开启 `cspViolation`。
|
|
62
62
|
- 需要分析实时通信:开启 `websocket`,注意避免多个 SDK 实例重复 patch。
|
|
63
|
-
|
|
64
|
-
# 基础采集插件
|
|
65
|
-
|
|
66
|
-
基础插件负责建立 RUM 数据的关联上下文:哪个用户、哪个会话、哪个页面、哪个设备。
|
|
67
|
-
|
|
68
|
-
以下片段聚焦对应的 `session` 或 `tracking` 配置,实际初始化仍需提供必填的 `application.name` 和有效的 `transport` endpoint 配置。
|
|
69
|
-
|
|
70
|
-
## session
|
|
71
|
-
|
|
72
|
-
`session` 维护 `session.id`,并在会话开始和轮换时写入 log。它是所有 RUM 信号的关联边界,获得 Consent 后始终开启,不能关闭;是否导出由 Session 采样决定。
|
|
73
|
-
|
|
74
|
-
默认规则:
|
|
75
|
-
|
|
76
|
-
- 不活跃超过 15 分钟后过期,下一次用户交互时轮换。
|
|
77
|
-
- 会话最长 4 小时。
|
|
78
|
-
- storage key 会按 endpoint host 隔离。
|
|
79
|
-
- 页面重新可见只续期有效会话,不会复活已过期会话。
|
|
80
|
-
- 跨 Tab 共享持久化状态,但已过期的 Tab 需要自身发生用户交互后才接管新会话。
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
new BkOpenTelemetry({
|
|
84
|
-
session: {
|
|
85
|
-
storageKey: 'bk-rum-session',
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
超时固定为 15 分钟无活动、4 小时最长生命周期,不开放配置。过期会结束当前 View、刷新旧 session 的待发送数据,并丢弃此后所有不带有效 `session.id` 的 span/log/metric;下一次用户交互续期时,同时创建新的 Session 和 View。Metric 使用 DELTA temporality,避免累计值跨 session 重复上报。
|
|
91
|
-
|
|
92
|
-
**产出遥测**:log `session.start` / `session.rotate`,并维护运行时属性 `session.id`。
|
|
93
|
-
|
|
94
|
-
## device
|
|
95
|
-
|
|
96
|
-
`device` 插件采集设备、浏览器、系统、视口和网络信息。默认开启。
|
|
97
|
-
|
|
98
|
-
```ts
|
|
99
|
-
new BkOpenTelemetry({
|
|
100
|
-
tracking: {
|
|
101
|
-
device: {
|
|
102
|
-
persistentId: true,
|
|
103
|
-
storageKey: 'bk-rum-device',
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
稳定的浏览器、系统和硬件能力写入三类信号共享的 Resource;设备 ID、视口和网络信息保留为运行时属性,后续 span/log 会自动携带,便于按浏览器、系统、网络类型下钻。
|
|
110
|
-
|
|
111
|
-
`device.id` 默认只在当前 SDK 实例内稳定;只有显式设置 `persistentId: true` 才写入 localStorage,并按应用名隔离默认 storage key。
|
|
112
|
-
|
|
113
|
-
**产出遥测**:写入 Resource 属性(如 `browser.name`、`os.name`、`device.type`、`device.memory_gib`)和运行时属性(如 `device.id`、`browser.viewport.*`、`network.effective_type`),本身不单独产生 span/metric/log。
|
|
114
|
-
|
|
115
|
-
## View
|
|
116
|
-
|
|
117
|
-
View 管理器负责初始页面、SPA 路由、手动 View、BFCache 和 Session 续期。它与 Session 一样不可关闭,并维护:
|
|
118
|
-
|
|
119
|
-
- `view.id`
|
|
120
|
-
- `view.name`
|
|
121
|
-
- `view.url`
|
|
122
|
-
- `view.url_path_group`
|
|
123
|
-
- `view.loading_type`
|
|
124
|
-
- `view.loading_time`
|
|
125
|
-
|
|
126
|
-
```ts
|
|
127
|
-
new BkOpenTelemetry({
|
|
128
|
-
tracking: {
|
|
129
|
-
view: {
|
|
130
|
-
tracking: 'auto',
|
|
131
|
-
loadingTime: true,
|
|
132
|
-
excludedActivityUrls: [/\/events\/stream$/],
|
|
133
|
-
getPathGroup: url => {
|
|
134
|
-
const { pathname } = new URL(url, window.location.href);
|
|
135
|
-
return pathname.replace(/\/\d+/g, '/:id');
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
自动模式只在 pathname 或非锚点 hash path 变化时切换 View;query-only 和页内锚点变化不会切换。手动模式使用 `view.tracking: 'manual'`,并调用 `startView({ name, url, attributes })`。
|
|
143
|
-
|
|
144
|
-
```ts
|
|
145
|
-
const bkOT = new BkOpenTelemetry({
|
|
146
|
-
application: { name: 'order-web' },
|
|
147
|
-
autoStart: false,
|
|
148
|
-
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
149
|
-
tracking: { view: { tracking: 'manual' } },
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
await bkOT.start();
|
|
153
|
-
bkOT.startView({
|
|
154
|
-
name: '订单详情',
|
|
155
|
-
url: window.location.href,
|
|
156
|
-
attributes: { 'biz.owner': 'order-team' },
|
|
157
|
-
});
|
|
158
|
-
bkOT.setViewName('订单详情-只读');
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
`view.id` 始终由 SDK 生成,`attributes` 不能覆盖 Session/View 等保留字段。普通 span/log 必须同时带有 `session.id` 和 `view.id` 才会进入导出链路;metric 只保留 `view.url_path_group` 等低基数维度,不携带唯一 `view.id`。手动模式在首次 `startView()` 前不会导出普通 RUM 数据。
|
|
162
|
-
|
|
163
|
-
View Loading Time 默认开启:初始加载取 `loadEventEnd` 与页面活动结束时间的较大值,SPA 路由取 View 创建到页面活动结束的耗时。请求、静态资源和 DOM 变更都属于页面活动,连续 100ms 无活动视为稳定。长轮询或埋点请求应配置到 `view.excludedActivityUrls`;业务也可在真正渲染完成时调用 `setViewLoadingTime()` 覆盖自动结果。
|
|
164
|
-
|
|
165
|
-
**产出遥测**:长 span `browser.view`(包含 `view.loading_time`)与 body 为 `browser.view` 的 create/update/final Snapshot Log,metric `browser.view.loading_time`,并维护 `view.*` 运行时属性。
|
|
166
|
-
|
|
167
|
-
## action
|
|
168
|
-
|
|
169
|
-
`action` 插件默认开启。它自动监听 click,观察交互后的请求、DOM 变更、资源、错误和长任务,在页面活动稳定后生成一个 `action` span。
|
|
170
|
-
|
|
171
|
-
**产出遥测**:span `action.<type>`(如 `action.click`,`span_type=action`)。`reportAction()` 走同一套字段。
|
|
172
|
-
|
|
173
|
-
```ts
|
|
174
|
-
new BkOpenTelemetry({
|
|
175
|
-
tracking: {
|
|
176
|
-
action: {
|
|
177
|
-
actionNameAttribute: 'data-bk-action-name',
|
|
178
|
-
maxDuration: 10000,
|
|
179
|
-
nameCollection: 'explicit',
|
|
180
|
-
},
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
自动命名在默认 `explicit` 模式只向上查找 `data-bk-action-name`;没有显式名称时退回目标元素标签名。设置 `nameCollection: 'text'` 后才会继续读取 label、按钮值、`aria-label`、`alt`、`name`、`title`、`placeholder` 和 DOM 文本,并自行评估隐私风险。
|
|
186
|
-
|
|
187
|
-
对关键业务动作,推荐使用 `reportAction()` 显式上报,字段更稳定。
|
|
188
|
-
|
|
189
|
-
```ts
|
|
190
|
-
bkOT.reportAction({
|
|
191
|
-
name: '立即支付',
|
|
192
|
-
attributes: {
|
|
193
|
-
'biz.order_id': '202605270001',
|
|
194
|
-
},
|
|
195
|
-
});
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
# 体验与性能插件
|
|
199
|
-
|
|
200
|
-
体验类插件关注页面加载、资源、核心 Web 指标、空白屏、主线程阻塞和 SPA 路由切换。
|
|
201
|
-
|
|
202
|
-
以下片段聚焦 `tracking` 配置,实际初始化仍需提供必填的 `application.name` 和有效的 `transport` endpoint 配置。
|
|
203
|
-
|
|
204
|
-
## resource
|
|
205
|
-
|
|
206
|
-
`resource` 插件默认开启,基于 PerformanceObserver 采集静态资源加载 span。
|
|
207
|
-
|
|
208
|
-
```ts
|
|
209
|
-
new BkOpenTelemetry({
|
|
210
|
-
tracking: {
|
|
211
|
-
resource: true,
|
|
212
|
-
},
|
|
213
|
-
});
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
常见字段包括 `resource.type`、`resource.size`、`resource.protocol`、`url.full`、`server.address`。当 Resource Timing 数据可用时,还会上报:
|
|
217
|
-
|
|
218
|
-
- `resource.redirect.*`、`resource.dns.*`、`resource.connect.*`、`resource.ssl.*`
|
|
219
|
-
- `resource.first_byte.*`、`resource.download.*`、`resource.worker.*`
|
|
220
|
-
- `resource.delivery_type`、`resource.render_blocking_status`
|
|
221
|
-
|
|
222
|
-
每个网络阶段同时包含相对资源开始时刻的 `start` 与阶段 `duration`,单位均为 ms。跨域资源没有返回 `Timing-Allow-Origin` 时,浏览器不会暴露完整阶段数据,SDK 会保留资源总耗时,但不生成不可信的阶段字段。
|
|
223
|
-
|
|
224
|
-
**产出遥测**:span `browser.resource`(`span_type=resource`)。
|
|
225
|
-
|
|
226
|
-
## action 与挫败信号
|
|
227
|
-
|
|
228
|
-
`action` 默认开启。它观察点击后的请求、DOM 变更、静态资源、错误和长任务,在活动稳定后计算 `action.loading_time` 和子事件数量。
|
|
229
|
-
|
|
230
|
-
自动点击还会判断三类挫败信号:
|
|
231
|
-
|
|
232
|
-
- `rage_click`:1 秒内在同一元素 100px 范围内连续点击至少三次;滚动或文本选择会中断判定。三次点击合并为一条 action。
|
|
233
|
-
- `dead_click`:点击后没有页面活动、输入、滚动或文本选择;文本输入、链接、select、textarea、canvas、contenteditable 等无法可靠判断的元素会排除。
|
|
234
|
-
- `error_click`:点击活动窗口内产生前端错误。
|
|
235
|
-
|
|
236
|
-
信号写入 `action.frustration.type`(string[])和 `action.frustration.count`。为了完成连续点击判断,action span 最多延迟 1 秒创建;`action.id` 只在真实页面活动窗口内挂到关联事件上,不会因为这个上报等待期延长。
|
|
237
|
-
|
|
238
|
-
## webVitals
|
|
239
|
-
|
|
240
|
-
`webVitals` 插件默认开启,采集 CLS、FCP、INP、LCP、TTFB。FCP/LCP/TTFB 按指标发生时刻归属 View,CLS 使用每个 View 独立的 1 秒间隔/5 秒窗口,INP 使用候选交互的近似 p98,而不是简单最大值。它会同时产生 metric 和 span:metric 用于低基数聚合,span 用于通过 `session.id`、`view.id` 定位具体页面和归因信息。
|
|
241
|
-
|
|
242
|
-
**产出遥测**:metric `browser.web_vital.cls`(unit `1`)、`browser.web_vital.duration`(unit `ms`,FCP/INP/LCP/TTFB 共用)+ span `browser.web_vital`(`span_type=vital`,含 attribution 归因)。
|
|
243
|
-
|
|
244
|
-
```ts
|
|
245
|
-
new BkOpenTelemetry({
|
|
246
|
-
tracking: {
|
|
247
|
-
webVitals: true,
|
|
248
|
-
},
|
|
249
|
-
});
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## blankScreen
|
|
253
|
-
|
|
254
|
-
`blankScreen` 插件默认开启。它会针对每个 View 等待页面活动稳定后执行九点分层采样;只有两次连续检测都超过阈值才上报。View 切换或页面隐藏会取消旧检测,恢复可见后重新调度。
|
|
255
|
-
|
|
256
|
-
```ts
|
|
257
|
-
new BkOpenTelemetry({
|
|
258
|
-
tracking: {
|
|
259
|
-
blankScreen: {
|
|
260
|
-
rootSelector: '#app',
|
|
261
|
-
checkDelay: 1000,
|
|
262
|
-
confirmationDelay: 200,
|
|
263
|
-
threshold: 0.8,
|
|
264
|
-
ignoreSelectors: ['.global-loading', '.skeleton'],
|
|
265
|
-
},
|
|
266
|
-
},
|
|
267
|
-
});
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
SPA 应用建议配置 `rootSelector`。根节点在确认阶段仍不存在时会以 `missing_root` 原因上报;loading 和骨架屏样本不进入空白比例分母。
|
|
271
|
-
|
|
272
|
-
**产出遥测**(仅判定为白屏时):metric `browser.blank_screen.count` + error span `browser.blank_screen`(`span_type=error`)。
|
|
273
|
-
|
|
274
|
-
## longTask
|
|
275
|
-
|
|
276
|
-
`longTask` 插件默认关闭。开启后优先通过 Long Animation Frames API 采集主线程阻塞;浏览器不支持时自动回退到 Long Tasks API,两种入口不会重复观察。
|
|
277
|
-
|
|
278
|
-
```ts
|
|
279
|
-
new BkOpenTelemetry({
|
|
280
|
-
tracking: {
|
|
281
|
-
longTask: {
|
|
282
|
-
threshold: 50,
|
|
283
|
-
warningThreshold: 100,
|
|
284
|
-
},
|
|
285
|
-
},
|
|
286
|
-
});
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
LoAF 会补充 blocking duration、render/style/layout 阶段、最重脚本归因,并把每个脚本作为 `long_task.script` Span Event。初始化阶段的 buffered entries 延迟到后续宏任务批量处理,避免 SDK 启动自身制造阻塞。不支持 LoAF 和 Long Tasks API 的浏览器会跳过插件。
|
|
290
|
-
|
|
291
|
-
**产出遥测**:metric `browser.long_task.count` / `browser.long_task.duration` / `browser.long_task.blocking_duration`(unit `ms`)+ span `browser.long_task`(`span_type=longtask`)。
|
|
292
|
-
|
|
293
|
-
## View Loading Time
|
|
294
|
-
|
|
295
|
-
View Loading Time 属于 View 管理器,默认启用,基于页面活动结束时间计算。
|
|
296
|
-
|
|
297
|
-
自动计算规则:
|
|
298
|
-
|
|
299
|
-
- 初始加载:取 `navigationStart → loadEventEnd` 与 `navigationStart → 页面活动结束` 的较大值。
|
|
300
|
-
- SPA 路由:取 View 创建到页面活动结束的耗时。
|
|
301
|
-
- Fetch/XHR 进行中、静态资源完成和 DOM Mutation 都属于活动;连续 100ms 无活动视为稳定。
|
|
302
|
-
- SDK 自身上报、`view.excludedActivityUrls` 命中的请求,以及 `data-bk-excluded-activity-mutations` 节点下的 DOM 变更不参与计算。
|
|
303
|
-
|
|
304
|
-
```ts
|
|
305
|
-
new BkOpenTelemetry({
|
|
306
|
-
tracking: {
|
|
307
|
-
view: {
|
|
308
|
-
loadingTime: true,
|
|
309
|
-
excludedActivityUrls: [/\/events\/stream$/, '/analytics'],
|
|
310
|
-
},
|
|
311
|
-
},
|
|
312
|
-
});
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
如果业务有明确的异步渲染完成点,可覆盖自动结果:
|
|
316
|
-
|
|
317
|
-
```ts
|
|
318
|
-
await loadAlarmDetail();
|
|
319
|
-
bkOT.setViewLoadingTime();
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
# 错误与安全插件
|
|
323
|
-
|
|
324
|
-
以下片段聚焦 `tracking` 配置,实际初始化仍需提供必填的 `application.name` 和有效的 `transport` endpoint 配置。
|
|
325
|
-
|
|
326
|
-
错误类插件帮助定位 JavaScript 异常、Promise 异常、资源加载失败、CSP 违规和空白屏等问题。
|
|
327
|
-
|
|
328
|
-
## error
|
|
329
|
-
|
|
330
|
-
`error` 插件默认开启,监听:
|
|
331
|
-
|
|
332
|
-
- `window.error`
|
|
333
|
-
- `unhandledrejection`
|
|
334
|
-
- 资源加载错误
|
|
335
|
-
|
|
336
|
-
插件会生成 error span,并使用 fingerprint 做窗口内节流,避免相同错误在短时间内刷屏。
|
|
337
|
-
|
|
338
|
-
**产出遥测**:span `browser.error`(JS 错误)、`browser.unhandledrejection`(Promise 异常)、`browser.resource_error`(资源加载失败),均为 `span_type=error`,带异常摘要、`error.source`、`error.window_occurrence_index`;精确总量由 `browser.error.count` 记录。
|
|
339
|
-
|
|
340
|
-
```ts
|
|
341
|
-
new BkOpenTelemetry({
|
|
342
|
-
tracking: {
|
|
343
|
-
error: {
|
|
344
|
-
maxPerWindow: 5,
|
|
345
|
-
windowMs: 60_000,
|
|
346
|
-
},
|
|
347
|
-
},
|
|
348
|
-
});
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
## 手动上报错误事件
|
|
352
|
-
|
|
353
|
-
业务捕获到错误后,可以通过 `reportCustomEvent()` 上报。
|
|
354
|
-
|
|
355
|
-
```ts
|
|
356
|
-
try {
|
|
357
|
-
await submitOrder();
|
|
358
|
-
} catch (error) {
|
|
359
|
-
bkOT.reportCustomEvent({
|
|
360
|
-
name: 'submit_order_failed',
|
|
361
|
-
error: error instanceof Error ? error : new Error(String(error)),
|
|
362
|
-
attributes: {
|
|
363
|
-
'biz.order_id': '202605270001',
|
|
364
|
-
},
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
## cspViolation
|
|
370
|
-
|
|
371
|
-
`cspViolation` 插件默认关闭。开启后监听浏览器 `securitypolicyviolation` 事件,并写入 error span。
|
|
372
|
-
|
|
373
|
-
**产出遥测**:span `csp.violation`(`span_type=error`),带 `csp.*` 字段;完整策略 `csp.original_policy` 仅在节流窗口首条携带。
|
|
374
|
-
|
|
375
|
-
```ts
|
|
376
|
-
new BkOpenTelemetry({
|
|
377
|
-
tracking: {
|
|
378
|
-
cspViolation: true,
|
|
379
|
-
},
|
|
380
|
-
});
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
建议与站点 CSP 响应头一起使用。
|
|
384
|
-
|
|
385
|
-
```http
|
|
386
|
-
Content-Security-Policy: default-src 'self'; report-uri /csp-report
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
## blankScreen 与错误排查
|
|
390
|
-
|
|
391
|
-
空白屏通常是错误、资源失败或首屏渲染失败的结果。建议同时开启 `blankScreen`、`error`、`resource`。
|
|
392
|
-
|
|
393
|
-
```ts
|
|
394
|
-
new BkOpenTelemetry({
|
|
395
|
-
tracking: {
|
|
396
|
-
blankScreen: {
|
|
397
|
-
rootSelector: '#app',
|
|
398
|
-
},
|
|
399
|
-
error: true,
|
|
400
|
-
resource: true,
|
|
401
|
-
},
|
|
402
|
-
});
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
通过 `view.id` 和 `session.id` 可以把空白屏、JS 错误、资源失败关联到同一次页面访问。
|
|
406
|
-
|
|
407
|
-
# 网络与扩展插件
|
|
408
|
-
|
|
409
|
-
网络能力覆盖 Fetch/XHR 与 WebSocket。两者都会 patch 浏览器全局 API,同一页面只应运行一个 SDK 实例。
|
|
410
|
-
|
|
411
|
-
以下片段聚焦 `tracking`,实际初始化仍需提供 `application.name` 和有效 Transport。
|
|
412
|
-
|
|
413
|
-
## Fetch/XHR request
|
|
414
|
-
|
|
415
|
-
`tracking.request` 默认开启。当前实现由 SDK 自己统一 patch `window.fetch` 与 `XMLHttpRequest.prototype.open/send`,不使用官方 Fetch/XHR instrumentation,也不会为同一请求叠加两套生命周期。
|
|
416
|
-
|
|
417
|
-
### 请求生命周期
|
|
418
|
-
|
|
419
|
-
一次请求按以下顺序处理:
|
|
420
|
-
|
|
421
|
-
1. 转成绝对 URL,检查 SDK 自身 OTLP Endpoint 与 `excludedUrls`。
|
|
422
|
-
2. 创建名为 `browser.resource`、kind 为 `CLIENT` 的 Span。
|
|
423
|
-
3. 记录 View/Action 页面活动;`view.excludedActivityUrls` 可只排除活动等待,不丢弃 Span。
|
|
424
|
-
4. `allowedTracingUrls` 命中且 Trace 开启时进入传播 Header 注入分支;默认 W3C propagator 注入 `traceparent`,宿主已有全局 propagator 时以实际实现为准。
|
|
425
|
-
5. 请求完成后写入状态、结果、错误和 `request.beforeSend` 属性。
|
|
426
|
-
6. 等待最多 200ms 匹配 Resource Timing,把网络阶段补回同一 Span。
|
|
427
|
-
7. 如已配置 Body 且 Log 开启,异步生成关联原 `trace.id` / `span.id` 的诊断 Log。
|
|
428
|
-
|
|
429
|
-
**产出遥测**:Span `browser.resource`,`span_type=resource`、`resource.type=fetch|xhr`,常用属性包括 `http.request.method`、`http.response.status_code`、`url.full`、`server.address`、网络阶段与响应体积。
|
|
430
|
-
|
|
431
|
-
```ts
|
|
432
|
-
new BkOpenTelemetry({
|
|
433
|
-
application: { name: 'request-demo' },
|
|
434
|
-
transport: { endpoint: 'https://collector.example.com' },
|
|
435
|
-
tracking: {
|
|
436
|
-
request: {
|
|
437
|
-
excludedUrls: [/\/health(?:\?|$)/],
|
|
438
|
-
beforeSend(event, context) {
|
|
439
|
-
event.attributes['request.transport'] = context.type;
|
|
440
|
-
return event.resource.statusCode !== 404;
|
|
441
|
-
},
|
|
442
|
-
},
|
|
443
|
-
},
|
|
444
|
-
});
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
`request.beforeSend` 在请求完成后执行,可修改 Span attributes;返回 `false` 会标记该 Span 在最终 processor 中丢弃,并立即跳过该请求的 Body Log。Hook 抛错不会中断业务请求,`debug: true` 时输出 warning。
|
|
448
|
-
|
|
449
|
-
### excludedUrls 与 excludedActivityUrls
|
|
450
|
-
|
|
451
|
-
| 配置 | 是否创建 Span | 是否计入 View/Action 活动 | 适用场景 |
|
|
452
|
-
| --- | --- | --- | --- |
|
|
453
|
-
| `tracking.request.excludedUrls` | 否 | 否 | 探活、埋点、无需采集的请求 |
|
|
454
|
-
| `tracking.view.excludedActivityUrls` | 是 | 否 | 长轮询、SSE、流式接口,不应阻塞页面稳定 |
|
|
455
|
-
|
|
456
|
-
两者都支持字符串包含、RegExp 和函数 matcher。
|
|
457
|
-
|
|
458
|
-
### traceparent 注入条件
|
|
459
|
-
|
|
460
|
-
只有 `allowedTracingUrls` 命中且 Trace 信号开启时才进入传播 Header 注入分支;默认 W3C propagator 会注入 `traceparent`,同源请求也不隐式放行。
|
|
461
|
-
|
|
462
|
-
```ts
|
|
463
|
-
tracking: {
|
|
464
|
-
request: {
|
|
465
|
-
allowedTracingUrls: [
|
|
466
|
-
url => new URL(url).origin === 'https://api.example.com',
|
|
467
|
-
/^https:\/\/[^/]+\.internal\.example\.com\//,
|
|
468
|
-
],
|
|
469
|
-
},
|
|
470
|
-
}
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
字符串 matcher 使用包含匹配,例如 `'https://api.example.com'` 也会命中 `https://api.example.com.evil/`,不适合作为安全 origin 边界。需要精确控制时使用上面的 URL-aware 函数或带 `/` 边界的正则。
|
|
474
|
-
|
|
475
|
-
跨域注入会触发 CORS 预检,目标服务必须在 `Access-Control-Allow-Headers` 放行实际使用的 Trace Header。SDK 成功注册自己的默认 W3C propagator 时通常注入 `traceparent`,并可能透传已有 `tracestate`;如果宿主已注册全局 propagator,实际 Header 由该 propagator 决定,可能还包含其他传播字段。
|
|
476
|
-
|
|
477
|
-
### Resource Timing
|
|
478
|
-
|
|
479
|
-
Fetch/XHR 与静态资源共用一个 Resource PerformanceObserver:
|
|
480
|
-
|
|
481
|
-
- `initiatorType=fetch|xmlhttprequest` 的 entry 只用于匹配请求 Span,不再创建静态资源 Span。
|
|
482
|
-
- 通过 URL 与时间窗口匹配;找不到 entry 时请求 Span 仍正常结束。
|
|
483
|
-
- 跨域接口缺少 `Timing-Allow-Origin` 时,浏览器不会提供完整阶段字段。
|
|
484
|
-
- Trace 关闭时跳过 timing 等待,因为不存在可导出的请求 Span。
|
|
485
|
-
|
|
486
|
-
### 请求/响应 Body
|
|
487
|
-
|
|
488
|
-
Body 默认关闭。开启时必须提供 `redact`,默认只采集状态未知、0 或 `>=400` 的请求:
|
|
489
|
-
|
|
490
|
-
```ts
|
|
491
|
-
tracking: {
|
|
492
|
-
request: {
|
|
493
|
-
body: {
|
|
494
|
-
capture: 'errors',
|
|
495
|
-
maxSize: 10 * 1024,
|
|
496
|
-
allowedContentTypes: ['application/json', /^text\//],
|
|
497
|
-
redact({ body, kind }) {
|
|
498
|
-
if (kind === 'request') {
|
|
499
|
-
return body.replace(/("(?:password|token)"\s*:\s*)"[^"]*"/g, '$1"***"');
|
|
500
|
-
}
|
|
501
|
-
return body;
|
|
502
|
-
},
|
|
503
|
-
},
|
|
504
|
-
},
|
|
505
|
-
}
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
**产出遥测**:Log `browser.request.body`,错误请求为 ERROR,`capture: 'all'` 下成功请求为 INFO。
|
|
509
|
-
|
|
510
|
-
- Fetch 的 Request/Response 通过 clone 限量读取,不消费业务原始流。
|
|
511
|
-
- XHR 支持文本与 JSON 响应。
|
|
512
|
-
- string、URLSearchParams、Blob 等可文本化请求可读取;FormData、ArrayBuffer 和二进制响应跳过。
|
|
513
|
-
- 默认 Content-Type:`text/*`、包含 `json`、`application/x-www-form-urlencoded`、`application/graphql`。
|
|
514
|
-
- `redact` 返回 `undefined` 时只跳过当前 request 或 response Body。
|
|
515
|
-
- Log 信号关闭时 Body 配置不生效。
|
|
516
|
-
|
|
517
|
-
## websocket
|
|
518
|
-
|
|
519
|
-
`tracking.websocket` 默认关闭。开启后用 Proxy 包装 `window.WebSocket`,保留静态常量、`instanceof` 与子类化行为。
|
|
520
|
-
|
|
521
|
-
```ts
|
|
522
|
-
new BkOpenTelemetry({
|
|
523
|
-
application: { name: 'realtime-demo' },
|
|
524
|
-
transport: { endpoint: 'https://collector.example.com' },
|
|
525
|
-
tracking: { websocket: true },
|
|
526
|
-
});
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
**产出遥测**:
|
|
530
|
-
|
|
531
|
-
- Span `websocket.connect`:只覆盖建连阶段,成功/失败后结束,不用长 Span 覆盖整个连接。
|
|
532
|
-
- Metric `browser.websocket.message.count`、`browser.websocket.message.bytes`:按 `in/out` 分组。
|
|
533
|
-
- Metric `browser.websocket.error.count`:按 `connect/runtime` 分组。
|
|
534
|
-
- Metric `browser.websocket.connect.duration`:只记录成功建连耗时。
|
|
535
|
-
- Log `websocket.error`、`websocket.close`:记录错误阶段和关闭详情。
|
|
536
|
-
|
|
537
|
-
插件不读取消息内容,只计算数量和字节数。超过 64KB 的字符串使用 `string.length` 近似字节数,避免编码开销;CJK/emoji 会低估。相同 URL 的错误 Log 在 60 秒内最多 5 条,Error Counter 不受节流影响。
|
|
538
|
-
|
|
539
|
-
SDK shutdown 后新建连接不再采集;已存在连接上的包装会保留,但回调立即返回。若其他库后来替换了 `window.WebSocket`,shutdown 不会强行覆盖后来者。
|
|
540
|
-
|
|
541
|
-
## 与额外 instrumentation 的关系
|
|
542
|
-
|
|
543
|
-
`extensions.instrumentations` 适合已有标准 OpenTelemetry instrumentation。不要再注册覆盖 Fetch/XHR 或用户交互的 instrumentation,否则可能与内置 request/action 重复 patch、重复 Span。
|
|
544
|
-
|
|
545
|
-
需要 Session/View、`emitLog()`、页面活动或 RUM 归一字段时,优先写自定义插件,见[内置采集与扩展](./concepts.md)与[自定义插件](./custom-plugin.md)。
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
## 命名规则
|
|
10
10
|
|
|
11
11
|
- **信号名**:`browser.*` 表示内置浏览器事件(如 `browser.web_vital`);`action.<type>`、`custom.<name>` 是运行期动态拼接;`csp.violation`、`websocket.*` 使用领域前缀。
|
|
12
|
-
- **属性 key**:标准字段与 RUM 领域字段均使用点号命名空间(如 `http.request.method`、`exception.type`、`view.id`、`session.id`、`browser.name`);跨类型检索字段使用下划线(如 `span_type`、`span_subtype`、`result
|
|
12
|
+
- **属性 key**:标准字段与 RUM 领域字段均使用点号命名空间(如 `http.request.method`、`exception.type`、`view.id`、`session.id`、`browser.name`);跨类型检索字段使用下划线(如 `span_type`、`span_subtype`、`result`)。公共与跨插件字段常量集中定义在 `src/schema/attributes.ts`,插件私有字段在对应插件内定义。
|
|
13
13
|
|
|
14
14
|
## 公共 Resource 与运行时上下文属性
|
|
15
15
|
|
|
@@ -42,21 +42,21 @@ Resource 属性由三类信号共享;运行时上下文属性自动挂到**几
|
|
|
42
42
|
|
|
43
43
|
## Span 清单
|
|
44
44
|
|
|
45
|
-
| span 名 | span_type | 来源 | 关键属性 | 备注 |
|
|
46
|
-
| --- | --- | --- | --- | --- |
|
|
47
|
-
| `browser.view` | `document` / `route` | View 管理器 | `view.name`、`view.loading_time`、`view.loading_time.source`、`url.previous`、`event.source`、`view.end_reason` |
|
|
48
|
-
| `browser.resource` | `resource` | Fetch/XHR request 采集 | `resource.type=fetch\|xhr`、`url.full`、`http.request.method`、`http.response.status_code`、网络阶段属性 |
|
|
49
|
-
| `browser.resource` | `resource` | resource 插件 | `resource.type`、`url.full`、`resource.size`、网络阶段、`resource.render_blocking_status`、`resource.protocol`、`resource.cache.hit` | 仅静态资源,跳过 Fetch/XHR |
|
|
50
|
-
| `browser.web_vital` | `vital` | webVitals 插件 | `vital.metric`、`vital.value`、`vital.rating`、`vital.id`、`rum.navigation.type`、`vital.<lcp\|cls\|inp\|fcp\|ttfb>.*` | 每个指标一条 |
|
|
51
|
-
| `browser.blank_screen` | `error` | blankScreen 插件(二次确认白屏时) | `blank_screen.empty_ratio`、`blank_screen.reason`、`blank_screen.root_selector`、`blank_screen.root_found`、`blank_screen.*_sample_count`、`blank_screen.center_element` | 每个 View 最多一条 |
|
|
52
|
-
| `browser.error` | `error` | error 插件(`window.error`) | `exception.fingerprint`、`exception.message_short`、`exception.stack_top_frame`、`error.source=window.error`、`error.window_occurrence_index`、`code.filepath`、`code.lineno`、`code.column`、`error.cross_origin` | 完整异常写入标准 `exception` Span Event |
|
|
53
|
-
| `browser.unhandledrejection` | `error` | error 插件(Promise 异常) | `exception.fingerprint`、`error.source=unhandledrejection` | 完整异常写入标准 `exception` Span Event |
|
|
54
|
-
| `browser.resource_error` | `error` | error 插件(资源加载失败) | `exception.fingerprint`、`error.source=resource`、`url.full`、`html.tag` | 完整异常写入标准 `exception` Span Event |
|
|
55
|
-
| `browser.long_task` | `longtask` | longTask 插件 | `long_task.id`、`long_task.entry_type`、`long_task.start_time`、`long_task.duration`、`long_task.blocking_duration`、`long_task.culprit`、`long_task.script.count` | LoAF 脚本详情写入 `long_task.script` Span Event |
|
|
56
|
-
| `csp.violation` | `error` | cspViolation 插件 | `csp.blocked_uri`、`csp.violated_directive`、`csp.effective_directive`、`csp.source_file`、`csp.line_number`、`csp.status_code`、`csp.fingerprint`、`csp.window_occurrence_index`、`csp.original_policy`(窗口首条) | |
|
|
57
|
-
| `websocket.connect` | `custom` | websocket 插件(仅建连阶段) | `url.full`、`url.scheme`、`server.address`、`network.protocol.name=websocket` | 长连接生命周期不绑定 span |
|
|
58
|
-
| `action.click` / `action.custom` | `action` | action 插件 / `reportAction()` | `action.id/name/type/target.*`、`action.loading_time`、`action.frustration.*`、`action.*.count` | 自动点击或手动动作;挫败信号仅自动点击 |
|
|
59
|
-
| `custom.<name>` | `custom` | `reportCustomEvent()` / 自定义插件 | `rum.custom.name`、业务自定义属性 | 带 `error` 时记录 exception、设置错误 Status/Result,`span_type` 仍为 `custom` |
|
|
45
|
+
| span 名 | span_type | kind | 来源 | 关键属性 | 备注 |
|
|
46
|
+
| --- | --- | --- | --- | --- | --- |
|
|
47
|
+
| `browser.view` | `document` / `route` | INTERNAL | View 管理器 | `view.name`、`view.loading_time`、`view.loading_time.source`、`url.previous`、`event.source`、`view.end_reason` | 有持续时间,由下一次 View、pagehide、Session 过期或 SDK shutdown 结束 |
|
|
48
|
+
| `browser.resource` | `resource` | CLIENT | Fetch/XHR request 采集 | `resource.type=fetch\|xhr`、`url.full`、`http.request.method`、`http.response.status_code`、网络阶段属性 | Fetch/XHR 共用同一实现 |
|
|
49
|
+
| `browser.resource` | `resource` | CLIENT | resource 插件 | `resource.type`、`url.full`、`resource.size`、网络阶段、`resource.render_blocking_status`、`resource.protocol`、`resource.cache.hit` | 仅静态资源,跳过 Fetch/XHR |
|
|
50
|
+
| `browser.web_vital` | `vital` | INTERNAL | webVitals 插件 | `vital.metric`、`vital.value`、`vital.rating`、`vital.id`、`rum.navigation.type`、`vital.<lcp\|cls\|inp\|fcp\|ttfb>.*` | 每个指标一条 |
|
|
51
|
+
| `browser.blank_screen` | `error` | INTERNAL | blankScreen 插件(二次确认白屏时) | `blank_screen.empty_ratio`、`blank_screen.reason`、`blank_screen.root_selector`、`blank_screen.root_found`、`blank_screen.*_sample_count`、`blank_screen.center_element` | 每个 View 最多一条 |
|
|
52
|
+
| `browser.error` | `error` | INTERNAL | error 插件(`window.error`) | `exception.fingerprint`、`exception.message_short`、`exception.stack_top_frame`、`error.source=window.error`、`error.window_occurrence_index`、`code.filepath`、`code.lineno`、`code.column`、`error.cross_origin` | 完整异常写入标准 `exception` Span Event |
|
|
53
|
+
| `browser.unhandledrejection` | `error` | INTERNAL | error 插件(Promise 异常) | `exception.fingerprint`、`error.source=unhandledrejection` | 完整异常写入标准 `exception` Span Event |
|
|
54
|
+
| `browser.resource_error` | `error` | INTERNAL | error 插件(资源加载失败) | `exception.fingerprint`、`error.source=resource`、`url.full`、`html.tag` | 完整异常写入标准 `exception` Span Event |
|
|
55
|
+
| `browser.long_task` | `longtask` | INTERNAL | longTask 插件 | `long_task.id`、`long_task.entry_type`、`long_task.start_time`、`long_task.duration`、`long_task.blocking_duration`、`long_task.culprit`、`long_task.script.count` | LoAF 脚本详情写入 `long_task.script` Span Event |
|
|
56
|
+
| `csp.violation` | `error` | INTERNAL | cspViolation 插件 | `csp.blocked_uri`、`csp.violated_directive`、`csp.effective_directive`、`csp.source_file`、`csp.line_number`、`csp.status_code`、`csp.fingerprint`、`csp.window_occurrence_index`、`csp.original_policy`(窗口首条) | |
|
|
57
|
+
| `websocket.connect` | `custom` | CLIENT | websocket 插件(仅建连阶段) | `url.full`、`url.scheme`、`server.address`、`server.port`、`network.protocol.name=websocket` | 长连接生命周期不绑定 span |
|
|
58
|
+
| `action.click` / `action.custom` | `action` | INTERNAL | action 插件 / `reportAction()` | `action.id/name/type/target.*`、`action.loading_time`、`action.frustration.*`、`action.*.count` | 自动点击或手动动作;挫败信号仅自动点击 |
|
|
59
|
+
| `custom.<name>` | `custom` | INTERNAL | `reportCustomEvent()` / 自定义插件 | `rum.custom.name`、业务自定义属性 | 带 `error` 时记录 exception、设置错误 Status/Result,`span_type` 仍为 `custom` |
|
|
60
60
|
|
|
61
61
|
## Metric 清单
|
|
62
62
|
|
|
@@ -71,16 +71,16 @@ Resource 属性由三类信号共享;运行时上下文属性自动挂到**几
|
|
|
71
71
|
| `browser.long_task.count` | Counter | - | `view.url_path_group`、`long_task.entry_type` | longTask |
|
|
72
72
|
| `browser.long_task.duration` | Histogram | `ms` | 同上 | longTask |
|
|
73
73
|
| `browser.long_task.blocking_duration` | Histogram | `ms` | 同上 | longTask,仅 LoAF |
|
|
74
|
-
| `browser.websocket.message.count` | Counter | - | `server.address`、`url.scheme`、`websocket.direction`(in/out) | websocket |
|
|
74
|
+
| `browser.websocket.message.count` | Counter | - | `server.address`、`server.port`、`url.scheme`、`websocket.direction`(in/out) | websocket |
|
|
75
75
|
| `browser.websocket.message.bytes` | Counter | `By` | 同上 | websocket |
|
|
76
|
-
| `browser.websocket.error.count` | Counter | - | `server.address`、`url.scheme`、`websocket.error.phase`(connect/runtime) | websocket |
|
|
77
|
-
| `browser.websocket.connect.duration` | Histogram | `ms` | `server.address`、`url.scheme` | websocket,仅成功建连 |
|
|
76
|
+
| `browser.websocket.error.count` | Counter | - | `server.address`、`server.port`、`url.scheme`、`websocket.error.phase`(connect/runtime) | websocket |
|
|
77
|
+
| `browser.websocket.connect.duration` | Histogram | `ms` | `server.address`、`server.port`、`url.scheme` | websocket,仅成功建连 |
|
|
78
78
|
|
|
79
79
|
> 各 metric 只会合并 `context.attributes.metric` hook 返回的自定义低基数维度,不会合并 `context.attributes.page`,也不会携带 `session.id`、`view.id` 或 `action.id`。`view.url_path_group` 中明显的数字 ID、UUID、长十六进制段会归一为 `:id`。精确 View 关联请查询对应 span 或 View Snapshot Log。**metric 维度务必保持低基数**,不要把 URL、订单号、用户输入等放进来。
|
|
80
80
|
|
|
81
81
|
## Log 事件清单
|
|
82
82
|
|
|
83
|
-
| body | severity | 来源 | 关键属性 |
|
|
83
|
+
| eventName / body | severity | 来源 | 关键属性 |
|
|
84
84
|
| --- | --- | --- | --- |
|
|
85
85
|
| `session.start` | INFO | session 插件(首次新建) | `session.id`、`session.start_time`、`session.rotate.reason=init` |
|
|
86
86
|
| `session.rotate` | INFO | session 插件(轮换) | + `session.previous_id`、`session.rotate.reason`(`inactivity` / `maxLifetime`) |
|
|
@@ -89,6 +89,8 @@ Resource 属性由三类信号共享;运行时上下文属性自动挂到**几
|
|
|
89
89
|
| `websocket.error` | ERROR | websocket 插件 | `url.full`、`websocket.error.phase`、`websocket.error.window_occurrence_index` |
|
|
90
90
|
| `websocket.close` | INFO | websocket 插件 | `websocket.close.code`、`websocket.close.reason`、`websocket.close.was_clean` |
|
|
91
91
|
|
|
92
|
+
> 内置 Log 的 `eventName` 与 `body` 当前使用同一个事件名;查询与 `tracking.beforeSend` 应优先使用 `eventName`。
|
|
93
|
+
|
|
92
94
|
> 错误主数据统一走 `error` span(见 Span 清单),SDK **不再**为同一个错误额外 emit error log,避免重复计数。
|
|
93
95
|
|
|
94
96
|
## 属性字典
|
|
@@ -104,6 +106,27 @@ Resource 属性由三类信号共享;运行时上下文属性自动挂到**几
|
|
|
104
106
|
| `result` | string | `success`/`warning`/`error`/`timeout`/`abort` | 是 |
|
|
105
107
|
| `error_type` | string | 错误细分,如 `http_5xx`/`network_timeout`/`slow`/`none` | 是 |
|
|
106
108
|
|
|
109
|
+
### View / Navigation
|
|
110
|
+
|
|
111
|
+
| key | 类型 | 出现位置 | 说明 |
|
|
112
|
+
| --- | --- | --- | --- |
|
|
113
|
+
| `view.id` / `view.name` / `view.url` / `view.url_path_group` | string | Span / Log | View 标识、名称、脱敏 URL 与低基数路由模板 |
|
|
114
|
+
| `view.loading_type` | string | Span / Log / Metric | `initial_load` / `route_change` / `session_renewal` / `bf_cache` |
|
|
115
|
+
| `view.loading_time` | number | Span / Log;同时作为 Metric 值 | View 从开始到页面活动稳定的耗时(ms) |
|
|
116
|
+
| `view.loading_time.source` | string | Span / Log | `auto` / `manual` |
|
|
117
|
+
| `view.first_byte` | number | 初始 View Span / Log | Navigation Timing 的 `responseStart`(相对 `performance.timeOrigin`,ms) |
|
|
118
|
+
| `view.dom_interactive` / `view.dom_content_loaded` | number | 初始 View Span / Log | DOM interactive / DOMContentLoaded 时间(相对 `performance.timeOrigin`,ms) |
|
|
119
|
+
| `view.dom_complete` / `view.load_event` | number | 初始 View Span / Log | DOM complete / load event 时间(相对 `performance.timeOrigin`,ms) |
|
|
120
|
+
| `url.previous` | string | Span / Log | 前一个 View URL(已脱敏) |
|
|
121
|
+
| `document.referrer` | string | 初始 View Span / Log | 页面 referrer(已脱敏) |
|
|
122
|
+
| `event.source` | string | Span / Log | View 创建触发源,如 `load`、`pushState`、`popstate`、`manual`、`bfCache`、`sessionRenewal` |
|
|
123
|
+
| `view.end_reason` | string | Span / final Log | 下一 View 的触发源,或 `pagehide` / `session_expired` / `shutdown` |
|
|
124
|
+
| `event.type` | string | Log | 固定 `view` |
|
|
125
|
+
| `view.snapshot.type` | string | Log | `create` / `update` / `final` |
|
|
126
|
+
| `view.document_version` | number | Log | 当前 View Snapshot 的递增版本号 |
|
|
127
|
+
| `view.duration` | number | Log | 从 View 开始到 Snapshot 的耗时(ms) |
|
|
128
|
+
| `view.is_active` | boolean | Log | 非 final Snapshot 为 `true` |
|
|
129
|
+
|
|
107
130
|
### HTTP / Resource
|
|
108
131
|
|
|
109
132
|
| key | 类型 | 说明 |
|
|
@@ -145,12 +168,11 @@ Resource 属性由三类信号共享;运行时上下文属性自动挂到**几
|
|
|
145
168
|
|
|
146
169
|
### 错误 / 异常
|
|
147
170
|
|
|
171
|
+
以下字段位于 Error Span 顶层属性:
|
|
172
|
+
|
|
148
173
|
| key | 类型 | 说明 |
|
|
149
174
|
| --- | --- | --- |
|
|
150
|
-
| `exception.type` | string | 异常类型/名称 |
|
|
151
|
-
| `exception.message` | string | 异常消息 |
|
|
152
175
|
| `exception.message_short` | string | 消息前 80 字符 |
|
|
153
|
-
| `exception.stacktrace` | string | 堆栈 |
|
|
154
176
|
| `exception.stack_top_frame` | string | 栈顶帧 |
|
|
155
177
|
| `exception.fingerprint` | string | 节流分组指纹(djb2 hash) |
|
|
156
178
|
| `error.source` | string | `window.error`/`unhandledrejection`/`resource`/`csp` |
|
|
@@ -160,6 +182,16 @@ Resource 属性由三类信号共享;运行时上下文属性自动挂到**几
|
|
|
160
182
|
| `code.filepath` / `code.lineno` / `code.column` | string/number | JS 错误位置 |
|
|
161
183
|
| `html.tag` | string | 资源错误的元素标签 |
|
|
162
184
|
|
|
185
|
+
`error.subtype` 仅作为 `browser.error.count` Metric 维度,取值为 `js` / `promise` / `resource_load`,不写入 Error Span 顶层属性。
|
|
186
|
+
|
|
187
|
+
完整异常由 `recordException()` 写入名为 `exception` 的标准 Span Event,不在 Span 顶层属性中:
|
|
188
|
+
|
|
189
|
+
| Event 属性 | 类型 | 说明 |
|
|
190
|
+
| --- | --- | --- |
|
|
191
|
+
| `exception.type` | string | 异常类型/名称 |
|
|
192
|
+
| `exception.message` | string | 异常消息 |
|
|
193
|
+
| `exception.stacktrace` | string | 堆栈(存在时) |
|
|
194
|
+
|
|
163
195
|
### 设备 / 浏览器 / 网络
|
|
164
196
|
|
|
165
197
|
| key | 类型 | 说明 |
|
|
@@ -169,6 +201,7 @@ Resource 属性由三类信号共享;运行时上下文属性自动挂到**几
|
|
|
169
201
|
| `device.logical_processor_count` | number | Resource 中的逻辑处理器数量 |
|
|
170
202
|
| `browser.viewport.width` / `browser.viewport.height` | number | 视口尺寸 |
|
|
171
203
|
| `browser.screen.width` / `browser.screen.height` | number | 屏幕尺寸 |
|
|
204
|
+
| `network.effective_type` | string | 网络质量,如 `4g` |
|
|
172
205
|
| `network.connection_type` / `network.downlink` / `network.rtt` / `network.save_data` | mixed | 网络信息 |
|
|
173
206
|
| `browser.name` / `browser.version` / `os.name` | string | Resource 中的 UA 解析结果 |
|
|
174
207
|
| `device.type` | string | Resource 中的 `mobile` / `desktop` |
|
|
@@ -203,7 +236,9 @@ Resource 属性由三类信号共享;运行时上下文属性自动挂到**几
|
|
|
203
236
|
| `long_task.is_frozen_frame` | boolean | 总耗时是否达到 700ms |
|
|
204
237
|
| `long_task.culprit` | string | 最重脚本 URL、函数或 legacy attribution |
|
|
205
238
|
| `long_task.script.count` | number | LoAF 脚本数 |
|
|
239
|
+
| `long_task.first_ui_event_timestamp` | number | LoAF 首个 UI Event 时间戳 |
|
|
206
240
|
| `long_task.render_start` / `long_task.style_and_layout_start` | number | LoAF 渲染与样式布局阶段起点 |
|
|
241
|
+
| `long_task.culprit.*` | mixed | 最重脚本的耗时、强制布局耗时、函数名与 invoker 类型 |
|
|
207
242
|
| `long_task.script.*` | mixed | `long_task.script` Span Event 上的脚本耗时、URL、函数、invoker 和强制布局归因 |
|
|
208
243
|
|
|
209
244
|
### CSP
|
|
@@ -224,7 +259,8 @@ Resource 属性由三类信号共享;运行时上下文属性自动挂到**几
|
|
|
224
259
|
| key | 类型 | 说明 |
|
|
225
260
|
| --- | --- | --- |
|
|
226
261
|
| `url.scheme` | string | `ws` / `wss` |
|
|
227
|
-
| `server.address` | string | 目标
|
|
262
|
+
| `server.address` | string | 目标 hostname,不包含端口 |
|
|
263
|
+
| `server.port` | number | 目标显式端口(存在时) |
|
|
228
264
|
| `network.protocol.name` | string | 固定 `websocket` |
|
|
229
265
|
| `websocket.direction` | string | `in` / `out`(仅 metric) |
|
|
230
266
|
| `websocket.error.phase` | string | `connect` / `runtime` |
|