@blueking/open-telemetry 0.0.13 → 0.0.15

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.
Files changed (46) hide show
  1. package/README.md +170 -554
  2. package/dist/bk-rum.global.js +9 -9
  3. package/dist/bk-rum.global.js.map +1 -1
  4. package/dist/core/action-activity.d.ts +28 -0
  5. package/dist/core/config.d.ts +113 -93
  6. package/dist/core/page-activity.d.ts +14 -0
  7. package/dist/core/plugin.d.ts +23 -6
  8. package/dist/core/processor.d.ts +25 -4
  9. package/dist/core/request-timing.d.ts +5 -0
  10. package/dist/core/runtime-context.d.ts +51 -3
  11. package/dist/core/sampling.d.ts +5 -1
  12. package/dist/core/sdk.d.ts +29 -10
  13. package/dist/core/url.d.ts +4 -1
  14. package/dist/index.d.ts +12 -14
  15. package/dist/index.js +2184 -1175
  16. package/dist/index.js.map +1 -1
  17. package/dist/plugins/action.d.ts +6 -2
  18. package/dist/plugins/activity.d.ts +6 -0
  19. package/dist/plugins/blank-screen.d.ts +17 -0
  20. package/dist/plugins/common.d.ts +11 -3
  21. package/dist/plugins/device.d.ts +2 -0
  22. package/dist/plugins/long-task.d.ts +3 -12
  23. package/dist/plugins/page-view.d.ts +1 -0
  24. package/dist/plugins/request-body.d.ts +14 -0
  25. package/dist/plugins/resource.d.ts +17 -1
  26. package/dist/plugins/session-state.d.ts +18 -0
  27. package/dist/plugins/session.d.ts +4 -4
  28. package/dist/plugins/web-vitals.d.ts +74 -0
  29. package/dist/schema/attributes.d.ts +31 -10
  30. package/dist/schema/span.d.ts +4 -12
  31. package/package.json +3 -7
  32. package/skills/bk-rum-otele/SKILL.md +34 -33
  33. package/skills/bk-rum-otele/evals/evals.json +1 -1
  34. package/skills/bk-rum-otele/references/api.md +45 -13
  35. package/skills/bk-rum-otele/references/concepts.md +38 -112
  36. package/skills/bk-rum-otele/references/configuration.md +135 -228
  37. package/skills/bk-rum-otele/references/custom-plugin.md +8 -5
  38. package/skills/bk-rum-otele/references/data-model.md +13 -8
  39. package/skills/bk-rum-otele/references/framework-integration.md +25 -17
  40. package/skills/bk-rum-otele/references/getting-started.md +27 -87
  41. package/skills/bk-rum-otele/references/plugins.md +165 -99
  42. package/skills/bk-rum-otele/references/privacy.md +42 -33
  43. package/skills/bk-rum-otele/references/telemetry-reference.md +73 -44
  44. package/skills/bk-rum-otele/references/troubleshooting.md +72 -38
  45. package/dist/plugins/http-body.d.ts +0 -3
  46. package/dist/plugins/route-timing.d.ts +0 -2
package/README.md CHANGED
@@ -1,120 +1,44 @@
1
1
  # @blueking/open-telemetry
2
2
 
3
- `@blueking/open-telemetry` 是蓝鲸 RUM Web 上报 SDK。它基于 OpenTelemetry 采集页面访问、接口请求、静态资源、JS 错误、Web Vitals、白屏、设备、会话等数据,并通过 OTLP HTTP 上报到 collector。
3
+ 蓝鲸 Web RUM SDK。采集 View、Fetch/XHR、静态资源、错误、Web Vitals、用户操作、白屏、Long Task、WebSocket、CSP、设备和 Session,并通过 OTLP HTTP 上报。
4
4
 
5
- ## 1. 安装和使用
6
-
7
- ### npm 使用
5
+ ## 安装
8
6
 
9
7
  ```bash
10
8
  npm install @blueking/open-telemetry
11
9
  ```
12
10
 
11
+ ## 最小接入
12
+
13
13
  ```javascript
14
14
  import { BkOpenTelemetry } from '@blueking/open-telemetry';
15
15
 
16
16
  const bkOT = new BkOpenTelemetry({
17
- app: {
18
- name: 'demo-app',
17
+ application: {
18
+ name: 'order-center',
19
19
  environment: 'production',
20
- version: '1.0.0',
20
+ version: '1.2.0',
21
21
  },
22
22
  transport: {
23
23
  endpoint: 'https://your-otlp-collector',
24
24
  token: 'your-report-token',
25
25
  },
26
- user: {
27
- id: window.USER_ID,
28
- },
29
26
  });
30
27
  ```
31
28
 
