@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.
Files changed (33) hide show
  1. package/README.md +83 -244
  2. package/dist/bk-rum.global.js +2 -2
  3. package/dist/bk-rum.global.js.map +1 -1
  4. package/dist/core/config.d.ts +2 -0
  5. package/dist/core/metric.d.ts +2 -0
  6. package/dist/core/sdk.d.ts +4 -0
  7. package/dist/core/signal.d.ts +3 -0
  8. package/dist/core/telemetry-attributes.d.ts +1 -0
  9. package/dist/core/throttle.d.ts +2 -2
  10. package/dist/index.js +525 -456
  11. package/dist/index.js.map +1 -1
  12. package/dist/plugins/blank-screen.d.ts +4 -0
  13. package/dist/plugins/common.d.ts +1 -0
  14. package/dist/plugins/csp-violation.d.ts +1 -1
  15. package/dist/plugins/long-task.d.ts +4 -0
  16. package/dist/plugins/request-body.d.ts +2 -1
  17. package/dist/plugins/resource.d.ts +4 -0
  18. package/dist/plugins/web-vitals.d.ts +2 -0
  19. package/package.json +1 -1
  20. package/skills/bk-rum-otele/SKILL.md +8 -3
  21. package/skills/bk-rum-otele/evals/evals.json +3 -3
  22. package/skills/bk-rum-otele/references/api.md +236 -135
  23. package/skills/bk-rum-otele/references/architecture.md +141 -0
  24. package/skills/bk-rum-otele/references/capabilities.md +100 -0
  25. package/skills/bk-rum-otele/references/concepts.md +7 -4
  26. package/skills/bk-rum-otele/references/configuration.md +221 -178
  27. package/skills/bk-rum-otele/references/custom-plugin.md +15 -3
  28. package/skills/bk-rum-otele/references/data-model.md +5 -3
  29. package/skills/bk-rum-otele/references/getting-started.md +16 -0
  30. package/skills/bk-rum-otele/references/plugins.md +100 -72
  31. package/skills/bk-rum-otele/references/privacy.md +5 -1
  32. package/skills/bk-rum-otele/references/telemetry-reference.md +14 -12
  33. package/skills/bk-rum-otele/references/transport-sampling.md +79 -0
package/README.md CHANGED
@@ -1,42 +1,68 @@
1
1
  # @blueking/open-telemetry
2
2
 
3
- 蓝鲸 Web RUM SDK。采集 View、Fetch/XHR、静态资源、错误、Web Vitals、用户操作、白屏、Long Task、WebSocket、CSP、设备和 Session,并通过 OTLP HTTP 上报。
3
+ 面向浏览器真实用户监控(RUM)的 OpenTelemetry SDK。它把 Session、View、Fetch/XHR、静态资源、错误、Web Vitals、用户操作、白屏、Long Task、WebSocket、CSP 和设备信息统一为 Trace、Metric、Log,并通过 OTLP HTTP 上报。
4
4
 
5
- ## 安装
5
+ ## 快速接入
6
6
 
7
7
  ```bash
8
8
  npm install @blueking/open-telemetry
9
9
  ```
10
10
 
11
- ## 最小接入
12
-
13
- ```javascript
11
+ ```ts
14
12
  import { BkOpenTelemetry } from '@blueking/open-telemetry';
15
13
 
