@blueking/open-telemetry 0.0.15 → 0.0.16

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.
@@ -0,0 +1,100 @@
1
+ <!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
2
+
3
+ # 能力矩阵
4
+
5
+ 本页回答四个问题:SDK 能采什么、默认是否启用、依赖哪个浏览器能力、最终上报什么。精确名称与属性请继续查[遥测参考](./telemetry-reference.md)。
6
+
7
+ ## 总览
8
+
9
+ | 能力 | 配置入口 | 默认 | 浏览器入口 | Trace | Metric | Log |
10
+ | --- | --- | --- | --- | --- | --- | --- |
11
+ | Session | `session` | 必选基础能力 | `localStorage`、用户活动、页面可见性 | — | — | `session.start` / `session.rotate` |
12
+ | View | `tracking.view` | 自动模式 | Navigation Timing、History、hash、BFCache、DOM Mutation | `browser.view` | `browser.view.loading_time` | `browser.view` Snapshot |
13
+ | Fetch/XHR | `tracking.request` | 开 | `fetch`、`XMLHttpRequest`、Resource Timing | `browser.resource` | — | 可选 `browser.request.body` |
14
+ | 静态资源 | `tracking.resource` | 开 | Resource PerformanceObserver | `browser.resource` | — | — |
15
+ | JS / Promise / 资源错误 | `tracking.error` | 开 | `error`、`unhandledrejection` | 三类 `browser.*error` | — | — |
16
+ | Web Vitals | `tracking.webVitals` | 开 | `web-vitals`、Layout Shift、Event Timing | `browser.web_vital` | 两个 Histogram | — |
17
+ | Action | `tracking.action` | 开 | click、DOM、请求与活动总线 | `action.click` | — | — |
18
+ | 手动 Action | `reportAction()` | 可调用 | 业务调用 | `action.custom` | — | — |
19
+ | 自定义事件 | `reportCustomEvent()` | 可调用 | 业务调用 | `custom.<name>` | — | — |
20
+ | 白屏 | `tracking.blankScreen` | 开 | DOM 命中测试、View 活动 | `browser.blank_screen` | `browser.blank_screen.count` | — |
21
+ | 设备 | `tracking.device` | 开 | UA、UA-CH、Screen、Network Information | 作为公共属性 | — | 作为公共属性 |
22
+ | Long Task | `tracking.longTask` | 关 | Long Animation Frames / Long Tasks | `browser.long_task` | 三个聚合指标 | — |
23
+ | WebSocket | `tracking.websocket` | 关 | `WebSocket` Proxy | `websocket.connect` | 四个聚合指标 | error / close |
24
+ | CSP | `tracking.cspViolation` | 关 | `securitypolicyviolation` | `csp.violation` | — | — |
25
+ | 自定义插件 | `extensions.plugins` / `use()` | 无 | 由插件决定 | 支持 | 无稳定公共辅助 API | 推荐 `emitLog()` |
26
+ | OTel instrumentation | `extensions.instrumentations` / `useInstrumentation()` | 无 | 由 instrumentation 决定 | 支持 | 无稳定支持 | 取决于实现 |
27
+
28
+ “默认开”表示获得 Consent 且 SDK 已启动后启用。是否真正导出还受 `enabled`、Session 采样、Session/View 有效性和单信号开关控制。
29
+
30
+ ## 能力边界
31
+
32
+ ### SDK 直接负责
33
+
34
+ - 创建和轮换 Session,划分初始加载、SPA、BFCache、手动和 Session 续期 View。
35
+ - 统一 patch Fetch/XHR;请求 span、活动计数、Trace Header、Resource Timing 和 Body 采集共用同一生命周期。
36
+ - 把浏览器事件归一为 `span_type`、`result`、`error_type`、`duration_bucket`、`target_*` 等字段。
37
+ - 自动为 Span/Log 关联 `session.id`、`view.id`,为 Metric 保留低基数 `view.url_path_group`。
38
+ - 在 exporter 前执行采样、有效上下文、自上报请求和 `tracking.beforeSend` 过滤。
39
+
40
+ ### SDK 不负责
41
+
42
+ - 不聚合 `session.duration`、影响用户数、地理信息、Trace 关键路径等后端指标。
43
+ - 不自动判断业务字段是否敏感,也不 hash `user.id`。
44
+ - 不默认采集 HTTP 请求/响应 Body。
45
+ - 不把唯一的 `session.id`、`view.id`、`action.id` 放入 Metric labels。
46
+ - 不保证浏览器未暴露的数据,例如缺少 `Timing-Allow-Origin` 的跨域资源网络阶段。
47
+
48
+ ## 默认开启与关闭
49
+
50
+ ```ts
51
+ new BkOpenTelemetry({
52
+ application: { name: 'capability-demo' },
53
+ transport: { endpoint: 'https://collector.example.com' },
54
+ tracking: {
55
+ request: true,
56
+ resource: true,
57
+ error: true,
58
+ webVitals: true,
59
+ action: true,
60
+ blankScreen: true,
61
+ device: true,
62
+ longTask: false,
63
+ websocket: false,
64
+ cspViolation: false,
65
+ },
66
+ });
67
+ ```
68
+
69
+ Session 与 View 是导出有效性边界,不提供关闭开关。`tracking.view` 只配置自动/手动模式、稳定耗时和路由分组。
70
+
71
+ ## 浏览器降级行为
72
+
73
+ | 条件 | 行为 |
74
+ | --- | --- |
75
+ | 无 `PerformanceObserver` 或不支持 `resource` | 跳过静态资源观察和请求网络阶段匹配;Fetch/XHR 本身仍可采集 |
76
+ | 不支持 Long Animation Frames | Long Task 插件尝试回退 Long Tasks API |
77
+ | 两种 Long Task API 都不支持 | 跳过 Long Task,不抛出业务异常 |
78
+ | 跨域资源无 `Timing-Allow-Origin` | 只保留浏览器可见的总耗时/体积,不伪造网络阶段 |
79
+ | 无 Network Information / UA-CH | 只写入可获得的设备字段 |
80
+ | 无 `localStorage` 或访问失败 | Session/Device 持久化退回内存 |
81
+ | 插件初始化抛错 | 隔离该插件;`debug: true` 时输出 warning,其余插件继续启动 |
82
+
83
+ ## 成本与隐私提示
84
+
85
+ | 能力 | 主要成本/风险 | 建议 |
86
+ | --- | --- | --- |
87
+ | `session.sampleRate` | 决定三类信号总体数据量 | 按应用容量设置;排障临时设为 `1` |
88
+ | Metric 自定义维度 | 高基数会放大时序数量 | 只放应用、租户类别、路由模板等低基数字段 |
89
+ | Request Body | 可能包含凭证、个人数据,且增加网络体积 | 默认关闭;开启时限制类型/大小并强制脱敏 |
90
+ | Action 文本命名 | DOM 文本可能包含用户输入 | 保持 `nameCollection: 'explicit'`,关键元素使用 `data-bk-action-name` |
91
+ | Device 持久 ID | 支持跨 Session 关联 | 默认不持久化;需取得合规依据后再开启 |
92
+ | Long Task | 产生 Span 与脚本归因信息 | 仅性能分析场景开启,结合采样控制 |
93
+ | WebSocket | Proxy 全局构造器并统计消息字节 | 同页面单实例;不采集消息内容 |
94
+
95
+ ## 下一步
96
+
97
+ - 配置每项能力:[配置参考](./configuration.md)
98
+ - 理解启动与上报链路:[架构与数据流](./architecture.md)
99
+ - 查看单个插件实现行为:[插件总览](./plugins.md)
100
+ - 查看精确遥测名称和属性:[遥测参考](./telemetry-reference.md)
@@ -10,7 +10,7 @@
10
10
 