32
- ### CDN 使用
33
-
34
- ```html
35
- <script src="https://unpkg.com/@blueking/open-telemetry/dist/bk-rum.global.js"></script>
36
- <script>
37
- window.bkOT = new window.BkOpenTelemetry({
38
- app: {
39
- name: 'demo-app',
40
- environment: 'production',
41
- version: '1.0.0',
42
- },
43
- transport: {
44
- endpoint: 'https://your-otlp-collector',
45
- token: 'your-report-token',
46
- },
47
- user: {
48
- id: window.USER_ID,
49
- },
50
- });
51
- </script>
52
- ```
53
-
54
- `new BkOpenTelemetry()` 后默认自动启动,不需要再手动调用 `start()`。
55
-
56
- `transport.endpoint` 填上报根地址(通常包含 `/v1` 路径前缀),SDK 会自动拼出三类上报地址:
57
-
58
- - traces: `endpoint/rum`
59
- - metrics: `endpoint/metrics`
60
- - logs: `endpoint/logs`
61
-
62
- 示例:`endpoint: 'http://9.134.239.232:4318/v1'` 时,traces 上报到 `http://9.134.239.232:4318/v1/rum`。
63
-
64
- `transport.token` 会作为默认鉴权头发送:`Authorization: Bearer <token>`。
29
+ `application.name` 和 `transport` 必填。使用根 `transport.endpoint` 时,SDK 自动生成:
65
30
 
66
- ## 2. 默认采集
67
-
68
- 只配置 `app` 和 `transport` 后,SDK 已经默认开启常用能力:
69
-
70
- - `documentLoad`: 页面加载链路。
71
- - `pageView`: 页面访问和 SPA 路由切换。
72
- - `fetch`: 自动采集 fetch 接口请求。
73
- - `xhr`: 自动采集 XMLHttpRequest 接口请求。
74
- - `resource`: 静态资源加载耗时。
75
- - `error`: JS 错误、Promise 异常、资源加载失败。
76
- - `webVitals`: CLS、FCP、INP、LCP、TTFB。
77
- - `blankScreen`: 首屏白屏检测。
78
- - `device`: 设备、浏览器、屏幕、网络信息。
79
- - `session`: 连续访问会话。
80
- - `userInteraction`: OpenTelemetry 官方用户交互 instrumentation。
81
-
82
- 默认关闭的能力需要手动打开:
83
-
84
- - `action`: 轻量用户操作事件,支持点击、输入、提交等。
85
- - `httpBody`: 接口异常时采集请求和响应 body。
86
- - `longTask`: 主线程 Long Task。
87
- - `routeTiming`: SPA 路由切换耗时。
88
- - `cspViolation`: CSP 违规事件。
89
- - `websocket`: WebSocket 连接、消息、错误指标。
90
-
91
- 如果要关闭默认能力,显式配置为 `false`:
92
-
93
- ```javascript
94
- new BkOpenTelemetry({
95
- transport: {
96
- endpoint: 'https://your-otlp-collector',
97
- },
98
- instrumentations: {
99
- fetch: false,
100
- xhr: false,
101
- userInteraction: false,
102
- },
103
- plugins: {
104
- webVitals: false,
105
- blankScreen: false,
106
- session: false,
107
- },
108
- });
109
- ```
31
+ - traces:`/v1/rum`
32
+ - metrics:`/v1/metrics`
33
+ - logs:`/v1/logs`
110
34
 
111
- ## 3. 给数据加上应用、用户和路由
35
+ 默认开启 Session、View、Fetch/XHR、静态资源、错误、Web Vitals、Action、白屏和设备采集。Long Task、WebSocket、CSP 默认关闭。
112
36
 
113
- 建议先补齐应用标识、用户 ID 和路由归类。这样后续排查问题时,可以按应用、版本、用户、页面聚合。
37
+ ## 推荐配置
114
38
 
