@blueking/open-telemetry 0.0.15 → 0.0.17
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 +83 -244
- package/dist/bk-rum.global.js +2 -2
- package/dist/bk-rum.global.js.map +1 -1
- package/dist/core/config.d.ts +2 -0
- package/dist/core/metric.d.ts +2 -0
- package/dist/core/sdk.d.ts +4 -0
- package/dist/core/signal.d.ts +3 -0
- package/dist/core/telemetry-attributes.d.ts +1 -0
- package/dist/core/throttle.d.ts +2 -2
- package/dist/index.js +525 -456
- package/dist/index.js.map +1 -1
- package/dist/plugins/blank-screen.d.ts +4 -0
- package/dist/plugins/common.d.ts +1 -0
- package/dist/plugins/csp-violation.d.ts +1 -1
- package/dist/plugins/long-task.d.ts +4 -0
- package/dist/plugins/request-body.d.ts +2 -1
- package/dist/plugins/resource.d.ts +4 -0
- package/dist/plugins/web-vitals.d.ts +2 -0
- package/package.json +1 -1
- package/skills/bk-rum-otele/SKILL.md +8 -3
- package/skills/bk-rum-otele/evals/evals.json +3 -3
- package/skills/bk-rum-otele/references/api.md +236 -135
- package/skills/bk-rum-otele/references/architecture.md +141 -0
- package/skills/bk-rum-otele/references/capabilities.md +100 -0
- package/skills/bk-rum-otele/references/concepts.md +7 -4
- package/skills/bk-rum-otele/references/configuration.md +221 -178
- package/skills/bk-rum-otele/references/custom-plugin.md +15 -3
- package/skills/bk-rum-otele/references/data-model.md +5 -3
- package/skills/bk-rum-otele/references/getting-started.md +16 -0
- package/skills/bk-rum-otele/references/plugins.md +100 -72
- package/skills/bk-rum-otele/references/privacy.md +5 -1
- package/skills/bk-rum-otele/references/telemetry-reference.md +14 -12
- package/skills/bk-rum-otele/references/transport-sampling.md +79 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# 插件总览
|
|
4
4
|
|
|
5
|
-
插件是 `@blueking/open-telemetry` 的能力边界。获得采集授权后,SDK 先建立 Device、
|
|
5
|
+
插件是 `@blueking/open-telemetry` 的能力边界。获得采集授权后,SDK 先建立 Session、Device、View 上下文,再启动请求采集和其他 RUM 插件。
|
|
6
6
|
|
|
7
7
|
## 默认插件组合
|
|
8
8
|
|
|
@@ -17,6 +17,7 @@ new BkOpenTelemetry({
|
|
|
17
17
|
webVitals: true,
|
|
18
18
|
blankScreen: true,
|
|
19
19
|
device: true,
|
|
20
|
+
action: true,
|
|
20
21
|
},
|
|
21
22
|
});
|
|
22
23
|
```
|
|
@@ -29,8 +30,8 @@ new BkOpenTelemetry({
|
|
|
29
30
|
| ---------- | ----------------------------------------------------------------- | ----------------------------- |
|
|
30
31
|
| 基础上下文 | Session、View、`device` | log、span、runtime attributes |
|
|
31
32
|
| 性能体验 | View Loading Time、`resource`、`webVitals`、`blankScreen`、`longTask` | span、metric、log |
|
|
32
|
-
| 错误安全 | `error`、`cspViolation` | span
|
|
33
|
-
| 网络扩展 | request
|
|
33
|
+
| 错误安全 | `error`、`cspViolation` | span |
|
|
34
|
+
| 网络扩展 | Fetch/XHR request patch、`websocket` | span、metric、log |
|
|
34
35
|
| 用户行为 | `action`、`reportAction()` | span |
|
|
35
36
|
|
|
36
37
|
## 插件启用规则
|
|
@@ -68,7 +69,7 @@ new BkOpenTelemetry({
|
|
|
68
69
|
|
|
69
70
|
## session
|
|
70
71
|
|
|
71
|
-
`session` 维护 `session.id`,并在会话开始和轮换时写入 log。它是所有 RUM
|
|
72
|
+
`session` 维护 `session.id`,并在会话开始和轮换时写入 log。它是所有 RUM 信号的关联边界,获得 Consent 后始终开启,不能关闭;是否导出由 Session 采样决定。
|
|
72
73
|
|
|
73
74
|
默认规则:
|
|
74
75
|
|
|
@@ -143,10 +144,12 @@ new BkOpenTelemetry({
|
|
|
143
144
|
```ts
|
|
144
145
|
const bkOT = new BkOpenTelemetry({
|
|
145
146
|
application: { name: 'order-web' },
|
|
147
|
+
autoStart: false,
|
|
146
148
|
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
147
149
|
tracking: { view: { tracking: 'manual' } },
|
|
148
150
|
});
|
|
149
151
|
|
|
152
|
+
await bkOT.start();
|
|
150
153
|
bkOT.startView({
|
|
151
154
|
name: '订单详情',
|
|
152
155
|
url: window.location.href,
|
|
@@ -179,7 +182,7 @@ new BkOpenTelemetry({
|
|
|
179
182
|
});
|
|
180
183
|
```
|
|
181
184
|
|
|
182
|
-
|
|
185
|
+
自动命名在默认 `explicit` 模式只向上查找 `data-bk-action-name`;没有显式名称时退回目标元素标签名。设置 `nameCollection: 'text'` 后才会继续读取 label、按钮值、`aria-label`、`alt`、`name`、`title`、`placeholder` 和 DOM 文本,并自行评估隐私风险。
|
|
183
186
|
|
|
184
187
|
对关键业务动作,推荐使用 `reportAction()` 显式上报,字段更稳定。
|
|
185
188
|
|
|
@@ -332,7 +335,7 @@ bkOT.setViewLoadingTime();
|
|
|
332
335
|
|
|
333
336
|
插件会生成 error span,并使用 fingerprint 做窗口内节流,避免相同错误在短时间内刷屏。
|
|
334
337
|
|
|
335
|
-
**产出遥测**:span `browser.error`(JS 错误)、`browser.unhandledrejection`(Promise 异常)、`browser.resource_error`(资源加载失败),均为 `span_type=error
|
|
338
|
+
**产出遥测**:span `browser.error`(JS 错误)、`browser.unhandledrejection`(Promise 异常)、`browser.resource_error`(资源加载失败),均为 `span_type=error`,带异常摘要、`error.source`、`error.window_occurrence_index`;精确总量由 `browser.error.count` 记录。
|
|
336
339
|
|
|
337
340
|
```ts
|
|
338
341
|
new BkOpenTelemetry({
|
|
@@ -403,115 +406,140 @@ new BkOpenTelemetry({
|
|
|
403
406
|
|
|
404
407
|
# 网络与扩展插件
|
|
405
408
|
|
|
406
|
-
|
|
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,也不会为同一请求叠加两套生命周期。
|
|
407
416
|
|
|
408
|
-
|
|
417
|
+
### 请求生命周期
|
|
409
418
|
|
|
410
|
-
|
|
419
|
+
一次请求按以下顺序处理:
|
|
411
420
|
|
|
412
|
-
|
|
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。
|
|
413
428
|
|
|
414
|
-
**产出遥测**:
|
|
429
|
+
**产出遥测**:Span `browser.resource`,`span_type=resource`、`resource.type=fetch|xhr`,常用属性包括 `resource.url`、`resource.method`、`resource.status_code`、`http.*`、`url.full`、网络阶段与响应体积。
|
|
415
430
|
|
|
416
431
|
```ts
|
|
417
432
|
new BkOpenTelemetry({
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
},
|
|
433
|
+
application: { name: 'request-demo' },
|
|
434
|
+
transport: { endpoint: 'https://collector.example.com' },
|
|
421
435
|
tracking: {
|
|
422
436
|
request: {
|
|
423
437
|
excludedUrls: [/\/health(?:\?|$)/],
|
|
424
|
-
beforeSend
|
|
425
|
-
event.attributes['
|
|
426
|
-
return
|
|
438
|
+
beforeSend(event, context) {
|
|
439
|
+
event.attributes['request.transport'] = context.type;
|
|
440
|
+
return event.resource.statusCode !== 404;
|
|
427
441
|
},
|
|
428
442
|
},
|
|
429
443
|
},
|
|
430
444
|
});
|
|
431
445
|
```
|
|
432
446
|
|
|
433
|
-
|
|
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。
|
|
434
457
|
|
|
435
|
-
|
|
458
|
+
### traceparent 注入条件
|
|
459
|
+
|
|
460
|
+
只有 `allowedTracingUrls` 命中且 Trace 信号开启时才进入传播 Header 注入分支;默认 W3C propagator 会注入 `traceparent`,同源请求也不隐式放行。
|
|
436
461
|
|
|
437
462
|
```ts
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
463
|
+
tracking: {
|
|
464
|
+
request: {
|
|
465
|
+
allowedTracingUrls: [
|
|
466
|
+
url => new URL(url).origin === 'https://api.example.com',
|
|
467
|
+
/^https:\/\/[^/]+\.internal\.example\.com\//,
|
|
468
|
+
],
|
|
443
469
|
},
|
|
444
|
-
}
|
|
470
|
+
}
|
|
445
471
|
```
|
|
446
472
|
|
|
447
|
-
|
|
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
|
|
448
478
|
|
|
449
|
-
|
|
479
|
+
Fetch/XHR 与静态资源共用一个 Resource PerformanceObserver:
|
|
450
480
|
|
|
451
|
-
|
|
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` 的请求:
|
|
452
489
|
|
|
453
490
|
```ts
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
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;
|
|
463
502
|
},
|
|
464
503
|
},
|
|
465
504
|
},
|
|
466
|
-
}
|
|
505
|
+
}
|
|
467
506
|
```
|
|
468
507
|
|
|
469
|
-
|
|
508
|
+
**产出遥测**:Log `browser.request.body`,错误请求为 ERROR,`capture: 'all'` 下成功请求为 INFO。
|
|
470
509
|
|
|
471
|
-
|
|
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 配置不生效。
|
|
472
516
|
|
|
473
|
-
|
|
517
|
+
## websocket
|
|
474
518
|
|
|
475
|
-
|
|
519
|
+
`tracking.websocket` 默认关闭。开启后用 Proxy 包装 `window.WebSocket`,保留静态常量、`instanceof` 与子类化行为。
|
|
476
520
|
|
|
477
521
|
```ts
|
|
478
522
|
new BkOpenTelemetry({
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
},
|
|
523
|
+
application: { name: 'realtime-demo' },
|
|
524
|
+
transport: { endpoint: 'https://collector.example.com' },
|
|
525
|
+
tracking: { websocket: true },
|
|
482
526
|
});
|
|
483
527
|
```
|
|
484
528
|
|
|
485
|
-
|
|
529
|
+
**产出遥测**:
|
|
486
530
|
|
|
487
|
-
|
|
488
|
-
|
|
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`:记录错误阶段和关闭详情。
|
|
489
536
|
|
|
490
|
-
|
|
491
|
-
socket.send(JSON.stringify({ type: 'ping' }));
|
|
492
|
-
});
|
|
493
|
-
```
|
|
537
|
+
插件不读取消息内容,只计算数量和字节数。超过 64KB 的字符串使用 `string.length` 近似字节数,避免编码开销;CJK/emoji 会低估。相同 URL 的错误 Log 在 60 秒内最多 5 条,Error Counter 不受节流影响。
|
|
494
538
|
|
|
495
|
-
|
|
539
|
+
SDK shutdown 后新建连接不再采集;已存在连接上的包装会保留,但回调立即返回。若其他库后来替换了 `window.WebSocket`,shutdown 不会强行覆盖后来者。
|
|
496
540
|
|
|
497
|
-
|
|
541
|
+
## 与额外 instrumentation 的关系
|
|
498
542
|
|
|
499
|
-
|
|
500
|
-
export const requestWithRum = async <T>(url: string, init?: RequestInit): Promise<T> => {
|
|
501
|
-
const span = bkOT.startSpan('custom.biz_request', {
|
|
502
|
-
'biz.request.url': url.replace(/\/\d+/g, '/:id'),
|
|
503
|
-
'biz.request.method': init?.method || 'GET',
|
|
504
|
-
});
|
|
543
|
+
`extensions.instrumentations` 适合已有标准 OpenTelemetry instrumentation。不要再注册覆盖 Fetch/XHR 或用户交互的 instrumentation,否则可能与内置 request/action 重复 patch、重复 Span。
|
|
505
544
|
|
|
506
|
-
|
|
507
|
-
const response = await fetch(url, init);
|
|
508
|
-
span.setAttribute('http.response.status_code', response.status);
|
|
509
|
-
return response.json() as Promise<T>;
|
|
510
|
-
} catch (error) {
|
|
511
|
-
span.recordException(error as Error);
|
|
512
|
-
throw error;
|
|
513
|
-
} finally {
|
|
514
|
-
span.end();
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
```
|
|
545
|
+
需要 Session/View、`emitLog()`、页面活动或 RUM 归一字段时,优先写自定义插件,见[内置采集与扩展](./concepts.md)与[自定义插件](./custom-plugin.md)。
|
|
@@ -24,7 +24,7 @@ new BkOpenTelemetry({
|
|
|
24
24
|
|
|
25
25
|
## 属性脱敏
|
|
26
26
|
|
|
27
|
-
`privacy.redactAttributes`
|
|
27
|
+
`privacy.redactAttributes` 会处理通过 SDK `startSpan()`、`emitLog()` 以及内置插件显式应用的属性,适合删除 authorization、手机号、邮箱等字段。
|
|
28
28
|
|
|
29
29
|
```ts
|
|
30
30
|
new BkOpenTelemetry({
|
|
@@ -40,6 +40,10 @@ new BkOpenTelemetry({
|
|
|
40
40
|
});
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
第三方 OpenTelemetry instrumentation 自己生成的 Span 属性不保证经过这一构造路径。需要统一清理第三方 Span 时,在 `tracking.beforeSend` 做最终兜底;该 Hook 作用于 Span/Log,不作用于 Metric。
|
|
44
|
+
|
|
45
|
+
`redactAttributes` 应返回完整可用的属性对象,不要只返回被修改的单个字段。
|
|
46
|
+
|
|
43
47
|
## 公共属性
|
|
44
48
|
|
|
45
49
|
`context.attributes` 提供四类 hook:
|
|
@@ -42,18 +42,18 @@
|
|
|
42
42
|
| span 名 | span_type | 来源 | 关键属性 | 备注 |
|
|
43
43
|
| --- | --- | --- | --- | --- |
|
|
44
44
|
| `browser.view` | `document` / `route` | View 管理器 | `view.name`、`view.loading_time`、`view.loading_time.source`、`url.previous`、`event.source`、`view.end_reason` | 有持续时间,下一次 View 或 pagehide 时结束 |
|
|
45
|
-
| `
|
|
45
|
+
| `browser.resource` | `resource` | Fetch/XHR request 采集 | `resource.type=fetch\|xhr`、`resource.url`、`resource.method`、`resource.status_code`、网络阶段属性 | span kind 为 CLIENT;Fetch/XHR 共用同一实现 |
|
|
46
46
|
| `browser.resource` | `resource` | resource 插件 | `resource.type`、`resource.url`、`resource.duration`、网络阶段、`resource.render_blocking_status`、`resource.protocol`、`resource.cache.hit` | 仅静态资源,跳过 Fetch/XHR |
|
|
47
47
|
| `browser.web_vital` | `vital` | webVitals 插件 | `vital.metric`、`vital.value`、`vital.rating`、`vital.id`、`rum.navigation.type`、`vital.<lcp\|cls\|inp\|fcp\|ttfb>.*` | 每个指标一条 |
|
|
48
48
|
| `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 最多一条 |
|
|
49
|
-
| `browser.error` | `error` | error 插件(`window.error`) | `exception
|
|
50
|
-
| `browser.unhandledrejection` | `error` | error 插件(Promise 异常) | `exception
|
|
51
|
-
| `browser.resource_error` | `error` | error 插件(资源加载失败) | `exception
|
|
49
|
+
| `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 |
|
|
50
|
+
| `browser.unhandledrejection` | `error` | error 插件(Promise 异常) | `exception.fingerprint`、`error.source=unhandledrejection` | 完整异常写入标准 `exception` Span Event |
|
|
51
|
+
| `browser.resource_error` | `error` | error 插件(资源加载失败) | `exception.fingerprint`、`error.source=resource`、`url.full`、`html.tag` | 完整异常写入标准 `exception` Span Event |
|
|
52
52
|
| `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`、`target_value` | LoAF 脚本详情写入 `long_task.script` Span Event |
|
|
53
|
-
| `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.
|
|
53
|
+
| `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`(窗口首条) | |
|
|
54
54
|
| `websocket.connect` | `custom` | websocket 插件(仅建连阶段) | `url.full`、`url.scheme`、`server.address`、`network.protocol.name=websocket`、`target_domain` | 长连接生命周期不绑定 span |
|
|
55
55
|
| `action.click` / `action.custom` | `action` | action 插件 / `reportAction()` | `action.id/name/type/target.*`、`action.loading_time`、`action.frustration.*`、`action.*.count` | 自动点击或手动动作;挫败信号仅自动点击 |
|
|
56
|
-
| `custom.<name>` | `custom` | `reportCustomEvent()` / 自定义插件 | `rum.custom.name`、业务自定义属性 | 带 `error`
|
|
56
|
+
| `custom.<name>` | `custom` | `reportCustomEvent()` / 自定义插件 | `rum.custom.name`、业务自定义属性 | 带 `error` 时记录 exception、设置错误 Status/Result,`span_type` 仍为 `custom` |
|
|
57
57
|
|
|
58
58
|
## Metric 清单
|
|
59
59
|
|
|
@@ -63,6 +63,8 @@
|
|
|
63
63
|
| `browser.web_vital.duration` | Histogram | `ms` | 同上(FCP/INP/LCP/TTFB 靠 `vital.metric` 区分) | webVitals |
|
|
64
64
|
| `browser.view.loading_time` | Histogram | `ms` | `view.url_path_group`、`view.loading_type` | View 管理器,View 结束时记录最终值 |
|
|
65
65
|
| `browser.blank_screen.count` | Counter | - | `view.url_path_group`、`blank_screen.root_selector`、`blank_screen.reason` | blankScreen |
|
|
66
|
+
| `browser.error.count` | Counter | - | `view.url_path_group`、`error.source`、`error.subtype` | error,span 节流前精确累计 |
|
|
67
|
+
| `browser.csp_violation.count` | Counter | - | `view.url_path_group`、`csp.disposition`、`csp.effective_directive` | cspViolation,span 节流前精确累计 |
|
|
66
68
|
| `browser.long_task.count` | Counter | - | `view.url_path_group`、`long_task.entry_type` | longTask |
|
|
67
69
|
| `browser.long_task.duration` | Histogram | `ms` | 同上 | longTask |
|
|
68
70
|
| `browser.long_task.blocking_duration` | Histogram | `ms` | 同上 | longTask,仅 LoAF |
|
|
@@ -71,7 +73,7 @@
|
|
|
71
73
|
| `browser.websocket.error.count` | Counter | - | `server.address`、`url.scheme`、`websocket.error.phase`(connect/runtime) | websocket |
|
|
72
74
|
| `browser.websocket.connect.duration` | Histogram | `ms` | `server.address`、`url.scheme` | websocket,仅成功建连 |
|
|
73
75
|
|
|
74
|
-
> 各 metric 只会合并 `context.attributes.metric` hook 返回的自定义低基数维度,不会合并 `context.attributes.page`,也不会携带 `session.id`、`view.id` 或 `action.id`。精确 View 关联请查询对应 span 或 View Snapshot Log。**metric 维度务必保持低基数**,不要把 URL、订单号、用户输入等放进来。
|
|
76
|
+
> 各 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、订单号、用户输入等放进来。
|
|
75
77
|
|
|
76
78
|
## Log 事件清单
|
|
77
79
|
|
|
@@ -80,8 +82,8 @@
|
|
|
80
82
|
| `session.start` | INFO | session 插件(首次新建) | `session.id`、`session.start_time`、`session.rotate.reason=init` |
|
|
81
83
|
| `session.rotate` | INFO | session 插件(轮换) | + `session.previous_id`、`session.rotate.reason`(`inactivity` / `maxLifetime`) |
|
|
82
84
|
| `browser.view` | INFO | View 管理器 | `view.snapshot.type=create\|update\|final`、`view.document_version`、`view.duration`、`view.is_active`、`view.loading_time` |
|
|
83
|
-
| `browser.request.body` | ERROR(错误请求)/ INFO(`capture: 'all'` 的成功请求) | request
|
|
84
|
-
| `websocket.error` | ERROR | websocket 插件 | `url.full`、`websocket.error.phase`、`websocket.error.
|
|
85
|
+
| `browser.request.body` | ERROR(错误请求)/ INFO(`capture: 'all'` 的成功请求) | Fetch/XHR request patch(仅显式配置 `request.body`) | 通过 OTel Log Context 关联 Trace/Span;属性含 `request.body` / `response.body`、`*.body.content_type`、`*.body.truncated` |
|
|
86
|
+
| `websocket.error` | ERROR | websocket 插件 | `url.full`、`websocket.error.phase`、`websocket.error.window_occurrence_index` |
|
|
85
87
|
| `websocket.close` | INFO | websocket 插件 | `websocket.close.code`、`websocket.close.reason`、`websocket.close.was_clean` |
|
|
86
88
|
|
|
87
89
|
> 错误主数据统一走 `error` span(见 Span 清单),SDK **不再**为同一个错误额外 emit error log,避免重复计数。
|
|
@@ -162,7 +164,7 @@
|
|
|
162
164
|
| `exception.fingerprint` | string | 节流分组指纹(djb2 hash) |
|
|
163
165
|
| `error.source` | string | `window.error`/`unhandledrejection`/`resource`/`csp` |
|
|
164
166
|
| `error.handled` | boolean | 是否被业务捕获(自动采集恒为 `false`) |
|
|
165
|
-
| `error.
|
|
167
|
+
| `error.window_occurrence_index` | number | 当前节流窗口内该已上报 span 的触发序号;总量查询 `browser.error.count` |
|
|
166
168
|
| `error.cross_origin` | boolean | 跨域脚本错误(`Script error.`) |
|
|
167
169
|
| `code.filepath` / `code.lineno` / `code.column` | string/number | JS 错误位置 |
|
|
168
170
|
| `html.tag` | string | 资源错误的元素标签 |
|
|
@@ -223,7 +225,7 @@
|
|
|
223
225
|
| `csp.source_file` | string | 触发脚本(已脱敏) |
|
|
224
226
|
| `csp.line_number` / `csp.column_number` | number | 位置 |
|
|
225
227
|
| `csp.status_code` | number | 状态码 |
|
|
226
|
-
| `csp.fingerprint` / `csp.
|
|
228
|
+
| `csp.fingerprint` / `csp.window_occurrence_index` | string/number | 节流指纹与该已上报 span 的窗口触发序号 |
|
|
227
229
|
| `csp.original_policy` | string | 完整策略,仅窗口首条携带 |
|
|
228
230
|
|
|
229
231
|
### WebSocket
|
|
@@ -235,7 +237,7 @@
|
|
|
235
237
|
| `network.protocol.name` | string | 固定 `websocket` |
|
|
236
238
|
| `websocket.direction` | string | `in` / `out`(仅 metric) |
|
|
237
239
|
| `websocket.error.phase` | string | `connect` / `runtime` |
|
|
238
|
-
| `websocket.error.
|
|
240
|
+
| `websocket.error.window_occurrence_index` | number | 该已上报错误日志在节流窗口内的触发序号;总量查询 `browser.websocket.error.count` |
|
|
239
241
|
| `websocket.close.code` / `websocket.close.reason` / `websocket.close.was_clean` | mixed | 关闭事件详情 |
|
|
240
242
|
|
|
241
243
|
### 白屏
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
|
|
2
|
+
|
|
3
|
+
# 传输与采样
|
|
4
|
+
|
|
5
|
+
## Endpoint
|
|
6
|
+
|
|
7
|
+
`transport.endpoint` 是可选根地址。未配置独立地址的已开启信号会基于它生成 `/v1/rum`、`/v1/metrics`、`/v1/logs`;单信号 `endpoint` 是完整 URL,不再拼接路径。
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
new BkOpenTelemetry({
|
|
11
|
+
application: { name: 'demo' },
|
|
12
|
+
transport: {
|
|
13
|
+
endpoint: 'https://collector.example.com',
|
|
14
|
+
token: 'report-token',
|
|
15
|
+
signals: {
|
|
16
|
+
traces: {
|
|
17
|
+
endpoint: 'https://trace.example.com/v1/rum',
|
|
18
|
+
processor: 'batch',
|
|
19
|
+
batch: {
|
|
20
|
+
maxQueueSize: 2048,
|
|
21
|
+
maxExportBatchSize: 512,
|
|
22
|
+
scheduledDelayMillis: 5000,
|
|
23
|
+
exportTimeoutMillis: 30000,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
metrics: { endpoint: 'https://metric.example.com/v1/metrics', intervalMillis: 60_000 },
|
|
27
|
+
logs: { endpoint: 'https://log.example.com/v1/logs' },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 独立信号开关
|
|
34
|
+
|
|
35
|
+
三类信号默认全部开启。设为 `false` 时,不创建对应 exporter、processor 或 metric reader:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
new BkOpenTelemetry({
|
|
39
|
+
application: { name: 'trace-only-demo' },
|
|
40
|
+
transport: {
|
|
41
|
+
signals: {
|
|
42
|
+
traces: { endpoint: 'https://trace.example.com/v1/rum' },
|
|
43
|
+
metrics: false,
|
|
44
|
+
logs: false,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
校验规则:
|
|
51
|
+
|
|
52
|
+
- 至少开启一种信号,三类不能全部为 `false`。
|
|
53
|
+
- 每个开启信号必须有独立 endpoint,或能回退到根 `transport.endpoint`。
|
|
54
|
+
- 关闭 Trace 后不记录 Span,也不会向 `allowedTracingUrls` 注入 `traceparent`。
|
|
55
|
+
- 关闭 Metric 后不启动周期导出定时器。
|
|
56
|
+
- 关闭 Log 不影响 Session/View 上下文维护,但不会产生 Session、View Snapshot、HTTP body 等 Log。
|
|
57
|
+
|
|
58
|
+
只开启 Metric 时没有精确 `view.id` 下钻链路;需要从指标定位具体 View 时,至少开启 Trace。
|
|
59
|
+
|
|
60
|
+
请求头优先级:`token` 生成的 Authorization < `transport.headers` < 单 signal `headers`。
|
|
61
|
+
|
|
62
|
+
浏览器 OTLP HTTP exporter 负责实际传输,SDK 在 `pagehide` 和页面进入 hidden 时触发 flush。`shutdown()` 会先结束 View 和插件,再 flush final Snapshot,最后关闭 provider。
|
|
63
|
+
|
|
64
|
+
## Session 级确定性采样
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
new BkOpenTelemetry({
|
|
68
|
+
application: { name: 'demo' },
|
|
69
|
+
transport: { endpoint: 'https://collector.example.com' },
|
|
70
|
+
session: { sampleRate: 0.05 },
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- `1` 表示全量,`0` 表示全部丢弃。
|
|
75
|
+
- 决定由 `application.name + session.id` 的稳定 hash 得出。
|
|
76
|
+
- 采样决定不写额外 storage;同一 Session 内 span/log/metric 决定一致。
|
|
77
|
+
- Session 续期后使用新 ID 重新计算。
|
|
78
|
+
|
|
79
|
+
Metric exporter 只接受带内部采样标记的数据点,并在传输前移除该标记。Metric 只保留低基数 `view.url_path_group`,精确 View 关联由 span/log/View Snapshot 的 `view.id` 提供。
|