16
- const bkOT = new BkOpenTelemetry({
14
+ export const bkOT = new BkOpenTelemetry({
17
15
  application: {
18
16
  name: 'order-center',
19
17
  environment: 'production',
20
18
  version: '1.2.0',
21
19
  },
22
20
  transport: {
23
- endpoint: 'https://your-otlp-collector',
24
- token: 'your-report-token',
21
+ endpoint: 'https://rum-collector.example.com',
22
+ token: 'report-token',
23
+ },
24
+ session: {
25
+ sampleRate: 0.2,
26
+ },
27
+ tracking: {
28
+ view: {
29
+ getPathGroup: url => new URL(url, location.href).pathname.replace(/\/orders\/[^/]+/, '/orders/:id'),
30
+ },
25
31
  },
26
32
  });
27
33
  ```
28
34
 
29
- `application.name` 和 `transport` 必填。使用根 `transport.endpoint` 时,SDK 自动生成:
35
+ `application.name` 与 `transport` 必填。根 `transport.endpoint` 会生成三个上报地址:
36
+
37
+ | 信号 | 默认地址 | 主要用途 |
38
+ | --- | --- | --- |
39
+ | Trace | `<endpoint>/v1/rum` | View、请求、资源、错误、性能、Action |
40
+ | Metric | `<endpoint>/v1/metrics` | Web Vitals、View Loading、白屏、Long Task、WebSocket 聚合 |
41
+ | Log | `<endpoint>/v1/logs` | Session 生命周期、View Snapshot、请求 Body、WebSocket 事件 |
42
+
43
+ 也可以为 `transport.signals.traces|metrics|logs.endpoint` 分别提供完整 URL,或把不需要的信号设为 `false`。至少要启用一种信号。
44
+
45
+ ## 默认能力
46
+
47
+ 只提供最小配置时,SDK 会自动启动并建立 Session 与 View。
30
48
 
31
- - traces:`/v1/rum`
32
- - metrics:`/v1/metrics`
33
- - logs:`/v1/logs`
49
+ | 能力 | 默认 | 产出 |
50
+ | --- | --- | --- |
51
+ | Session / View | 开启且不可关闭 | `session.*` Log、`browser.view` Span/Log/Metric、运行时关联字段 |
52
+ | Fetch / XHR | 开启 | `browser.resource` CLIENT Span,可选 `traceparent` 与 Body Log |
53
+ | 静态资源 | 开启 | `browser.resource` Span、网络阶段属性 |
54
+ | Error | 开启 | JS、Promise、资源加载错误 Span |
55
+ | Web Vitals | 开启 | CLS/FCP/INP/LCP/TTFB Span 与 Metric |
56
+ | Action | 开启 | 点击活动、耗时、关联计数和挫败信号 Span |
57
+ | Blank Screen | 开启 | 白屏 Span 与 Counter |
58
+ | Device | 开启 | 浏览器、OS、屏幕、网络运行时属性 |
59
+ | Long Task / WebSocket / CSP | 关闭 | 按需通过 `tracking` 开启 |
34
60
 
35
- 默认开启 Session、View、Fetch/XHR、静态资源、错误、Web Vitals、Action、白屏和设备采集。Long Task、WebSocket、CSP 默认关闭。
61
+ 完整的浏览器 API、默认值、配置入口和遥测产出见[能力矩阵](./wikis/capabilities.md)。
36
62
 
37
- ## 推荐配置
63
+ ## 生产配置基线
38
64
 
39
- ```javascript
65
+ ```ts
40
66
  const bkOT = new BkOpenTelemetry({
41
67
  application: {
42
68
  name: 'order-center',
@@ -44,205 +70,56 @@ const bkOT = new BkOpenTelemetry({
44
70
  version: '1.2.0',
45
71
  },
46
72
  transport: {
47
- endpoint: 'https://your-otlp-collector',
48
- token: 'your-report-token',
73
+ endpoint: 'https://rum-collector.example.com',
74
+ token: 'report-token',
49
75
  signals: {
50
76
  traces: {
51
77
  processor: 'batch',
52
- batch: {
53
- maxQueueSize: 2048,
54
- maxExportBatchSize: 512,
55
- },
56
- },
57
- metrics: {
58
- intervalMillis: 60_000,
78
+ batch: { maxQueueSize: 2048, maxExportBatchSize: 512 },
59
79
  },
80
+ metrics: { intervalMillis: 60_000 },
60
81
  },
61
82
  },
62
- session: {
63
- sampleRate: 0.2,
64
- },
83
+ session: { sampleRate: 0.2 },
65
84
  tracking: {
66
85
  view: {
67
- getPathGroup: url => new URL(url, location.href).pathname.replace(/\/orders\/\d+/, '/orders/:id'),
68
- excludedActivityUrls: [/\/events\/stream$/],
86
+ getPathGroup: url => new URL(url, location.href).pathname.replace(/\/orders\/[^/]+/, '/orders/:id'),
87
+ excludedActivityUrls: [/\/events\/stream(?:\?|$)/],
69
88
  },
70
89
  request: {
71
- allowedTracingUrls: ['https://api.example.com'],
90
+ allowedTracingUrls: [url => new URL(url).origin === 'https://api.example.com'],
72
91
  excludedUrls: [/\/health(?:\?|$)/],
73
92
  },
74
- longTask: { threshold: 50 },
75
- websocket: true,
93
+ blankScreen: { rootSelector: '#app' },
76
94
  },
77
95
  context: {
78
96
  user: { id: window.USER_ID },
79
97
  attributes: {
80
98
  page: () => ({ 'biz.module': 'order' }),
81
- custom: () => ({ 'biz.team': 'checkout' }),
82
- },
83
- },
84
- privacy: {
85
- redactAttributes: attributes => attributes,
86
- },
87
- });
88
- ```
89
-
90
- ## 入口字段
91
-
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 |
101
-
102
- 旧入口 `app`、`sampling`、`route`、`view`、`plugins`、`instrumentations`、`attributes`、`spanBatch` 不再支持。
103
-
104
- ## 三类信号独立开关
105
-
106
- `traces`、`metrics`、`logs` 默认全部开启。设为 `false` 会关闭对应导出链路;关闭的信号不会创建 exporter、processor 或 metric reader。
107
-
108
- ```javascript
109
- new BkOpenTelemetry({
110
- application: { name: 'trace-only-app' },
111
- transport: {
112
- signals: {
113
- traces: { endpoint: 'https://trace.example.com/v1/rum' },
114
- metrics: false,
115
- logs: false,
116
- },
117
- },
118
- });
119
- ```
120
-
121
- 根 `transport.endpoint` 可省略,但每个开启的信号必须配置独立 endpoint;三类信号不能全部关闭。关闭 Trace 后不会创建 Span,也不会注入 `traceparent`。
122
-
123
- ## View 与 SPA
124
-
125
- 自动模式会为初始加载、pathname/hash 路由、BFCache 和 Session 续期创建独立 View。query-only 和页内锚点变化不会创建新 View。
126
-
127
- ```javascript
128
- const bkOT = new BkOpenTelemetry({
129
- application: { name: 'manual-view-app' },
130
- transport: { endpoint: 'https://your-otlp-collector' },
131
- tracking: {
132
- view: { tracking: 'manual' },
133
- },
134
- });
135
-
136
- bkOT.startView({ name: '订单详情', url: location.href });
137
- bkOT.setViewName('订单详情-只读');
138
- bkOT.setViewLoadingTime();
139
- ```
140
-
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。
142
-
143
- ## Metric 如何关联 View
144
-
145
- Metric datapoint 只携带低基数 `view.url_path_group`,不携带唯一 `view.id`,避免时序基数随 PV 无限增长。
146
-
147
- 精确关联放在 View Snapshot、span 和 log:这些事件会携带 `session.id + view.id`,用户操作期间还会携带 `action.id`。需要从单个指标下钻到具体 View 时,应在后端使用 exemplar,或从原始事件派生聚合指标。
148
-
149
- ## 请求与资源
150
-
151
- Fetch/XHR 由一套请求生命周期统一采集,不会重复 patch 或重复计数。Trace Header 只对 `allowedTracingUrls` 命中的 URL 注入,包括同源请求。
152
-
153
- ```javascript
154
- new BkOpenTelemetry({
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
- },
99
+ metric: () => ({ 'biz.app': 'order-center' }),
170
100
  },
171
101
  },
172
- });
173
- ```
174
-
175
- 静态资源与请求共用一个 Resource PerformanceObserver。静态资源生成独立 span;Fetch/XHR timing 会匹配回对应请求 span。SDK 自身 OTLP 请求始终排除。
176
-
177
- ## 隐私与 Consent
178
-
179
- 默认 URL 脱敏会移除用户名、密码、query 和 hash。Action 默认只读取显式属性及可访问名称,不读取任意 DOM 文本;设备 ID 默认不持久化。
180
-
181
- ```javascript
182
- const bkOT = new BkOpenTelemetry({
183
- application: { name: 'privacy-demo' },
184
- transport: { endpoint: 'https://your-otlp-collector' },
185
102
  privacy: {
186
- trackingConsent: 'not-granted',
187
- redactUrl: url => new URL(url, location.href).origin,
188
- redactAttributes: attributes => ({ ...attributes, token: undefined }),
189
- },
190
- });
191
-
192
- await bkOT.setTrackingConsent('granted');
193
- await bkOT.setTrackingConsent('not-granted');
194
- ```
195
-
196
- 未授权时不创建 Session、不安装采集 patch。运行期可授权、撤回和再次授权。
197
-
198
- ## 全局 beforeSend
199
-
200
- `tracking.beforeSend` 在 span/log 进入 exporter 前执行,可修改属性或返回 `false` 丢弃事件。
201
-
202
- ```javascript
203
- new BkOpenTelemetry({
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';
103
+ redactAttributes(attributes) {
104
+ const next = { ...attributes };
105
+ delete next['biz.secret'];
106
+ return next;
210
107
  },
211
108
  },
212
109
  });
213
110
  ```
214
111
 
215
- 请求专属 `tracking.request.beforeSend` 额外提供原始 Request/Response 或 XMLHttpRequest 上下文。
216
-
217
- ## Session 与采样
112
+ 生产接入至少确认以下事项:
218
113
 
219
- `session.sampleRate` 范围为 `0 - 1`,默认 `1`。采样决定由 `application.name + session.id` 确定性计算,不写入额外 storage;同一 Session 内始终一致。
114
+ 1. `getPathGroup` 已把动态 ID 转成低基数路由模板。
115
+ 2. 跨域 Trace Header 白名单足够精确,服务端 CORS 已放行 `traceparent`。
116
+ 3. `user.id`、URL、错误和业务属性满足隐私要求;HTTP Body 默认保持关闭。
117
+ 4. SPA 的 `blankScreen.rootSelector` 指向真实挂载节点。
118
+ 5. 同一页面只运行一个实例,避免重复 patch Fetch/XHR/WebSocket。
220
119
 
221
- Session 固定为 15 分钟无活动过期、4 小时最长生命周期。storage key 默认按应用名和 endpoint 隔离。
120
+ ## 手动事件与 View
222
121
 
223
- ## Action、设备和安全默认值
224
-
225
- ```javascript
226
- new BkOpenTelemetry({
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',
233
- },
234
- device: { persistentId: false },
235
- blankScreen: { rootSelector: '#app' },
236
- cspViolation: true,
237
- },
238
- });
239
- ```
240
-
241
- 只有明确接受 DOM 文本采集风险时,才设置 `action.nameCollection: 'text'`。只有需要跨 Session 设备关联时,才设置 `device.persistentId: true`。
242
-
243
- ## 手动事件
244
-
245
- ```javascript
122
+ ```ts
246
123
  bkOT.setUser({ id: 'user-001' });
247
124
 
248
125
  bkOT.reportAction({
@@ -256,71 +133,33 @@ bkOT.reportCustomEvent({
256
133
  });
257
134
  ```
258
135
 
259
- ## 扩展
260
-
261
- ```javascript
262
- import { BkOpenTelemetry, createPlugin } from '@blueking/open-telemetry';
263
-
264
- const plugin = createPlugin({
265
- name: 'demo-plugin',
266
- init(context) {
267
- const span = context.startSpan('demo.plugin_ready');
268
- span.end();
269
- },
270
- });
136
+ 手动 View 最稳妥的接入方式是在 SDK 启动并建立 Session 后创建:
271
137
 
138
+ ```ts
272
139
  const bkOT = new BkOpenTelemetry({
273
- application: { name: 'extension-demo' },
140
+ application: { name: 'manual-view-app' },
274
141
  autoStart: false,
275
- transport: { endpoint: 'https://your-otlp-collector' },
276
- extensions: {
277
- plugins: [plugin],
278
- instrumentations: [],
279
- },
142
+ transport: { endpoint: 'https://rum-collector.example.com' },
143
+ tracking: { view: { tracking: 'manual' } },
280
144
  });
281
145
 
282
146
  await bkOT.start();
283
- await bkOT.flush();
284
- await bkOT.shutdown();
147
+ bkOT.startView({ name: '订单详情', url: location.href });
285
148
  ```
286
149
 
287
- 也可在 `start()` 前调用 `use(plugin)` 或 `useInstrumentation(instrumentation)`。退出上报使用 OpenTelemetry 浏览器 exporter 的 `fetch keepalive`,并在 pagehide/hidden 时 flush。
150
+ `reportAction()`、`reportCustomEvent()` 和 View 控制方法均受 Session 采样/有效状态约束。调试时先使用 `session.sampleRate: 1`。
288
151
 
289
- ## 完整配置骨架
152
+ ## 文档导航
290
153
 
291
- ```javascript
292
- new BkOpenTelemetry({
293
- application: { name: 'demo-app', environment: 'production', version: '1.0.0' },
294
- transport: {
295
- endpoint: 'https://your-otlp-collector',
296
- token: 'token',
297
- headers: {},
298
- signals: {
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
302
- },
303
- },
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: {},
308
- resource: true,
309
- error: true,
310
- webVitals: true,
311
- blankScreen: true,
312
- device: true,
313
- action: true,
314
- longTask: false,
315
- cspViolation: false,
316
- websocket: false,
317
- beforeSend: event => true,
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,
325
- });
326
- ```
154
+ | 目标 | 文档 |
155
+ | --- | --- |
156
+ | 首次接入 | [快速上手](./wikis/getting-started.md) |
157
+ | 判断能采什么、默认是否开启、产出哪类信号 | [能力矩阵](./wikis/capabilities.md) |
158
+ | 理解初始化、插件顺序、上下文、过滤和上报数据流 | [架构与数据流](./wikis/architecture.md) |
159
+ | 查完整配置、默认值和约束 | [配置参考](./wikis/configuration.md) |
160
+ | 查公开方法与导出符号 | [API 参考](./wikis/api.md) |
161
+ | 查精确 Span / Metric / Log 名和字段 | [遥测参考](./wikis/telemetry-reference.md) |
162
+ | 隐私、Consent 和低基数字段 | [隐私与公共属性](./wikis/privacy-attributes.md) |
163
+ | 没有数据或数据异常 | [调试与排障](./wikis/troubleshooting.md) |
164
+
165
+ 完整 Wiki 入口见 [`wikis/`](./wikis/README.md)。文档以当前 `src/` 和 `src/index.ts` 公开导出为事实来源,不承诺历史配置兼容。