115
39
  ```javascript
116
40
  const bkOT = new BkOpenTelemetry({
117
- app: {
41
+ application: {
118
42
  name: 'order-center',
119
43
  environment: 'production',
120
44
  version: '1.2.0',
@@ -122,417 +46,217 @@ const bkOT = new BkOpenTelemetry({
122
46
  transport: {
123
47
  endpoint: 'https://your-otlp-collector',
124
48
  token: 'your-report-token',
125
- },
126
- user: {
127
- id: window.USER_ID,
128
- },
129
- route: {
130
- getPathGroup: url => {
131
- const { pathname } = new URL(url, location.href);
132
- return pathname.replace(/\/user\/\d+/, '/user/:id');
49
+ signals: {
50
+ traces: {
51
+ processor: 'batch',
52
+ batch: {
53
+ maxQueueSize: 2048,
54
+ maxExportBatchSize: 512,
55
+ },
56
+ },
57
+ metrics: {
58
+ intervalMillis: 60_000,
59
+ },
133
60
  },
134
61
  },
135
- });
136
- ```
137
-
138
- 常用基础配置:
139
-
140
- - `app.name`: 应用名,会写入 `service.name`,默认 `unknown_service`。
141
- - `app.environment`: 环境名,会写入 `deployment.environment.name`,默认 `production`。
142
- - `app.version`: 应用版本,会写入 `service.version`。
143
- - `user.id`: 用户 ID,会写入 `user.id`。SDK 原样透传,不做 hash 和脱敏。
144
- - `route.getPathGroup`: 把高基数 URL 归类成低基数路由,例如 `/user/123` 归类成 `/user/:id`。
145
-
146
- 运行中也可以更新用户和当前 View:
147
-
148
- ```javascript
149
- bkOT.setUser({ id: 'user-001' });
150
-
151
- bkOT.setView({
152
- id: 'view-001',
153
- url: location.href,
154
- urlPathGroup: '/order/:id',
155
- loadingType: 'route_change',
156
- });
157
- ```
158
-
159
- `setUser` 和 `setView` 会更新运行期公共属性,后续 span、metric、log 都会自动带上这些字段。
160
-
161
- ## 4. 按需打开接口、资源和路由能力
162
-
163
- 多数 Web 应用可以从这一组配置开始:
164
-
165
- ```javascript
166
- new BkOpenTelemetry({
167
- app: {
168
- name: 'demo-app',
169
- version: '1.0.0',
170
- },
171
- transport: {
172
- endpoint: 'https://your-otlp-collector',
173
- token: 'your-report-token',
174
- },
175
- route: {
176
- getPathGroup: url => new URL(url, location.href).pathname,
177
- },
178
- plugins: {
179
- routeTiming: true,
180
- longTask: { threshold: 80 },
62
+ session: {
63
+ sampleRate: 0.2,
181
64
  },
182
- });
183
- ```
184
-
185
- - `fetch` / `xhr`: 默认开启,采集接口耗时、状态码、请求方法、URL 归类等。
186
- - `resource`: 默认开启,采集 img、script、css 等静态资源耗时、大小、缓存命中和协议。
187
- - `pageView`: 默认开启,监听 `pushState`、`replaceState`、`popstate`、`hashchange`。
188
- - `routeTiming`: 默认关闭,估算 SPA 路由切换到下一帧渲染完成的耗时。
189
- - `longTask`: 默认关闭,采集主线程长任务。`threshold` 默认 `50` ms。
190
-
191
- SDK 会自动忽略指向自身 OTLP 上报地址的请求,避免上报请求被再次采集导致循环放大。
192
-
193
- ## 5. 配置错误、白屏和 CSP
194
-
195
- ```javascript
196
- new BkOpenTelemetry({
197
- transport: {
198
- endpoint: 'https://your-otlp-collector',
199
- },
200
- plugins: {
201
- error: {
202
- windowMs: 60 * 1000,
203
- maxPerWindow: 5,
65
+ tracking: {
66
+ view: {
67
+ getPathGroup: url => new URL(url, location.href).pathname.replace(/\/orders\/\d+/, '/orders/:id'),
68
+ excludedActivityUrls: [/\/events\/stream$/],
204
69
  },
205
- blankScreen: {
206
- rootSelector: '#app',
207
- checkDelay: 3000,
208
- threshold: 0.8,
209
- ignoreSelectors: ['.app-loading', '.page-skeleton'],
70
+ request: {
71
+ allowedTracingUrls: ['https://api.example.com'],
72
+ excludedUrls: [/\/health(?:\?|$)/],
210
73
  },
211
- cspViolation: true,
212
- },
213
- });
214
- ```
215
-
216
- 错误采集说明:
217
-
218
- - `error`: 默认开启,采集 `window.error`、`unhandledrejection`、资源加载失败。
219
- - `error.windowMs`: 同类错误节流窗口,默认 `60000` ms。
220
- - `error.maxPerWindow`: 同类错误在窗口内最多上报条数,默认 `5`。
221
- - `cspViolation`: 默认关闭,监听 `securitypolicyviolation` 事件。适合有 CSP 策略的站点开启。
222
-
223
- 白屏检测说明:
224
-
225
- - `blankScreen`: 默认开启,只在判定为白屏时上报。
226
- - `blankScreen.rootSelector`: 应用挂载点。Vue / React 项目建议配置为 `#app` 或 `#root`。
227
- - `blankScreen.checkDelay`: DOM ready 后延迟多久检测,默认 `3000` ms。
228
- - `blankScreen.threshold`: 空白采样点比例阈值,范围 `0 - 1`,默认 `0.8`。
229
- - `blankScreen.ignoreSelectors`: 追加 loading、骨架屏等忽略选择器,命中后不计入空白比例。
230
-
231
- ## 6. 配置用户操作和 WebSocket
232
-
233
- ```javascript
234
- new BkOpenTelemetry({
235
- transport: {
236
- endpoint: 'https://your-otlp-collector',
74
+ longTask: { threshold: 50 },
75
+ websocket: true,
237
76
  },
238
- plugins: {
239
- action: {
240
- eventNames: ['click', 'submit', 'keydown'],
77
+ context: {
78
+ user: { id: window.USER_ID },
79
+ attributes: {
80
+ page: () => ({ 'biz.module': 'order' }),
81
+ custom: () => ({ 'biz.team': 'checkout' }),
241
82
  },
242
- websocket: true,
83
+ },
84
+ privacy: {
85
+ redactAttributes: attributes => attributes,
243
86
  },
244
87
  });
245
88
  ```
246
89
 
247
- `action` 用于上报轻量用户操作:
248
-
249
- - `action: true`: 采集 `click`、`submit`、`keydown`。
250
- - `action.eventNames`: 自定义采集事件,支持 `click`、`input`、`keydown`、`pointerdown`、`scroll`、`submit`。
251
- - 上报时会截取元素文本、标签名,并写入 `action.type`、`target.text_short`、`target.tag`。
90
+ ## 入口字段
252
91
 