11
11
  - Trace:用于描述一次有起止时间的行为,例如页面访问、接口请求、资源加载、用户点击、长任务。
12
12
  - Metric:用于描述可聚合的数值,例如 Web Vitals、长任务数量、WebSocket 消息大小、空白屏结果。
13
- - Log:用于描述离散事件或诊断信息,例如 CSP 违规、Session 生命周期和 WebSocket 状态。
13
+ - Log:用于描述离散事件或诊断信息,例如 Session 生命周期、View Snapshot、请求 Body 和 WebSocket 状态。
14
14
 
15
15
  示例:手动创建一个业务 span。
16
16
 
@@ -49,6 +49,7 @@ bkOT.setUser({
49
49
  示例:手动模式由业务路由系统创建 View。
50
50
 
51
51
  ```ts
52
+ // 前提:autoStart: false,且已经 await bkOT.start() 建立 Session。
52
53
  bkOT.startView({
53
54
  name: '商品详情',
54
55
  url: window.location.href,
@@ -60,10 +61,10 @@ bkOT.startView({
60
61
 
61
62
  SDK 将能力分为两类:
62
63
 
63
- 1. 内置采集:`tracking.request` 使用统一的 Fetch/XHR 生命周期实现,负责 patch 浏览器 API、创建 CLIENT Span、Trace Header 和请求 Performance Timing 匹配。
64
+ 1. 内置采集:`tracking.request` 使用 SDK 自有的统一 Fetch/XHR 生命周期,负责 patch 浏览器 API、创建 `browser.resource` CLIENT Span、Trace Header 和请求 Performance Timing 匹配。
64
65
  2. RUM 插件:View、Session、`resource`、`error`、`webVitals`、`blankScreen`、`device` 等,负责主动产生 RUM 归一数据。
65
66
 
66
- 用户交互统一由 SDK 的 `action` 插件采集,避免与官方 user-interaction instrumentation 重复上报。
67
+ 用户交互统一由 SDK 的 `action` 插件采集。接入额外 instrumentation 时,应避免再注册覆盖 Fetch/XHR 或用户交互的探针,以免重复上报。
67
68
 
68
69
  ```ts
69
70
  new BkOpenTelemetry({
@@ -80,7 +81,7 @@ new BkOpenTelemetry({
80
81
 
81
82
  ## 采样
82
83
 
83
- `session.sampleRate` 是会话级确定性采样。决定由 `application.name + session.id` 的稳定 hash 得出,同一 Session 的三类信号保持一致。插件会维护必要的页面生命周期,但未命中时 sampler/processor 不导出其数据,`reportAction()` 和 `reportCustomEvent()` 直接丢弃。
84
+ `session.sampleRate` 是会话级确定性采样。决定由 `application.name + session.id` 的稳定 hash 得出,同一 Session 的三类信号保持一致。插件仍会维护必要的浏览器生命周期,但未命中时创建或导出路径会丢弃数据,`reportAction()` 和 `reportCustomEvent()` 直接返回。
84
85
 
85
86
  示例:生产环境按 10% 会话采样。
86
87
 
@@ -150,4 +151,6 @@ new BkOpenTelemetry({
150
151
 
151
152
  内置 Fetch/XHR 不再基于官方 instrumentation 叠加适配,而是由单一请求生命周期实现,避免重复 patch、重复活动计数及私有 `_addHeaders/_patchSend` 依赖。
152
153
 
154
+ 当前扩展 instrumentation 的稳定能力边界是 Trace:Filtering Span Processor 会在 Span 创建时补充有效 RUM 上下文。Metric exporter 要求 SDK 内部采样标记,而包未公开对应 helper,因此第三方 instrumentation 产生的 Metric 默认会被过滤,不应作为已支持的扩展能力。
155
+
153
156
  扩展必须在 `start()` 前注册;动态 Consent 重新授权时,插件可能再次执行 `init()`,所以插件的 `shutdown()` 应完整释放副作用。
@@ -1,137 +1,191 @@
1
1
  <!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
2
2
 
3
- # 配置总览
3
+ # 配置参考
4
4
 
5
- SDK 入口按职责分为 `application`、`transport`、`session`、`tracking`、`context`、`privacy`、`extensions`。`application.name` 与 `transport` 必填;根 `transport.endpoint` 可由所有已开启信号的独立 endpoint 取代。
5
+ `BkOpenTelemetry` 只接受当前 `BkOTOptions` 结构。`application.name` 与 `transport` 必填;所有已启用信号必须能解析到有效 Endpoint。
6
6
 
7
7
  ```ts
8
- const bkOT = new BkOpenTelemetry({
9
- application: {
10
- name: 'bk-monitor-web',
11
- environment: 'production',
12
- version: '1.4.2',
13
- },
14
- transport: {
15
- endpoint: 'https://rum-collector.example.com',
16
- token: 'report-token',
17
- signals: {
18
- traces: { processor: 'batch', batch: { maxQueueSize: 2048 } },
19
- metrics: { intervalMillis: 60_000 },
20
- },
21
- },
22
- session: {
23
- sampleRate: 0.2,
24
- },
25
- tracking: {
26
- view: {
27
- tracking: 'auto',
28
- getPathGroup: url => new URL(url, location.href).pathname.replace(/\/\d+/g, '/:id'),
29
- },
30
- request: {
31
- allowedTracingUrls: ['https://api.example.com'],
32
- excludedUrls: [/\/health$/],
33
- },
34
- longTask: false,
35
- websocket: false,
36
- },
37
- context: {
38
- user: { id: 'user-12345' },
39
- attributes: {
40
- page: () => ({ 'biz.space_id': window.__BK_SPACE_ID__ }),
41
- },
42
- },
43
- privacy: {
44
- trackingConsent: 'granted',
45
- redactAttributes: attributes => attributes,
46
- },
47
- extensions: {
48
- plugins: [],
49
- instrumentations: [],
50
- },
51
- });
8
+ import { BkOpenTelemetry, type BkOTOptions } from '@blueking/open-telemetry';
9
+
10
+ const options: BkOTOptions = {
11
+ application: { name: 'bk-monitor-web' },
12
+ transport: { endpoint: 'https://rum-collector.example.com' },
13
+ };
14
+
15
+ const bkOT = new BkOpenTelemetry(options);
52
16
  ```
53
17
 
54
18
  ## 顶层配置
55
19
 
56
- | 配置 | 默认值 | 说明 |
57
- | --- | --- | --- |
58
- | `application.name` | 无 | 必填,写入 `service.name` |
59
- | `application.environment` | `production` | 写入 `deployment.environment.name` |
60
- | `application.version` | 无 | 写入 `service.version` |
61
- | `transport.endpoint` | 无 | 上报根地址;已开启信号没有独立 endpoint 时必填 |
62
- | `transport.signals.traces` | `{}` | Trace 配置;设为 `false` 关闭 |
63
- | `transport.signals.metrics` | `{}` | Metric 配置;设为 `false` 关闭 |
64
- | `transport.signals.logs` | `{}` | Log 配置;设为 `false` 关闭 |
65
- | `session.sampleRate` | `1` | Session 级确定性采样率 |
66
- | `tracking.view.tracking` | `auto` | 自动或手动 View |
67
- | `tracking.view.loadingTime` | `true` | 自动计算 View loading time |
68
- | `privacy.trackingConsent` | `granted` | 初始化授权状态 |
69
- | `enabled` | `true` | 是否启用 SDK |
70
- | `autoStart` | `true` | 构造后自动启动 |
71
- | `debug` | `false` | 输出 exporter 与插件调试信息 |
72
-
73
- Session 固定为 15 分钟无活动过期、4 小时最长生命周期。View 和 Session 是 RUM 关联边界,不能作为普通插件关闭。
74
-
75
- ## 内置采集开关
76
-
77
- 内置能力全部位于 `tracking`:
78
-
79
- | 配置 | 默认 | 说明 |
80
- | --- | --- | --- |
81
- | `view` | 开 | 初始加载、SPA、BFCache、手动 View |
82
- | `request` | 开 | Fetch/XHR 请求 span、Trace Header、body |
83
- | `resource` | 开 | 静态资源 span;PerformanceObserver 始终为 View 活动和请求 timing 服务 |
84
- | `error` | 开 | JS、Promise 与资源错误 |
85
- | `webVitals` | 开 | FCP/LCP/TTFB 及 View 级 CLS/INP |
86
- | `blankScreen` | 开 | 白屏检测 |
87
- | `device` | 开 | 浏览器、OS、屏幕与网络信息 |
88
- | `action` | 开 | 点击 Action 与活动聚合 |
89
- | `longTask` | 关 | LoAF/Long Task |
90
- | `websocket` | 关 | WebSocket 指标 |
91
- | `cspViolation` | 关 | CSP 违规 |
20
+ | 字段 | 类型 | 默认 | 说明 |
21
+ | --- | --- | --- | --- |
22
+ | `application` | `BkOTApplicationConfig` | 必填 | 应用 Resource 标识 |
23
+ | `transport` | `BkOTTransportConfig` | 必填 | 三类 OTLP HTTP 导出链路 |
24
+ | `session` | `BkOTSessionConfig` | `{ sampleRate: 1 }` | Session 存储和确定性采样 |
25
+ | `tracking` | `BkOTTrackingConfig` | `{}` | 内置采集、View 与事件 Hook |
26
+ | `context` | `BkOTContextConfig` | 无 | 初始用户与公共属性 Hook |
27
+ | `privacy` | `BkOTPrivacyConfig` | Consent 已授权、默认 URL 脱敏 | 授权、URL 和属性脱敏 |
28
+ | `extensions` | `BkOTExtensionsConfig` | 空数组 | 自定义 RUM 插件与 OTel instrumentation |
29
+ | `enabled` | `boolean` | `true` | `false` 时 `start()` 不安装采集能力 |
30
+ | `autoStart` | `boolean` | `true` | 构造后异步启动 |
31
+ | `debug` | `boolean` | `false` | 输出 exporter 数据和可诊断 warning |
92
32
 
93
- ```ts
94
- new BkOpenTelemetry({
95
- application: { name: 'demo' },
96
- transport: { endpoint: 'https://rum-collector.example.com' },
97
- tracking: {
98
- request: false,
99
- blankScreen: false,
100
- longTask: { threshold: 80 },
101
- },
102
- });
103
- ```
33
+ ## application
104
34
 
105
- ## 请求配置
35
+ | 字段 | 类型 | 默认 | Resource Attribute |
36
+ | --- | --- | --- | --- |
37
+ | `name` | `string` | 必填且非空 | `service.name` |
38
+ | `environment` | `string` | `production` | `deployment.environment.name` |
39
+ | `version` | `string` | 无 | `service.version` |
106
40
 
107
- `tracking.request.allowedTracingUrls` 是严格白名单,同源请求也必须命中后才注入 `traceparent`。关闭 Trace 时不会注入。`excludedUrls` 命中后完全不采集。SDK 自身已开启 signal endpoint 始终排除。
41
+ SDK 还会固定写入 `rum.provider=blueking`、`rum.schema.version=1`、`telemetry.sdk.name=@blueking/open-telemetry` 和 `telemetry.sdk.language=webjs`。
42
+
43
+ ## transport
108
44
 
109
45
  ```ts
110
- new BkOpenTelemetry({
111
- application: { name: 'request-demo' },
112
- transport: { endpoint: 'https://rum-collector.example.com' },
113
- tracking: {
114
- request: {
115
- allowedTracingUrls: [/https:\/\/api\.example\.com/],
116
- excludedUrls: [/\/health(?:\?|$)/],
117
- beforeSend: (event, context) => {
118
- event.attributes['request.transport'] = context.type;
119
- return true;
120
- },
121
- body: {
122
- capture: 'errors',
123
- redact: ({ body }) => body.replace(/token=[^&]+/g, 'token=***'),
46
+ transport: {
47
+ endpoint: 'https://collector.example.com',
48
+ token: 'report-token',
49
+ headers: { 'X-Tenant': 'blueking' },
50
+ signals: {
51
+ traces: {
52
+ endpoint: 'https://trace.example.com/v1/rum',
53
+ processor: 'batch',
54
+ batch: {
55
+ maxQueueSize: 2048,
56
+ maxExportBatchSize: 512,
57
+ scheduledDelayMillis: 5000,
58
+ exportTimeoutMillis: 30000,
124
59
  },
60
+ timeoutMillis: 10_000,
61
+ concurrencyLimit: 10,
62
+ },
63
+ metrics: {
64
+ intervalMillis: 60_000,
125
65
  },
66
+ logs: {},
126
67
  },
127
- });
68
+ }
128
69
  ```
129
70
 
130
- 跨域注入 Trace Header 可能触发 CORS 预检,服务端需要放行 `traceparent`。
71
+ ### 根字段
72
+
73
+ | 字段 | 类型 | 默认 | 说明 |
74
+ | --- | --- | --- | --- |
75
+ | `endpoint` | `string` | 无 | 根地址,去掉末尾 `/` 后拼默认信号路径 |
76
+ | `token` | `string` | 无 | 生成 `Authorization: Bearer <token>` |
77
+ | `headers` | `Record<string,string>` | 无 | 所有信号的公共 Header |
78
+ | `signals` | `SignalExportersInputConfig` | 三类开启 | 单信号开关和覆盖项 |
79
+
80
+ 默认路径:Trace `/v1/rum`、Metric `/v1/metrics`、Log `/v1/logs`。单信号 `endpoint` 是完整 URL,不再拼路径。
81
+
82
+ Header 覆盖顺序为 `token` < 根 `headers` < 单信号 `headers`。同名字段由右侧配置覆盖。
83
+
84
+ ### 单信号字段
85
+
86
+ | 字段 | Trace | Metric | Log | SDK 默认 |
87
+ | --- | --- | --- | --- | --- |
88
+ | `endpoint` | 支持 | 支持 | 支持 | 回退根 Endpoint |
89
+ | `headers` | 支持 | 支持 | 支持 | 回退根 Header |
90
+ | `timeoutMillis` | 支持 | 支持 | 支持 | 交给 OTel exporter |
91
+ | `concurrencyLimit` | 支持 | 支持 | 支持 | 交给 OTel exporter |
92
+ | `processor` | `'batch' \| 'simple'` | — | — | `batch` |
93
+ | `batch` | `BkOTBatchConfig` | — | — | 交给 `BatchSpanProcessor` |
94
+ | `intervalMillis` | — | number | — | `60_000` |
95
+
96
+ `batch` 支持 `maxQueueSize`、`maxExportBatchSize`、`scheduledDelayMillis`、`exportTimeoutMillis`。未提供时使用 OpenTelemetry `BatchSpanProcessor` 默认值。
97
+
98
+ 校验规则:
99
+
100
+ - 三类信号不能全部为 `false`。
101
+ - 每个已开启信号必须配置单独 Endpoint,或能回退到根 `transport.endpoint`。
102
+ - 关闭 Trace 后不创建 Trace exporter/processor,不记录可导出的 Span,也不注入 `traceparent`。
103
+ - 关闭 Metric 后不创建 reader;关闭 Log 后不创建 log processor,Request Body 配置也不会产生 Log。
104
+
105
+ 更多行为见[传输与采样](./transport-sampling.md)。
106
+
107
+ ## session
108
+
109
+ | 字段 | 类型 | 默认 | 说明 |
110
+ | --- | --- | --- | --- |
111
+ | `sampleRate` | `number` | `1` | Session 确定性采样;有限数值限制到 `0..1`,非有限值回退 `1` |
112
+ | `storageKey` | `string` | 按应用名和 Endpoint host hash | Session localStorage key |
113
+
114
+ Session 固定为 15 分钟无活动过期、4 小时最长生命周期,不开放超时配置。localStorage 不可用时退回进程内存。
115
+
116
+ ## tracking.view
131
117
 
132
- ## 全局 beforeSend
118
+ | 字段 | 类型 | 默认 | 说明 |
119
+ | --- | --- | --- | --- |
120
+ | `tracking` | `'auto' \| 'manual'` | `auto` | 自动观察 History/hash,或由业务调用 `startView()` |
121
+ | `loadingTime` | `boolean` | `true` | 计算 View 页面活动稳定耗时 |
122
+ | `getPathGroup` | `(url) => string \| undefined` | URL pathname | 返回低基数 `view.url_path_group` |
123
+ | `excludedActivityUrls` | matcher 或 matcher[] | 无 | 命中请求/资源不延长 View/Action 活动窗口 |
133
124
 
134
- `tracking.beforeSend` 在 span/log 进入 exporter 前执行,可修改属性或返回 `false` 丢弃事件。内部 `bk.rum.sampled` 标记会在此之前移除。
125
+ URL matcher 支持字符串包含、`RegExp` 或 `(url) => boolean`。字符串使用 `url.includes(matcher)`,不等于 origin 精确匹配;安全白名单应使用 URL-aware 函数或带边界的正则。自动 View 只对 pathname 和非页内锚点 hash path 的变化切换,query-only 变化不切换。
126
+
127
+ ## tracking.request
128
+
129
+ `request` 可设为 `false` 完全关闭 Fetch/XHR patch;`true` 或 `{}` 使用默认配置。
130
+
131
+ | 字段 | 类型 | 默认 | 说明 |
132
+ | --- | --- | --- | --- |
133
+ | `excludedUrls` | matcher 或 matcher[] | 无 | 命中后不采集、不注入、不计入页面活动 |
134
+ | `allowedTracingUrls` | matcher 或 matcher[] | 无 | W3C Trace Context 显式白名单;同源请求也必须命中,推荐 URL-aware 函数 |
135
+ | `beforeSend` | `(event, context) => boolean \| void` | 无 | 修改请求属性;返回 `false` 丢弃 Span,并跳过该请求的 Body Log |
136
+ | `body` | `BkOTRequestBodyConfig` | 关闭 | 请求/响应 Body Log |
137
+
138
+ Request Body:
139
+
140
+ | 字段 | 类型 | 默认 | 说明 |
141
+ | --- | --- | --- | --- |
142
+ | `capture` | `'errors' \| 'all'` | `errors` | 错误包括状态未知、0 或 `>=400` |
143
+ | `maxSize` | `number` | `10 * 1024` | 每个最终 Body 的最大字符数;无效值回退默认 |
144
+ | `allowedContentTypes` | `(string \| RegExp)[]` | text、json、urlencoded、graphql | Response 必须命中;无 Content-Type 的 Request 允许读取 |
145
+ | `redact` | `(payload) => string \| undefined` | 必填 | 返回脱敏文本;`undefined` 跳过当前 Body |
146
+
147
+ 默认不采集 Body。Body 只在 Log 信号开启时生效,不支持 FormData、ArrayBuffer 等不可安全文本化的内容。
148
+
149
+ ## tracking 内置能力
150
+
151
+ | 字段 | 类型 | 默认 | 参数 |
152
+ | --- | --- | --- | --- |
153
+ | `resource` | `boolean` | `true` | 无;`false` 只关闭静态资源 Span,Resource Observer 仍服务请求 timing/活动 |
154
+ | `error` | `boolean \| BkOTErrorPluginOptions` | `true` | `windowMs=60_000`、`maxPerWindow=5` |
155
+ | `webVitals` | `boolean` | `true` | 无 |
156
+ | `blankScreen` | `boolean \| BkOTBlankScreenPluginOptions` | `true` | 见下表 |
157
+ | `device` | `boolean \| BkOTDevicePluginOptions` | `true` | 见下表 |
158
+ | `action` | `boolean \| BkOTActionPluginOptions` | `true` | 见下表 |
159
+ | `longTask` | `boolean \| BkOTLongTaskPluginOptions` | `false` | `threshold=50`、`warningThreshold=100` ms |
160
+ | `websocket` | `boolean` | `false` | 无 |
161
+ | `cspViolation` | `boolean` | `false` | 无,内置同指纹 60 秒最多 5 条 |
162
+
163
+ Blank Screen:
164
+
165
+ | 字段 | 默认 | 说明 |
166
+ | --- | --- | --- |
167
+ | `rootSelector` | `body` | 应用挂载根节点 |
168
+ | `threshold` | `0.8` | 九点采样的空白比例,限制到 `0..1` |
169
+ | `checkDelay` | `1000` ms | 页面活动稳定后的首次检查延迟 |
170
+ | `confirmationDelay` | `200` ms | 两次候选白屏的确认间隔 |
171
+ | `ignoreSelectors` | 内置 loading/skeleton 选择器 | 自定义数组会替换内置数组 |
172
+
173
+ Action:
174
+
175
+ | 字段 | 默认 | 说明 |
176
+ | --- | --- | --- |
177
+ | `actionNameAttribute` | `data-bk-action-name` | 向上查找的显式动作名属性 |
178
+ | `maxDuration` | `10_000` ms | 单次 Action 最大活动窗口 |
179
+ | `nameCollection` | `explicit` | 默认只取显式属性,否则退回标签名;`text` 才读取可访问名称/DOM 文本 |
180
+
181
+ Device:
182
+
183
+ | 字段 | 默认 | 说明 |
184
+ | --- | --- | --- |
185
+ | `persistentId` | `false` | `false` 时 ID 只在当前实例稳定;`true` 写 localStorage |
186
+ | `storageKey` | 按应用名 hash | 仅持久 ID 使用 |
187
+
188
+ ## tracking.beforeSend
135
189
 
136
190
  ```ts
137
191
  tracking: {
@@ -142,84 +196,73 @@ tracking: {
142
196
  }
143
197
  ```
144
198
 
145
- ## 不再支持的旧入口
199
+ 该 Hook 在 Span/Log 进入底层 processor 前执行,可原地修改属性或返回 `false` 丢弃。异常会被吞掉,`debug: true` 时输出 warning。它不处理 Metric;请求专属逻辑优先使用 `tracking.request.beforeSend`。
146
200
 
147
- `app`、`sampling`、`route`、顶层 `view`、`plugins`、`instrumentations`、`attributes`、`spanProcessor`、`spanBatch` 已删除,不做兼容映射。
201
+ ## context
148
202
 
149
- # 传输与采样
203
+ | 字段 | 类型 | 默认 | 作用 |
204
+ | --- | --- | --- | --- |
205
+ | `user.id` | `string` | 无 | SDK 原样写入 `user.id` |
206
+ | `attributes.page` | `() => Attributes` | host/path | 页面、请求、错误、Action 等事件属性 |
207
+ | `attributes.metric` | `() => Attributes` | `{}` | 内置 Metric 的低基数自定义维度 |
208
+ | `attributes.error` | `() => Attributes` | `{}` | Error Span 附加属性 |
209
+ | `attributes.custom` | `() => Attributes` | `{}` | `reportCustomEvent()` 附加属性 |
150
210
 
151
- ## Endpoint
211
+ 自定义 `page` Hook 会替换默认 host/path Hook,不是合并默认实现。Metric Hook 禁止放用户 ID、订单 ID、完整 URL 等高基数字段。
152
212
 
153
- `transport.endpoint` 是可选根地址。未配置独立地址的已开启信号会基于它生成 `/v1/rum`、`/v1/metrics`、`/v1/logs`;单信号 `endpoint` 是完整 URL,不再拼接路径。
213
+ ## privacy
154
214
 
155
- ```ts
156
- new BkOpenTelemetry({
157
- application: { name: 'demo' },
158
- transport: {
159
- endpoint: 'https://collector.example.com',
160
- token: 'report-token',
161
- signals: {
162
- traces: {
163
- endpoint: 'https://trace.example.com/v1/rum',
164
- processor: 'batch',
165
- batch: {
166
- maxQueueSize: 2048,
167
- maxExportBatchSize: 512,
168
- scheduledDelayMillis: 5000,
169
- exportTimeoutMillis: 30000,
170
- },
171
- },
172
- metrics: { endpoint: 'https://metric.example.com/v1/metrics', intervalMillis: 60_000 },
173
- logs: { endpoint: 'https://log.example.com/v1/logs' },
174
- },
175
- },
176
- });
177
- ```
215
+ | 字段 | 类型 | 默认 | 说明 |
216
+ | --- | --- | --- | --- |
217
+ | `trackingConsent` | `'granted' \| 'not-granted'` | `granted` | 初始化授权状态 |
218
+ | `redactUrl` | `(url) => string` | 删除 username/password/query/hash | SDK URL 属性脱敏 |
219
+ | `redactAttributes` | `(attributes) => Attributes` | 原样返回 | SDK 创建 Span/Log 和内置插件属性脱敏 |
220
+
221
+ 第三方 instrumentation 的自有 Span 属性不保证经过 `redactAttributes`;需要在 `tracking.beforeSend` 做最终兜底。详见[隐私与公共属性](./privacy.md)。
222
+
223
+ ## extensions
178
224
 
179
- ## 独立信号开关
225
+ | 字段 | 类型 | 默认 | 说明 |
226
+ | --- | --- | --- | --- |
227
+ | `plugins` | `BkOTPlugin[]` | `[]` | 在内置插件后初始化 |
228
+ | `instrumentations` | `Instrumentation[]` | `[]` | 插件完成后注册到 SDK provider |
180
229
 
181
- 三类信号默认全部开启。设为 `false` 时,不创建对应 exporter、processor 或 metric reader:
230
+ 也可以在 `start()` 前调用 `use()` / `useInstrumentation()`。需要动态注册时设置 `autoStart: false`;启动后调用会抛错。
231
+
232
+ ## 完整配置骨架
182
233
 
183
234
  ```ts
184
235
  new BkOpenTelemetry({
185
- application: { name: 'trace-only-demo' },
236
+ application: { name: 'demo', environment: 'production', version: '1.0.0' },
186
237
  transport: {
238
+ endpoint: 'https://collector.example.com',
239
+ token: 'token',
240
+ headers: {},
187
241
  signals: {
188
- traces: { endpoint: 'https://trace.example.com/v1/rum' },
189
- metrics: false,
190
- logs: false,
242
+ traces: { processor: 'batch', batch: {} },
243
+ metrics: { intervalMillis: 60_000 },
244
+ logs: {},
191
245
  },
192
246
  },
247
+ session: { sampleRate: 1 },
248
+ tracking: {
249
+ view: { tracking: 'auto', loadingTime: true },
250
+ request: true,
251
+ resource: true,
252
+ error: true,
253
+ webVitals: true,
254
+ blankScreen: true,
255
+ device: true,
256
+ action: true,
257
+ longTask: false,
258
+ websocket: false,
259
+ cspViolation: false,
260
+ },
261
+ context: { attributes: {} },
262
+ privacy: { trackingConsent: 'granted' },
263
+ extensions: { plugins: [], instrumentations: [] },
264
+ enabled: true,
265
+ autoStart: true,
266
+ debug: false,
193
267
  });
194
268
  ```
195
-
196
- 校验规则:
197
-
198
- - 至少开启一种信号,三类不能全部为 `false`。
199
- - 每个开启信号必须有独立 endpoint,或能回退到根 `transport.endpoint`。
200
- - 关闭 Trace 后不记录 Span,也不会向 `allowedTracingUrls` 注入 `traceparent`。
201
- - 关闭 Metric 后不启动周期导出定时器。
202
- - 关闭 Log 不影响 Session/View 上下文维护,但不会产生 Session、View Snapshot、HTTP body 等 Log。
203
-
204
- 只开启 Metric 时没有精确 `view.id` 下钻链路;需要从指标定位具体 View 时,至少开启 Trace。
205
-
206
- 请求头优先级:`token` 生成的 Authorization < `transport.headers` < 单 signal `headers`。
207
-
208
- 浏览器 exporter 使用 `fetch keepalive`,SDK 在 `pagehide` 和页面进入 hidden 时触发 flush。`shutdown()` 会先结束 View 和插件,再 flush final Snapshot,最后关闭 provider。
209
-
210
- ## Session 级确定性采样
211
-
212
- ```ts
213
- new BkOpenTelemetry({
214
- application: { name: 'demo' },
215
- transport: { endpoint: 'https://collector.example.com' },
216
- session: { sampleRate: 0.05 },
217
- });
218
- ```
219
-
220
- - `1` 表示全量,`0` 表示全部丢弃。
221
- - 决定由 `application.name + session.id` 的稳定 hash 得出。
222
- - 不写额外 sessionStorage;同一 Session 内 span/log/metric 决定一致。
223
- - Session 续期后使用新 ID 重新计算。
224
-
225
- Metric exporter 只接受带内部采样标记的数据点,并在传输前移除该标记。Metric 只保留低基数 `view.url_path_group`,精确 View 关联由 span/log/View Snapshot 的 `view.id` 提供。
@@ -54,7 +54,11 @@ await bkOT.start();
54
54
 
55
55
  `init(context)` 中可以访问 `tracer`、`meter`、`logger`、`startSpan()`、`emitLog()`、`getRuntimeAttributes()` 等能力。
56
56
 
57
+ 优先使用 `context.startSpan()` 和 `context.emitLog()`:它们会合并事件发生时的运行时上下文并应用 SDK 脱敏。直接调用 `context.logger.emit()` 的 Log 不会自动获得这些能力,可能因缺少有效 Session/View 被导出过滤器丢弃。
58
+
57
59
  ```ts
60
+ let teardownVisibility = () => {};
61
+
58
62
  const visibilityPlugin = createPlugin({
59
63
  name: 'visibility-change',
60
64
  init(context) {
@@ -69,8 +73,10 @@ const visibilityPlugin = createPlugin({
69
73
  };
70
74
 
71
75
  document.addEventListener('visibilitychange', onVisibilityChange);
72
-
73
- return undefined;
76
+ teardownVisibility = () => document.removeEventListener('visibilitychange', onVisibilityChange);
77
+ },
78
+ shutdown() {
79
+ teardownVisibility();
74
80
  },
75
81
  });
76
82
  ```
@@ -158,4 +164,10 @@ bkOT.useInstrumentation(new SomeWebInstrumentation());
158
164
  await bkOT.start();
159
165
  ```
160
166
 
161
- > Extension instrumentation 与采集生命周期一致:未授权或 SDK 停止时不会注册;授权后注册。它产生的 RUM 数据仍受 Session sampler 和导出过滤约束。
167
+ > Extension instrumentation 与采集生命周期一致:未授权或 SDK 停止时不会注册;授权后注册。它产生的 Span 受 Session sampler 和导出过滤约束;第三方 instrumentation Metric 因没有公开采样 helper,默认会被过滤。
168
+
169
+ ## 自定义 Metric 注意事项
170
+
171
+ 内置 Metric 会主动带上内部采样标记与低基数 `view.url_path_group`。当前包没有导出稳定的自定义 Metric helper 或采样属性;自定义插件直接调用 `context.meter` 创建的数据点默认无法通过 `FilteringMetricExporter`。不要依赖内部 `bk.rum.sampled` 字段,也不要把 `context.getRuntimeAttributes()` 整体复制到 Metric attributes,否则还会把唯一的 `session.id`、`view.id`、`action.id` 变成高基数 labels。
172
+
173
+ 如果需求是记录一次具体业务行为,使用 Span 或 Log。确实需要自定义 Metric 时,应先为 SDK 设计并公开低基数、采样安全的 Metric API,而不是绕过当前过滤约束。
@@ -18,11 +18,11 @@ SDK 的数据模型遵循“浏览器 SDK 负责低成本原始数据和单事
18
18
  | `document` | 文档加载 | View 管理器(初始加载) |
19
19
  | `resource` | Fetch/XHR 请求与静态资源 | request、resource 采集 |
20
20
  | `vital` | Web Vitals | webVitals 插件 |
21
- | `error` | 错误 | error 插件、blankScreen 插件、cspViolation 插件、自定义事件错误 |
21
+ | `error` | 浏览器与体验错误 | error 插件、blankScreen 插件、cspViolation 插件 |
22
22
  | `longtask` | 长任务 | longTask 插件 |
23
23
  | `action` | 用户动作 | action 插件、reportAction |
24
24
  | `route` | 路由切换 | View 管理器(SPA/手动 View) |
25
- | `custom` | 自定义事件 | reportCustomEvent、自定义插件、websocket 插件 |
25
+ | `custom` | 自定义事件 | reportCustomEvent、自定义插件、websocket 插件;`reportCustomEvent({ error })` 仍属于此类型 |
26
26
 
27
27
  > 每种 span 的具体 span 名、metric 名、log 事件名和完整属性字典见[遥测参考](./telemetry-reference.md)。
28
28
 
@@ -56,6 +56,8 @@ span.end();
56
56
 
57
57
  请求 Resource Span 会根据状态码推导结果:`408`、`504` 为 timeout,`>= 400` 为 error,其余为 success。
58
58
 
59
+ `reportCustomEvent({ error })` 会设置 `result=error` 和 OpenTelemetry Span Status ERROR,但不会把 `span_type` 从 `custom` 改为 `error`。`span_type` 描述事件类别,`result` 描述结果,两者不要混用。
60
+
59
61
  ```ts
60
62
  bkOT.reportCustomEvent({
61
63
  name: 'upload_timeout',