253
- `websocket` 用于采集 WebSocket:
92
+ | 字段 | 作用 |
93
+ | --- | --- |
94
+ | `application` | 应用名、环境和版本;`name` 必填 |
95
+ | `transport` | OTLP endpoint、鉴权头及每类 signal 配置;根 `endpoint` 与单信号 endpoint 至少提供一种 |
96
+ | `session` | Session storage key 和确定性 `sampleRate` |
97
+ | `tracking` | 内置采集能力、View 分组、请求过滤和全局 `beforeSend` |
98
+ | `context` | 用户及 page/metric/error/custom 公共属性 |
99
+ | `privacy` | Consent、URL 和属性脱敏 |
100
+ | `extensions` | 自定义插件与原生 OpenTelemetry instrumentation |
254
101
 
255
- - 连接成功耗时:`browser.websocket.connect.duration`。
256
- - 收发消息数:`browser.websocket.message.count`。
257
- - 收发字节数:`browser.websocket.message.bytes`。
258
- - 错误数:`browser.websocket.error.count`。
102
+ 旧入口 `app`、`sampling`、`route`、`view`、`plugins`、`instrumentations`、`attributes`、`spanBatch` 不再支持。
259
103
 
260
- SDK 会忽略指向自身上报地址的 WebSocket URL。
104
+ ## 三类信号独立开关
261
105
 
262
- ## 7. 采集异常接口 body
263
-
264
- `httpBody` 默认关闭。它会 patch `fetch` 和 `XMLHttpRequest`,只在请求失败、请求抛错或状态码 `>= 400` 时上报 body。
106
+ `traces`、`metrics`、`logs` 默认全部开启。设为 `false` 会关闭对应导出链路;关闭的信号不会创建 exporter、processor 或 metric reader。
265
107
 
266
108
  ```javascript
267
109
  new BkOpenTelemetry({
110
+ application: { name: 'trace-only-app' },
268
111
  transport: {
269
- endpoint: 'https://your-otlp-collector',
270
- },
271
- plugins: {
272
- httpBody: {
273
- maxBodySize: 4 * 1024,
274
- redact: ({ body, type, url, status, truncated }) => {
275
- return body.replace(/password=[^&]+/g, 'password=***').replace(/token=[^&]+/g, 'token=***');
276
- },
112
+ signals: {
113
+ traces: { endpoint: 'https://trace.example.com/v1/rum' },
114
+ metrics: false,
115
+ logs: false,
277
116
  },
278
117
  },
279
118
  });
280
119
  ```
281
120
 
282
- 配置项:
283
-
284
- - `httpBody: true`: 使用默认配置开启。
285
- - `httpBody.maxBodySize`: 单个请求或响应 body 最大采集长度,默认 `10 * 1024` 字符。
286
- - `httpBody.redact`: body 上报前的脱敏函数,必须返回字符串。
121
+ 根 `transport.endpoint` 可省略,但每个开启的信号必须配置独立 endpoint;三类信号不能全部关闭。关闭 Trace 后不会创建 Span,也不会注入 `traceparent`。
287
122
 
288
- `redact` 入参:
123
+ ## View 与 SPA
289
124
 
290
- - `body`: 已截断后的 body 字符串。
291
- - `type`: `request` 或 `response`。
292
- - `url`: 请求 URL。
293
- - `method`: 请求方法。
294
- - `status`: 响应状态码,网络错误时可能为空。
295
- - `contentType`: body 的 content-type。
296
- - `truncated`: 是否被 `maxBodySize` 截断。
297
-
298
- 建议只在排障需要时开启 `httpBody`,并务必处理密码、token、手机号等敏感信息。
299
-
300
- ## 8. 加公共属性和脱敏
301
-
302
- 公共属性适合放业务线、模块、页面类型等每条数据都想带上的信息。
125
+ 自动模式会为初始加载、pathname/hash 路由、BFCache 和 Session 续期创建独立 View。query-only 和页内锚点变化不会创建新 View。
303
126
 
304
127
  ```javascript
305
- new BkOpenTelemetry({
306
- transport: {
307
- endpoint: 'https://your-otlp-collector',
308
- },
309
- attributes: {
310
- page: () => ({
311
- 'biz.module': 'order',
312
- 'rum.page.host': location.host,
313
- 'rum.page.path': location.pathname,
314
- }),
315
- metric: () => ({
316
- 'biz.metric_source': 'rum',
317
- }),
318
- error: () => ({
319
- 'biz.error_source': 'browser',
320
- }),
321
- custom: () => ({
322
- 'biz.team': 'demo',
323
- }),
324
- },
325
- privacy: {
326
- redactUrl: url => url.replace(/token=[^&]+/g, 'token=***'),
327
- redactAttributes: attributes => {
328
- const next = { ...attributes };
329
- for (const key of Object.keys(next)) {
330
- if (typeof next[key] === 'string') {
331
- next[key] = next[key].replace(/\b\d{11}\b/g, '***');
332
- }
333
- }
334
- return next;
335
- },
128
+ const bkOT = new BkOpenTelemetry({
129
+ application: { name: 'manual-view-app' },
130
+ transport: { endpoint: 'https://your-otlp-collector' },
131
+ tracking: {
132
+ view: { tracking: 'manual' },
336
133
  },
337
134
  });
338
- ```
339
135
 
340
- `attributes` 配置项:
136
+ bkOT.startView({ name: '订单详情', url: location.href });
137
+ bkOT.setViewName('订单详情-只读');
138
+ bkOT.setViewLoadingTime();
139
+ ```
341
140
 
342
- - `attributes.page`: 页面、接口、资源、错误等 RUM 数据都会带上。
343
- - `attributes.metric`: Web Vitals、Long Task、Route Timing、WebSocket 等 metric 会带上。
344
- - `attributes.error`: JS 错误、白屏、CSP 等错误类数据会带上。
345
- - `attributes.custom`: `reportCustomEvent` 上报的自定义事件会带上。
141
+ 每个 View 有一个覆盖生命周期的 `browser.view` span,并产生 create/update/final Snapshot log。初始 View 记录 TTFB、DOM Interactive、DOMContentLoaded、DOM Complete、Load Event;SPA View 独立计算 CLS session window 和 INP p98。
346
142
 
347
- `privacy` 配置项:
143
+ ## Metric 如何关联 View
348
144
 
349
- - `privacy.redactUrl`: 处理 URL,例如 `url.full`、`document.referrer`、资源 URL。
350
- - `privacy.redactAttributes`: 处理 span 和 log 属性。适合兜底清理敏感字段。
351
- - `plugins.httpBody.redact`: 只处理请求和响应 body。
145
+ Metric datapoint 只携带低基数 `view.url_path_group`,不携带唯一 `view.id`,避免时序基数随 PV 无限增长。
352
146
 
353
- 脱敏顺序可以简单理解为:URL 先走 `redactUrl`,属性整体再走 `redactAttributes`。
147
+ 精确关联放在 View Snapshot、span 和 log:这些事件会携带 `session.id + view.id`,用户操作期间还会携带 `action.id`。需要从单个指标下钻到具体 View 时,应在后端使用 exemplar,或从原始事件派生聚合指标。
354
148
 
355
- ## 9. 配置设备和会话
149
+ ## 请求与资源
356
150
 
357
- `device` 和 `session` 默认开启,一般不需要配置。多应用共用同一域名时,可以自定义 storage key。
151
+ Fetch/XHR 由一套请求生命周期统一采集,不会重复 patch 或重复计数。Trace Header 只对 `allowedTracingUrls` 命中的 URL 注入,包括同源请求。
358
152
 
359
153
  ```javascript
360
154
  new BkOpenTelemetry({
361
- transport: {
362
- endpoint: 'https://your-otlp-collector',
363
- },
364
- plugins: {
365
- device: {
366
- storageKey: 'DEMO_DEVICE_ID',
367
- },
368
- session: {
369
- storageKey: 'DEMO_SESSION',
370
- inactivityMs: 30 * 60 * 1000,
371
- maxLifetimeMs: 24 * 60 * 60 * 1000,
155
+ application: { name: 'request-demo' },
156
+ transport: { endpoint: 'https://your-otlp-collector' },
157
+ tracking: {
158
+ request: {
159
+ allowedTracingUrls: ['https://api.example.com'],
160
+ excludedUrls: [/\/health(?:\?|$)/],
161
+ beforeSend: (event, context) => {
162
+ event.attributes['request.transport'] = context.type;
163
+ return event.resource.statusCode !== 404;
164
+ },
165
+ body: {
166
+ capture: 'errors',
167
+ maxSize: 10 * 1024,
168
+ redact: ({ body }) => body.replace(/("(?:password|token)"\s*:\s*)"[^"]*"/g, '$1"***"'),
169
+ },
372
170
  },
373
171
  },
374
172
  });
375
173
  ```
376
174
 
377
- `device` 配置项:
378
-
379
- - `device: true`: 使用默认设备配置。
380
- - `device.storageKey`: 设备 ID 的 localStorage key,默认 `BK_RUM_DEVICE_ID`。
381
- - 设备 ID 跨会话持久,会写入 `device.id`。
382
-
383
- `session` 配置项:
175
+ 静态资源与请求共用一个 Resource PerformanceObserver。静态资源生成独立 span;Fetch/XHR timing 会匹配回对应请求 span。SDK 自身 OTLP 请求始终排除。
384
176
 
385
- - `session: true`: 使用默认会话配置。
386
- - `session.storageKey`: 会话 storage key。默认会按上报 endpoint host 自动生成隔离后缀。
387
- - `session.inactivityMs`: 用户不活跃多久后创建新会话,默认 `30` 分钟。
388
- - `session.maxLifetimeMs`: 会话最长持续时间,默认 `24` 小时。
177
+ ## 隐私与 Consent
389
178
 
390
- 会话会写入 `session.id`,并在首次创建或轮换时上报 `session.start` / `session.rotate` log。
391
-
392
- ## 10. 手动上报业务事件
393
-
394
- ### 自定义事件
179
+ 默认 URL 脱敏会移除用户名、密码、query 和 hash。Action 默认只读取显式属性及可访问名称,不读取任意 DOM 文本;设备 ID 默认不持久化。
395
180
 
396
181
  ```javascript
397
- bkOT.reportCustomEvent({
398
- name: 'order.checkout',
399
- attributes: {
400
- 'biz.order_id': 'O20260527001',
401
- 'biz.order_amount': 199,
402
- },
403
- });
404
- ```
405
-
406
- ### 自定义失败事件
407
-
408
- ```javascript
409
- bkOT.reportCustomEvent({
410
- name: 'order.checkout',
411
- attributes: {
412
- 'biz.order_id': 'O20260527001',
182
+ const bkOT = new BkOpenTelemetry({
183
+ application: { name: 'privacy-demo' },
184
+ transport: { endpoint: 'https://your-otlp-collector' },
185
+ privacy: {
186
+ trackingConsent: 'not-granted',
187
+ redactUrl: url => new URL(url, location.href).origin,
188
+ redactAttributes: attributes => ({ ...attributes, token: undefined }),
413
189
  },
414
- error: new Error('库存不足'),
415
190
  });
416
- ```
417
191
 
418
- ### 手动上报用户操作
419
-
420
- ```javascript
421
- bkOT.reportAction({
422
- type: 'click',
423
- targetText: '立即购买',
424
- targetTag: 'button',
425
- attributes: {
426
- 'biz.order_id': 'O20260527001',
427
- },
428
- });
192
+ await bkOT.setTrackingConsent('granted');
193
+ await bkOT.setTrackingConsent('not-granted');
429
194
  ```
430
195
 
431
- 说明:
196
+ 未授权时不创建 Session、不安装采集 patch。运行期可授权、撤回和再次授权。
432
197
 
433
- - `reportCustomEvent.name`: 事件名,会生成 `custom.${name}` span。
434
- - `reportCustomEvent.attributes`: 业务属性,会和 `attributes.custom` 合并。
435
- - `reportCustomEvent.error`: 传入后事件结果会标记为 error,并记录 exception。
436
- - `reportAction.type`: 操作类型,会生成 `action.${type}` span。
437
- - 未命中采样时,手动上报事件会被静默丢弃;`debug: true` 时会打印提示。
198
+ ## 全局 beforeSend
438
199
 
439
- ## 11. 控制采样、调试和上报
200
+ `tracking.beforeSend` 在 span/log 进入 exporter 前执行,可修改属性或返回 `false` 丢弃事件。
440
201
 
441
202
  ```javascript
442
203
  new BkOpenTelemetry({
443
- debug: true,
444
- enabled: true,
445
- sampling: {
446
- rate: 0.2,
447
- },
448
- spanProcessor: 'batch',
449
- spanBatch: {
450
- maxQueueSize: 2048,
451
- maxExportBatchSize: 512,
452
- scheduledDelayMillis: 5000,
453
- exportTimeoutMillis: 30000,
454
- },
455
- transport: {
456
- endpoint: 'https://your-otlp-collector',
457
- token: 'your-report-token',
458
- headers: {
459
- 'X-Biz-ID': 'demo',
460
- },
461
- signals: {
462
- traces: {
463
- timeoutMillis: 10000,
464
- },
465
- metrics: {
466
- concurrencyLimit: 2,
467
- },
204
+ application: { name: 'filter-demo' },
205
+ transport: { endpoint: 'https://your-otlp-collector' },
206
+ tracking: {
207
+ beforeSend(event) {
208
+ delete event.attributes['debug.payload'];
209
+ return event.name !== 'custom.ignore-me';
468
210
  },
469
211
  },
470
212
  });
471
213
  ```
472
214
 
473
- 常用控制项:
215
+ 请求专属 `tracking.request.beforeSend` 额外提供原始 Request/Response 或 XMLHttpRequest 上下文。
474
216
 
475
- - `enabled`: 是否启用 SDK,默认 `true`。设为 `false` 后不会启动采集和上报。
476
- - `debug`: 是否在控制台输出 exporter 数据和插件异常,默认 `false`。
477
- - `sampling.rate`: 采样率,范围 `0 - 1`,默认 `1`。
478
- - `spanProcessor`: trace processor 模式,默认 `batch`。本地调试可用 `simple`。
479
- - `spanBatch`: `batch` 模式的批量上报配置。
480
- - `transport.endpoint`: 上报根地址(通常包含 `/v1` 路径前缀),默认 `http://localhost:4318`。SDK 会追加 `/rum`、`/metrics`、`/logs`。
481
- - `transport.token`: 默认鉴权 token。
482
- - `transport.headers`: 所有信号共用请求头。
483
- - `transport.signals.traces/metrics/logs`: 分别配置某一类信号。
217
+ ## Session 与采样
484
218
 
485
- 采样结果会在一次浏览器会话中保持稳定。`rate < 1` 时,SDK 会把采样结果写入 `sessionStorage`;不可用时降级到内存缓存。
219
+ `session.sampleRate` 范围为 `0 - 1`,默认 `1`。采样决定由 `application.name + session.id` 确定性计算,不写入额外 storage;同一 Session 内始终一致。
486
220
 
487
- 如果三类信号要发到不同地址:
221
+ Session 固定为 15 分钟无活动过期、4 小时最长生命周期。storage key 默认按应用名和 endpoint 隔离。
222
+
223
+ ## Action、设备和安全默认值
488
224
 
489
225
  ```javascript
490
226
  new BkOpenTelemetry({
491
- transport: {
492
- endpoint: 'https://your-otlp-collector',
493
- token: 'your-report-token',
494
- signals: {
495
- endpoints: {
496
- traces: 'https://trace.example.com/v1/rum',
497
- metrics: 'https://metric.example.com/v1/metrics',
498
- logs: 'https://log.example.com/v1/logs',
499
- },
227
+ application: { name: 'interaction-demo' },
228
+ transport: { endpoint: 'https://your-otlp-collector' },
229
+ tracking: {
230
+ action: {
231
+ actionNameAttribute: 'data-bk-action-name',
232
+ nameCollection: 'explicit',
500
233
  },
234
+ device: { persistentId: false },
235
+ blankScreen: { rootSelector: '#app' },
236
+ cspViolation: true,
501
237
  },
502
238
  });
503
239
  ```
504
240
 
505
- 请求头优先级为:`transport.token` 默认头 < `transport.headers` < 单信号 `headers`。
241
+ 只有明确接受 DOM 文本采集风险时,才设置 `action.nameCollection: 'text'`。只有需要跨 Session 设备关联时,才设置 `device.persistentId: true`。
506
242
 
507
- ## 12. 控制启动和生命周期
508
-
509
- 默认 `autoStart: true`。如果要先注册自定义插件或 instrumentation,再启动 SDK,可以关闭自动启动。
243
+ ## 手动事件
510
244
 
511
245
  ```javascript
512
- const bkOT = new BkOpenTelemetry({
513
- autoStart: false,
514
- transport: {
515
- endpoint: 'https://your-otlp-collector',
516
- },
517
- });
518
-
519
- await bkOT.start();
520
- ```
246
+ bkOT.setUser({ id: 'user-001' });
521
247
 
522
- 生命周期方法:
248
+ bkOT.reportAction({
249
+ name: '立即购买',
250
+ attributes: { 'biz.order_id': 'O20260716001' },
251
+ });
523
252
 
524
- ```javascript
525
- await bkOT.flush();
526
- await bkOT.shutdown();
253
+ bkOT.reportCustomEvent({
254
+ name: 'order.checkout',
255
+ attributes: { 'biz.order_amount': 199 },
256
+ });
527
257
  ```
528
258
 
529
- - `start`: 启动 provider、instrumentation 和插件。重复调用会直接返回。
530
- - `flush`: 立即刷新插件、trace、metric、log。
531
- - `shutdown`: 先刷新,再卸载插件、事件监听和 instrumentation。关闭后不能再次启动同一个实例。
532
-
533
- ## 13. 扩展插件
534
-
535
- 普通接入方通常不需要扩展插件。只有默认采集不满足时,再使用插件能力。
259
+ ## 扩展
536
260
 
537
261
  ```javascript
538
262
  import { BkOpenTelemetry, createPlugin } from '@blueking/open-telemetry';
@@ -540,171 +264,63 @@ import { BkOpenTelemetry, createPlugin } from '@blueking/open-telemetry';
540
264
  const plugin = createPlugin({
541
265
  name: 'demo-plugin',
542
266
  init(context) {
543
- context.setRuntimeAttributes({
544
- 'biz.plugin_enabled': true,
545
- });
546
-
547
- const span = context.startSpan('demo.plugin_ready', {
548
- 'biz.plugin': 'demo',
549
- });
267
+ const span = context.startSpan('demo.plugin_ready');
550
268
  span.end();
551
269
  },
552
270
  });
553
271
 
554
272
  const bkOT = new BkOpenTelemetry({
273
+ application: { name: 'extension-demo' },
555
274
  autoStart: false,
556
- plugins: {
557
- custom: [plugin],
558
- },
559
- transport: {
560
- endpoint: 'https://your-otlp-collector',
561
- },
562
- });
563
-
564
- await bkOT.start();
565
- ```
566
-
567
- 也可以在 `start()` 前链式注册:
568
-
569
- ```javascript
570
- bkOT.use(plugin);
571
- ```
572
-
573
- 插件上下文常用方法:
574
-
575
- - `context.startSpan`: 创建 span。
576
- - `context.emitLog`: 上报 log,并自动带上运行期公共属性和脱敏。
577
- - `context.meter`: 创建 metric。
578
- - `context.setRuntimeAttributes`: 更新后续数据都会携带的公共属性。
579
- - `context.getRuntimeAttributes`: 获取当前公共属性快照。
580
- - `context.setUser`: 更新用户上下文。
581
- - `context.setView`: 更新 View 上下文。
582
-
583
- ## 14. 接入原生 OpenTelemetry Instrumentation
584
-
585
- ```javascript
586
- import { BkOpenTelemetry } from '@blueking/open-telemetry';
587
- import { MyCustomInstrumentation } from './my-custom-instrumentation';
588
-
589
- const bkOT = new BkOpenTelemetry({
590
- autoStart: false,
591
- instrumentations: {
592
- custom: [new MyCustomInstrumentation()],
593
- },
594
- transport: {
595
- endpoint: 'https://your-otlp-collector',
275
+ transport: { endpoint: 'https://your-otlp-collector' },
276
+ extensions: {
277
+ plugins: [plugin],
278
+ instrumentations: [],
596
279
  },
597
280
  });
598
281
 
599
282
  await bkOT.start();
283
+ await bkOT.flush();
284
+ await bkOT.shutdown();
600
285
  ```
601
286
 
602
- 也可以在 `start()` 前链式注册:
603
-
604
- ```javascript
605
- bkOT.useInstrumentation(new MyCustomInstrumentation());
606
- ```
607
-
608
- 注意:`use` 和 `useInstrumentation` 必须在 `start()` 前调用。如果使用默认自动启动,请改成 `autoStart: false`。
287
+ 也可在 `start()` 前调用 `use(plugin)` 或 `useInstrumentation(instrumentation)`。退出上报使用 OpenTelemetry 浏览器 exporter 的 `fetch keepalive`,并在 pagehide/hidden 时 flush。
609
288
 
610
- ## 15. 完整配置速查
289
+ ## 完整配置骨架
611
290
 
612
291
  ```javascript
613
292
  new BkOpenTelemetry({
614
- app: {
615
- name: 'demo-app',
616
- environment: 'production',
617
- version: '1.0.0',
618
- },
619
- user: {
620
- id: 'user-001',
621
- },
293
+ application: { name: 'demo-app', environment: 'production', version: '1.0.0' },
622
294
  transport: {
623
295
  endpoint: 'https://your-otlp-collector',
624
- token: 'your-report-token',
296
+ token: 'token',
625
297
  headers: {},
626
298
  signals: {
627
- endpoints: {
628
- traces: 'https://your-otlp-collector/v1/rum',
629
- metrics: 'https://your-otlp-collector/v1/metrics',
630
- logs: 'https://your-otlp-collector/v1/logs',
631
- },
632
- traces: {
633
- headers: {},
634
- timeoutMillis: 10000,
635
- concurrencyLimit: 2,
636
- },
637
- metrics: {},
638
- logs: {},
299
+ traces: { endpoint: 'https://trace.example.com/v1/rum', processor: 'batch', batch: {}, timeoutMillis: 10_000 },
300
+ metrics: { endpoint: 'https://metric.example.com/v1/metrics', intervalMillis: 60_000 }, // 或 false
301
+ logs: { endpoint: 'https://log.example.com/v1/logs' }, // 或 false
639
302
  },
640
303
  },
641
- enabled: true,
642
- autoStart: true,
643
- debug: false,
644
- sampling: {
645
- rate: 1,
646
- },
647
- spanProcessor: 'batch',
648
- spanBatch: {
649
- maxQueueSize: 2048,
650
- maxExportBatchSize: 512,
651
- scheduledDelayMillis: 5000,
652
- exportTimeoutMillis: 30000,
653
- },
654
- route: {
655
- getPathGroup: url => new URL(url, location.href).pathname,
656
- },
657
- attributes: {
658
- page: () => ({}),
659
- metric: () => ({}),
660
- error: () => ({}),
661
- custom: () => ({}),
662
- },
663
- privacy: {
664
- redactUrl: url => url,
665
- redactAttributes: attributes => attributes,
666
- },
667
- instrumentations: {
668
- documentLoad: true,
669
- fetch: true,
670
- xhr: true,
671
- userInteraction: true,
672
- },
673
- plugins: {
674
- pageView: true,
304
+ session: { sampleRate: 1, storageKey: 'optional-session-key' },
305
+ tracking: {
306
+ view: { tracking: 'auto', loadingTime: true, getPathGroup: url => new URL(url, location.href).pathname },
307
+ request: {},
675
308
  resource: true,
676
309
  error: true,
677
310
  webVitals: true,
678
311
  blankScreen: true,
679
312
  device: true,
680
- session: true,
681
- action: false,
682
- httpBody: false,
313
+ action: true,
683
314
  longTask: false,
684
- routeTiming: false,
685
315
  cspViolation: false,
686
316
  websocket: false,
317
+ beforeSend: event => true,
687
318
  },
319
+ context: { user: { id: 'user-001' }, attributes: {} },
320
+ privacy: { trackingConsent: 'granted' },
321
+ extensions: { plugins: [], instrumentations: [] },
322
+ autoStart: true,
323
+ enabled: true,
324
+ debug: false,
688
325
  });
689
326
  ```
690
-
691
- 配置默认值:
692
-
693
- - `autoStart`: 默认 `true`。
694
- - `enabled`: 默认 `true`。
695
- - `debug`: 默认 `false`。
696
- - `sampling.rate`: 默认 `1`。
697
- - `spanProcessor`: 默认 `batch`。
698
- - `transport.endpoint`: 默认 `http://localhost:4318`。
699
- - `app.environment`: 默认 `production`。
700
- - `app.name`: 默认 `unknown_service`。
701
-
702
- ## 16. 推荐接入顺序
703
-
704
- 新项目建议按下面顺序接入:
705
-
706
- 1. 先配置 `app`、`transport`、`user`,确认页面访问、错误、接口请求能上报。
707
- 2. 再配置 `route.getPathGroup`,避免 URL 动态 ID 导致维度过高。
708
- 3. 按业务需要开启 `routeTiming`、`longTask`、`action`、`websocket`。
709
- 4. 排障时再开启 `httpBody`,并先做好脱敏。
710
- 5. 最后补充 `attributes` 和 `privacy`,统一业务维度和敏感信息处理。