@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.
- package/README.md +83 -244
- 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 +4 -2
- package/skills/bk-rum-otele/references/getting-started.md +16 -0
- package/skills/bk-rum-otele/references/plugins.md +99 -71
- package/skills/bk-rum-otele/references/privacy.md +5 -1
- package/skills/bk-rum-otele/references/telemetry-reference.md +3 -3
- package/skills/bk-rum-otele/references/transport-sampling.md +79 -0
|
@@ -2,50 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
# API 参考
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
本页只描述 `src/index.ts` 公开导出的 API。深层路径文件属于实现细节,接入方不应直接 import。
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 创建实例
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
|
-
import { BkOpenTelemetry } from '@blueking/open-telemetry';
|
|
10
|
+
import { BkOpenTelemetry, type BkOTOptions } from '@blueking/open-telemetry';
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const options: BkOTOptions = {
|
|
13
13
|
application: { name: 'bk-rum-demo' },
|
|
14
14
|
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
15
|
-
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const bkOT = new BkOpenTelemetry(options);
|
|
16
18
|
```
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
| --- | --- | --- |
|
|
24
|
-
| `start()` | `() => Promise<void>` | 启动 SDK,注册 provider、instrumentation 和插件。 |
|
|
25
|
-
| `shutdown()` | `() => Promise<void>` | 刷新数据、关闭 provider、清理插件;关闭后不可重启。 |
|
|
26
|
-
| `flush()` | `() => Promise<void>` | 立即刷新插件、trace、metric、log。 |
|
|
27
|
-
| `use(plugin)` | `(plugin) => this` | 注册自定义插件,须在 `start()` 前。 |
|
|
28
|
-
| `useInstrumentation(instr)` | `(instr) => this` | 注册额外 OpenTelemetry instrumentation,须在 `start()` 前。 |
|
|
29
|
-
| `setUser(user)` | `(user) => void` | 更新用户上下文(`user.id`)。 |
|
|
30
|
-
| `setTrackingConsent(consent)` | `(consent) => Promise<void>` | 授予或撤销采集授权,并启动或停止采集。 |
|
|
31
|
-
| `startView(options?)` | `(options?) => void` | 结束当前 View 并创建新 View。可在 SDK 启动前调用。 |
|
|
32
|
-
| `setViewName(name)` | `(name) => void` | 更新当前 View 名称,不创建新 View。 |
|
|
33
|
-
| `setViewLoadingTime()` | `() => void` | 使用当前时刻覆盖当前 View 的自动页面稳定耗时。 |
|
|
34
|
-
| `reportAction(payload)` | `(payload) => void` | 手动上报用户动作(受采样控制)。 |
|
|
35
|
-
| `reportCustomEvent(payload)` | `(payload) => void` | 手动上报自定义事件(受采样控制)。 |
|
|
36
|
-
| `startSpan(name, attributes?, options?)` | `(...) => Span` | 创建并返回一个 span,自动带上运行时属性与脱敏。 |
|
|
37
|
-
| `emitLog(record)` | `(record) => void` | 发送一条 log,自动合并运行时属性与脱敏。 |
|
|
38
|
-
| `getRuntimeAttributes()` | `() => Attributes` | 读取当前运行时公共属性快照。 |
|
|
39
|
-
| `setRuntimeAttributes(attributes)` | `(attributes) => void` | 写入运行时公共属性。 |
|
|
40
|
-
| `applyRedact(attributes)` | `(attributes) => Attributes` | 对属性执行一次 `privacy.redactAttributes`。 |
|
|
41
|
-
| `config` | `ResolvedBkOTConfig` | 解析后的只读配置。 |
|
|
42
|
-
| `tracer` / `meter` / `logger` | OpenTelemetry 原生对象 | 用于直接操作三类信号 provider。 |
|
|
43
|
-
|
|
44
|
-
> `startSpan` / `emitLog` / `getRuntimeAttributes` 等既是实例方法,也是自定义插件 `init(context)` 中 `context` 的能力,见[自定义插件](./custom-plugin.md)。
|
|
45
|
-
|
|
46
|
-
### start
|
|
47
|
-
|
|
48
|
-
启动 SDK,注册 provider、instrumentation 和插件。
|
|
20
|
+
构造函数同步解析配置并创建三个 OpenTelemetry Provider;`autoStart: true` 时随后异步启动采集。完整配置见[配置参考](./configuration.md)。
|
|
21
|
+
|
|
22
|
+
## 生命周期方法
|
|
23
|
+
|
|
24
|
+
### start()
|
|
49
25
|
|
|
50
26
|
```ts
|
|
51
27
|
const bkOT = new BkOpenTelemetry({
|
|
@@ -54,178 +30,250 @@ const bkOT = new BkOpenTelemetry({
|
|
|
54
30
|
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
55
31
|
});
|
|
56
32
|
|
|
33
|
+
bkOT.use(myPlugin);
|
|
57
34
|
await bkOT.start();
|
|
58
35
|
```
|
|
59
36
|
|
|
60
|
-
|
|
37
|
+
启动 Session、View、内置插件、接入方插件和 instrumentations,并安装页面隐藏时的 flush 监听。重复调用 `start()` 不会重复启动。
|
|
61
38
|
|
|
62
|
-
|
|
39
|
+
### flush()
|
|
63
40
|
|
|
64
41
|
```ts
|
|
65
|
-
await bkOT.
|
|
42
|
+
await bkOT.flush();
|
|
66
43
|
```
|
|
67
44
|
|
|
68
|
-
|
|
45
|
+
先并行调用已启动插件的 `flush()`,再 force flush Trace、Metric、Log Provider。SDK 已在 `pagehide` 和页面变为 hidden 时触发 flush;业务只需在关键流程完成后按需主动调用。
|
|
69
46
|
|
|
70
|
-
|
|
47
|
+
### shutdown()
|
|
71
48
|
|
|
72
49
|
```ts
|
|
73
|
-
|
|
74
|
-
void bkOT.flush();
|
|
75
|
-
});
|
|
50
|
+
await bkOT.shutdown();
|
|
76
51
|
```
|
|
77
52
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
注册自定义插件,必须在 `start()` 前调用。
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
bkOT.use(
|
|
84
|
-
createPlugin({
|
|
85
|
-
name: 'biz-plugin',
|
|
86
|
-
init(context) {
|
|
87
|
-
const span = context.startSpan('custom.biz_plugin_ready');
|
|
88
|
-
span.end();
|
|
89
|
-
},
|
|
90
|
-
}),
|
|
91
|
-
);
|
|
92
|
-
```
|
|
53
|
+
反向关闭插件、结束待处理事件、刷新 Provider 并清理浏览器 patch/监听。该方法幂等;关闭后不能重新启动同一实例,再调用 `start()` 会抛错。
|
|
93
54
|
|
|
94
|
-
|
|
55
|
+
## Consent
|
|
95
56
|
|
|
96
|
-
|
|
57
|
+
### setTrackingConsent(consent)
|
|
97
58
|
|
|
98
59
|
```ts
|
|
99
|
-
bkOT
|
|
100
|
-
|
|
60
|
+
const bkOT = new BkOpenTelemetry({
|
|
61
|
+
application: { name: 'consent-demo' },
|
|
62
|
+
privacy: { trackingConsent: 'not-granted' },
|
|
63
|
+
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
64
|
+
});
|
|
101
65
|
|
|
102
|
-
|
|
66
|
+
await bkOT.setTrackingConsent('granted');
|
|
67
|
+
await bkOT.setTrackingConsent('not-granted');
|
|
68
|
+
```
|
|
103
69
|
|
|
104
|
-
|
|
70
|
+
- 未授权:不创建 Session/View,不启动插件,不 patch 浏览器 API。
|
|
71
|
+
- 授权:启动采集并建立新的 Session/View。
|
|
72
|
+
- 撤销:关闭采集副作用并 flush 已允许的数据。
|
|
73
|
+
- 再授权:插件会再次执行 `init()`。
|
|
105
74
|
|
|
106
|
-
|
|
107
|
-
bkOT.setUser({
|
|
108
|
-
id: 'user-12345',
|
|
109
|
-
});
|
|
110
|
-
```
|
|
75
|
+
该方法在 `autoStart: false` 且尚未 `start()` 时只更新状态;随后 `start()` 使用最新 Consent。
|
|
111
76
|
|
|
112
|
-
|
|
77
|
+
## User 与 View
|
|
113
78
|
|
|
114
|
-
|
|
79
|
+
### setUser(user)
|
|
115
80
|
|
|
116
81
|
```ts
|
|
117
|
-
|
|
118
|
-
|
|
82
|
+
bkOT.setUser({ id: 'user-12345' });
|
|
83
|
+
bkOT.setUser({ id: undefined });
|
|
119
84
|
```
|
|
120
85
|
|
|
121
|
-
|
|
86
|
+
更新后续事件的 `user.id`。SDK 不 hash、不脱敏、不改写该值。
|
|
122
87
|
|
|
123
|
-
|
|
88
|
+
### startView(options?)
|
|
89
|
+
|
|
90
|
+
结束当前 View 并创建新 View,`view.id` 始终由 SDK 生成。
|
|
124
91
|
|
|
125
92
|
```ts
|
|
93
|
+
const bkOT = new BkOpenTelemetry({
|
|
94
|
+
application: { name: 'manual-view-demo' },
|
|
95
|
+
autoStart: false,
|
|
96
|
+
tracking: { view: { tracking: 'manual' } },
|
|
97
|
+
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
await bkOT.start();
|
|
126
101
|
bkOT.startView({
|
|
127
|
-
name: '
|
|
128
|
-
url:
|
|
129
|
-
attributes: {
|
|
130
|
-
'biz.owner': 'portal-team',
|
|
131
|
-
},
|
|
102
|
+
name: '订单详情',
|
|
103
|
+
url: location.href,
|
|
104
|
+
attributes: { 'biz.owner': 'order-team' },
|
|
132
105
|
});
|
|
133
106
|
```
|
|
134
107
|
|
|
135
|
-
|
|
108
|
+
`BkOTStartViewOptions` 包含 `name?`、`url?`、`attributes?`。调用时必须已有采样有效的 Session;例如 `autoStart: false` 且尚未 `await start()`、未授权或未采样时,调用会被忽略。自动启动过程中、Page View 插件尚未初始化时发出的有效命令会由运行时队列交给插件消费,但接入代码仍推荐显式等待 `start()`。`attributes` 不能覆盖 SDK 的 Session/View 保留字段。
|
|
136
109
|
|
|
137
|
-
|
|
110
|
+
### setViewName(name)
|
|
138
111
|
|
|
139
112
|
```ts
|
|
140
|
-
bkOT.setViewName('
|
|
113
|
+
bkOT.setViewName('订单详情-只读');
|
|
141
114
|
```
|
|
142
115
|
|
|
143
|
-
|
|
116
|
+
更新当前 View 名称,不创建新 View。后续子事件使用新名称,View Snapshot 产生 update。
|
|
144
117
|
|
|
145
|
-
|
|
118
|
+
### setViewLoadingTime()
|
|
146
119
|
|
|
147
120
|
```ts
|
|
148
121
|
await renderAsyncPage();
|
|
149
122
|
bkOT.setViewLoadingTime();
|
|
150
123
|
```
|
|
151
124
|
|
|
152
|
-
|
|
125
|
+
用“当前时刻 - View 开始时刻”覆盖自动 `view.loading_time`。每次调用替换前一次值;没有有效 View 时忽略。
|
|
153
126
|
|
|
154
|
-
|
|
127
|
+
## 手动事件
|
|
128
|
+
|
|
129
|
+
### reportAction(payload)
|
|
155
130
|
|
|
156
131
|
```ts
|
|
157
132
|
bkOT.reportAction({
|
|
158
133
|
name: '保存',
|
|
159
|
-
attributes: {
|
|
160
|
-
'biz.form': 'alarm-strategy',
|
|
161
|
-
},
|
|
134
|
+
attributes: { 'biz.form': 'alarm-strategy' },
|
|
162
135
|
});
|
|
163
136
|
```
|
|
164
137
|
|
|
165
|
-
|
|
138
|
+
创建并立即结束 `action.custom` Span,写入新的 `action.id`、`action.name` 和 `action.type=custom`。它不会触发自动点击的活动耗时、关联计数或挫败信号计算。
|
|
166
139
|
|
|
167
|
-
|
|
140
|
+
### reportCustomEvent(payload)
|
|
168
141
|
|
|
169
142
|
```ts
|
|
170
143
|
bkOT.reportCustomEvent({
|
|
171
144
|
name: 'strategy_saved',
|
|
172
|
-
attributes: {
|
|
173
|
-
'biz.strategy_id': '10001',
|
|
174
|
-
},
|
|
145
|
+
attributes: { 'biz.strategy_id': '10001' },
|
|
175
146
|
});
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
带错误的自定义事件:
|
|
179
147
|
|
|
180
|
-
```ts
|
|
181
148
|
bkOT.reportCustomEvent({
|
|
182
149
|
name: 'strategy_save_failed',
|
|
183
150
|
error: new Error('validation failed'),
|
|
184
|
-
attributes: {
|
|
185
|
-
'biz.strategy_id': '10001',
|
|
186
|
-
},
|
|
187
151
|
});
|
|
188
152
|
```
|
|
189
153
|
|
|
190
|
-
|
|
154
|
+
创建 `custom.<name>` Span,并合并 `context.attributes.page`、`context.attributes.custom` 与 payload attributes。传入 `error` 时记录 exception、设置 Span Status/`result=error`,但 `span_type` 仍为 `custom`。
|
|
155
|
+
|
|
156
|
+
两类方法均受 Session 采样控制;未采样时直接返回。`debug: true` 仅对被丢弃的 Custom Event 输出 warning。
|
|
157
|
+
|
|
158
|
+
## 自定义信号
|
|
159
|
+
|
|
160
|
+
### startSpan(name, attributes?, options?)
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
const startedAt = Date.now();
|
|
164
|
+
const span = bkOT.startSpan(
|
|
165
|
+
'custom.cache_warmup',
|
|
166
|
+
{ 'biz.cache': 'homepage' },
|
|
167
|
+
{ startTime: startedAt, contextTime: startedAt },
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
span.end();
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
自动合并事件发生时的运行时上下文,并应用 `privacy.redactAttributes`。第三个参数的内部形状名为 `BkOTStartSpanOptions`,但该类型没有从包根导出,接入方直接按下表传对象即可,不要生成对它的 import:
|
|
174
|
+
|
|
175
|
+
| 字段 | 说明 |
|
|
176
|
+
| --- | --- |
|
|
177
|
+
| `startTime` | OpenTelemetry `TimeInput`;常用 epoch ms |
|
|
178
|
+
| `contextTime` | 用该 epoch ms 从历史快照解析 Session/View/Action;数字型 `startTime` 默认同时作为该值 |
|
|
179
|
+
| `kind` | OpenTelemetry `SpanKind`,默认 `INTERNAL` |
|
|
180
|
+
|
|
181
|
+
只有已采样且同时带有效 `session.id`、`view.id` 的 Span 会导出。
|
|
182
|
+
|
|
183
|
+
### emitLog(record)
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
bkOT.emitLog({
|
|
187
|
+
severityText: 'INFO',
|
|
188
|
+
body: 'biz.cache_ready',
|
|
189
|
+
attributes: { 'biz.cache': 'homepage' },
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
自动合并运行时上下文与脱敏。自定义插件应使用 `emitLog()`,不要直接调用 `logger.emit()`。
|
|
194
|
+
|
|
195
|
+
### tracer / meter / logger
|
|
196
|
+
|
|
197
|
+
实例公开 SDK 私有 Provider 对应的原生 OpenTelemetry `Tracer`、`Meter`、`Logger`。优先使用 `startSpan()` 与 `emitLog()`。当前没有公开稳定的自定义 Metric 采样 helper,直接通过 `meter` 创建的数据点默认无法通过过滤器,不应作为接入方稳定能力;详见[架构与数据流](./architecture.md#扩展边界)。
|
|
198
|
+
|
|
199
|
+
## 扩展注册
|
|
200
|
+
|
|
201
|
+
### use(plugin)
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
bkOT.use(
|
|
205
|
+
createPlugin({
|
|
206
|
+
name: 'biz-plugin',
|
|
207
|
+
init(context) {
|
|
208
|
+
context.startSpan('custom.biz_plugin_ready').end();
|
|
209
|
+
},
|
|
210
|
+
}),
|
|
211
|
+
);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### useInstrumentation(instrumentation)
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
bkOT.useInstrumentation(new SomeWebInstrumentation());
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
两者都必须在 `start()` 前调用;使用默认自动启动时没有可靠的动态注册窗口,推荐配置 `autoStart: false`。完整插件契约见[自定义插件](./custom-plugin.md)。
|
|
221
|
+
|
|
222
|
+
额外 instrumentation 的稳定扩展边界是 Trace。第三方 Metric 不会自动获得 SDK 内部采样标记,默认无法通过 Metric 过滤器。
|
|
223
|
+
|
|
224
|
+
## 运行时与诊断成员
|
|
225
|
+
|
|
226
|
+
| 成员 | 返回/作用 |
|
|
227
|
+
| --- | --- |
|
|
228
|
+
| `config` | `resolveConfig()` 解析后的 `ResolvedBkOTConfig` |
|
|
229
|
+
| `applyRedact(attributes)` | 执行 `privacy.redactAttributes` |
|
|
230
|
+
| `getRuntimeAttributes()` | 当前公共属性快照 |
|
|
231
|
+
| `getRuntimeAttributesAt(timestamp)` | 指定 epoch ms 的历史公共属性快照 |
|
|
232
|
+
| `setRuntimeAttributes(attributes, changedAt?)` | 写入公共属性;高级扩展 API,谨慎避免覆盖 SDK 字段 |
|
|
233
|
+
| `isSampled()` | 当前 Session 是否命中采样 |
|
|
234
|
+
| `isSessionActive()` | 是否存在有效 Session |
|
|
235
|
+
| `isViewActive()` | 是否存在有效 View |
|
|
236
|
+
| `onSessionLifecycle(listener)` | 订阅 Session renewed/expired,返回取消函数 |
|
|
237
|
+
| `notifySessionLifecycle(event)` | 向运行时分发生命周期事件;主要供高级插件使用 |
|
|
238
|
+
|
|
239
|
+
## createPlugin(plugin)
|
|
240
|
+
|
|
241
|
+
`createPlugin()` 是保留完整类型推导的恒等构造器。
|
|
191
242
|
|
|
192
243
|
```ts
|
|
193
244
|
import { createPlugin } from '@blueking/open-telemetry';
|
|
194
245
|
|
|
195
|
-
|
|
246
|
+
const plugin = createPlugin({
|
|
196
247
|
name: 'page-visible',
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
attributes: {
|
|
202
|
-
'document.visibility_state': document.visibilityState,
|
|
203
|
-
},
|
|
204
|
-
});
|
|
205
|
-
},
|
|
248
|
+
enabled: config => config.enabled,
|
|
249
|
+
init(context) {},
|
|
250
|
+
flush() {},
|
|
251
|
+
shutdown() {},
|
|
206
252
|
});
|
|
207
253
|
```
|
|
208
254
|
|
|
209
|
-
|
|
255
|
+
`BkOTPlugin` 的 `enabled` 可为布尔值或接收 `ResolvedBkOTConfig` 的函数。Plugin Manager 顺序启动、并行 flush、反向 shutdown,并隔离单个插件的初始化错误。
|
|
210
256
|
|
|
211
|
-
|
|
257
|
+
## Schema 辅助 API
|
|
212
258
|
|
|
213
|
-
|
|
214
|
-
|
|
259
|
+
### RUM_ATTRIBUTES
|
|
260
|
+
|
|
261
|
+
归一字段 key 常量。
|
|
215
262
|
|
|
263
|
+
```ts
|
|
216
264
|
bkOT.reportCustomEvent({
|
|
217
265
|
name: 'biz_event',
|
|
218
|
-
attributes: {
|
|
219
|
-
[RUM_ATTRIBUTES.targetLabel]: 'submit-order',
|
|
220
|
-
},
|
|
266
|
+
attributes: { [RUM_ATTRIBUTES.targetLabel]: 'submit-order' },
|
|
221
267
|
});
|
|
222
268
|
```
|
|
223
269
|
|
|
224
|
-
|
|
270
|
+
### RUM_SPAN_TYPE / RUM_SPAN_RESULT
|
|
225
271
|
|
|
226
|
-
|
|
227
|
-
|
|
272
|
+
分别提供标准 `span_type` 与 `result` 值。
|
|
273
|
+
|
|
274
|
+
### buildRumSpanAttributes(classification)
|
|
228
275
|
|
|
276
|
+
```ts
|
|
229
277
|
const span = bkOT.startSpan('custom.cache_hit', {
|
|
230
278
|
...buildRumSpanAttributes({
|
|
231
279
|
spanType: RUM_SPAN_TYPE.custom,
|
|
@@ -235,26 +283,79 @@ const span = bkOT.startSpan('custom.cache_hit', {
|
|
|
235
283
|
targetValue: true,
|
|
236
284
|
}),
|
|
237
285
|
});
|
|
238
|
-
|
|
239
286
|
span.end();
|
|
240
287
|
```
|
|
241
288
|
|
|
242
|
-
|
|
289
|
+
### getDurationBucket(duration)
|
|
290
|
+
|
|
291
|
+
返回 `<100ms`、`100~500ms`、`500ms~2s`、`>2s` 之一。
|
|
292
|
+
|
|
293
|
+
### buildRumSpanAttributes 相关类型
|
|
243
294
|
|
|
244
|
-
`
|
|
295
|
+
公开 `RumSpanClassification`、`RumSpanType`、`RumSpanResult`,用于扩展插件保持同一归一模型。
|
|
296
|
+
|
|
297
|
+
## resolveConfig(options)
|
|
245
298
|
|
|
246
299
|
```ts
|
|
247
300
|
import { resolveConfig } from '@blueking/open-telemetry';
|
|
248
301
|
|
|
249
302
|
const config = resolveConfig({
|
|
250
|
-
application: {
|
|
251
|
-
|
|
252
|
-
},
|
|
253
|
-
transport: {
|
|
254
|
-
endpoint: 'https://rum-collector.example.com',
|
|
255
|
-
},
|
|
303
|
+
application: { name: 'bk-rum-demo' },
|
|
304
|
+
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
256
305
|
});
|
|
257
306
|
|
|
258
|
-
console.log(config.
|
|
259
|
-
console.log(config.transport.traces.endpoint);
|
|
307
|
+
console.log(config.transport.traces && config.transport.traces.endpoint);
|
|
260
308
|
```
|
|
309
|
+
|
|
310
|
+
用于预览核心解析结果和测试配置。插件自己的参数默认值在插件工厂执行时解析,不会全部展开到 `ResolvedBkOTConfig`。
|
|
311
|
+
|
|
312
|
+
## 内置插件工厂
|
|
313
|
+
|
|
314
|
+
公共入口导出以下工厂,便于自定义组合或测试:
|
|
315
|
+
|
|
316
|
+
| 工厂 | 选项类型 |
|
|
317
|
+
| --- | --- |
|
|
318
|
+
| `createSessionPlugin` | `BkOTSessionConfig` |
|
|
319
|
+
| `createDevicePlugin` | `BkOTDevicePluginOptions` |
|
|
320
|
+
| `createCommonInstrumentationsPlugin` | `BkOTRequestConfig \| boolean` |
|
|
321
|
+
| `createResourcePlugin` | 直接传 `boolean`,控制是否为静态资源创建 Span;默认 `true` |
|
|
322
|
+
| `createErrorPlugin` | `BkOTErrorPluginOptions` |
|
|
323
|
+
| `createWebVitalsPlugin` | 无 |
|
|
324
|
+
| `createBlankScreenPlugin` | `BkOTBlankScreenPluginOptions` |
|
|
325
|
+
| `createActionPlugin` | `BkOTActionPluginOptions` |
|
|
326
|
+
| `createLongTaskPlugin` | `BkOTLongTaskPluginOptions` |
|
|
327
|
+
| `createWebSocketPlugin` | 无 |
|
|
328
|
+
| `createCspViolationPlugin` | 无 |
|
|
329
|
+
|
|
330
|
+
`createCommonInstrumentationsPlugin` 名称保留,但当前实现是 SDK 自有 Fetch/XHR patch,不注册官方 Fetch/XHR instrumentation。
|
|
331
|
+
|
|
332
|
+
## 其他公共导出
|
|
333
|
+
|
|
334
|
+
`src/index.ts` 还导出以下高级能力:
|
|
335
|
+
|
|
336
|
+
- `RumRuntimeContext` 及 Session/View/User 相关类型。
|
|
337
|
+
- `PluginManager`。
|
|
338
|
+
- `FilteringSpanProcessor`、`FilteringMetricExporter`、`FilteringLogRecordProcessor`。
|
|
339
|
+
- `EXCLUDED_ACTIVITY_MUTATIONS_ATTRIBUTE`,用于标记不应延长 View Loading/Action 的 DOM 子树。
|
|
340
|
+
- 配置输入、解析结果、Transport、Hook、请求上下文等 TypeScript 类型。
|
|
341
|
+
|
|
342
|
+
这些主要服务 SDK 维护和高级扩展;常规接入只需 `BkOpenTelemetry`、`BkOTOptions` 和手动事件类型。
|
|
343
|
+
|
|
344
|
+
`BkOpenTelemetry` 具体类上还能看到 `registerInstrumentations()`,它用于 SDK 向插件运行时提供批量注册能力,但被刻意排除在 `BkOTInstance` 契约之外,也会绕过 `useInstrumentation()` 的启动阶段检查。接入方不要直接调用;使用 `extensions.instrumentations` 或 `useInstrumentation()`。
|
|
345
|
+
|
|
346
|
+
## 公共类型索引
|
|
347
|
+
|
|
348
|
+
以下名称都可以从包根路径执行 `import type`:
|
|
349
|
+
|
|
350
|
+
| 分类 | 类型 |
|
|
351
|
+
| --- | --- |
|
|
352
|
+
| 顶层配置 | `BkOTOptions`、`BkOTApplicationConfig`、`BkOTTransportConfig`、`BkOTTrackingConfig`、`BkOTTrackingConsent`、`BkOTContextConfig`、`BkOTPrivacyConfig`、`BkOTExtensionsConfig` |
|
|
353
|
+
| Transport | `BkOTBatchConfig`、`SignalExporterConfig`、`SignalExporterInputConfig`、`SignalExportersInputConfig`、`TraceExporterInputConfig`、`MetricExporterInputConfig` |
|
|
354
|
+
| View/Session/User | `BkOTViewConfig`、`BkOTSessionConfig`、`BkOTStartViewOptions`、`BkOTViewContext`、`BkOTSessionLifecycleEvent`、`BkOTUserContext` |
|
|
355
|
+
| Request | `BkOTRequestConfig`、`BkOTRequestEvent`、`BkOTRequestContext`、`BkOTRequestBodyConfig`、`BkOTRequestBodyRedactPayload`、`BkOTUrlMatcher` |
|
|
356
|
+
| 事件与 Hook | `BkOTActionEventPayload`、`BkOTCustomEventPayload`、`BkOTBeforeSendEvent`、`BkOTAttributesConfig`、`BkOTAttributeValue` |
|
|
357
|
+
| 插件 | `BkOTPlugin`、`BkOTRuntimeContext`、`BkOTActionPluginOptions`、`BkOTBlankScreenPluginOptions`、`BkOTDevicePluginOptions`、`BkOTErrorPluginOptions`、`BkOTLongTaskPluginOptions` |
|
|
358
|
+
| 实例与解析结果 | `BkOTInstance`、`PluginManager`、`ResolvedBkOTConfig`、`ResolvedApplicationConfig`、`ResolvedTransportConfig`、`ResolvedViewConfig`、`ResolvedConfigHooks` |
|
|
359
|
+
| Schema | `RumAttributeKey`、`RumSpanClassification`、`RumSpanType`、`RumSpanResult` |
|
|
360
|
+
|
|
361
|
+
如某个源码类型没有出现在本表,也没有从 `src/index.ts` 导出,则它不是包的公共契约。
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
|
|
2
|
+
|
|
3
|
+
# 架构与数据流
|
|
4
|
+
|
|
5
|
+
本页描述当前 `src/` 的实现边界,适合 SDK 维护者、扩展插件作者和需要解释“为什么数据没有被导出”的接入方。
|
|
6
|
+
|
|
7
|
+
## 源码模块
|
|
8
|
+
|
|
9
|
+
| 目录/文件 | 职责 | 稳定入口 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `src/index.ts` | ESM 公共导出边界 | npm import 只能依赖这里导出的符号 |
|
|
12
|
+
| `src/browser.ts` | CDN/IIFE 入口 | 暴露 `window.BkOpenTelemetry` |
|
|
13
|
+
| `src/core/config.ts` | 输入类型、校验、默认值、Endpoint 与 Hook 解析 | `BkOTOptions`、`resolveConfig()` |
|
|
14
|
+
| `src/core/sdk.ts` | Provider、Exporter、生命周期、内置插件组合、公开实例 API | `BkOpenTelemetry` |
|
|
15
|
+
| `src/core/runtime-context.ts` | User/Session/View/Action 属性快照与历史归属 | `RumRuntimeContext` |
|
|
16
|
+
| `src/core/processor.ts` | Span/Metric/Log 的采样、上下文、自上报和 beforeSend 过滤 | 三个 Filtering 类 |
|
|
17
|
+
| `src/core/plugin.ts` | 插件契约、启动、并行 flush、反向 shutdown、错误隔离 | `createPlugin()` |
|
|
18
|
+
| `src/plugins/` | 浏览器采集与 RUM 语义 | 各 `create*Plugin()` |
|
|
19
|
+
| `src/schema/` | 归一字段、Span 类型、结果和耗时分桶 | `RUM_ATTRIBUTES`、`buildRumSpanAttributes()` |
|
|
20
|
+
|
|
21
|
+
文档描述与源码冲突时,以 `src/index.ts` 的公开导出和对应实现为准。`dist/` 是构建产物,不作为文档事实源。
|
|
22
|
+
|
|
23
|
+
## 构造、启动与关闭
|
|
24
|
+
|
|
25
|
+
### 构造阶段
|
|
26
|
+
|
|
27
|
+
`new BkOpenTelemetry(options)` 同步完成:
|
|
28
|
+
|
|
29
|
+
1. `resolveConfig()` 校验 `application.name`、Transport 和已启用信号的 Endpoint。
|
|
30
|
+
2. 创建 Resource、TracerProvider、MeterProvider、LoggerProvider。
|
|
31
|
+
3. 根据三类信号开关决定是否创建 exporter、processor 或 metric reader。
|
|
32
|
+
4. 创建运行时上下文;初始状态尚无 Session/View,也未命中采样。
|
|
33
|
+
5. `autoStart !== false` 时异步调用 `start()`。
|
|
34
|
+
|
|
35
|
+
因此,需要在启动前注册扩展或立即创建手动 View 时,应显式设置 `autoStart: false`。
|
|
36
|
+
|
|
37
|
+
### 启动阶段
|
|
38
|
+
|
|
39
|
+
`start()` 幂等。获得 Consent 且 `enabled=true` 时,插件按以下顺序初始化:
|
|
40
|
+
|
|
41
|
+
1. 上下文:Session → Device → Activity → View → Resource Observer。
|
|
42
|
+
2. 请求:统一 Fetch/XHR patch。
|
|
43
|
+
3. RUM:Error → Web Vitals → Blank Screen → Action → 按需 WebSocket / Long Task / CSP。
|
|
44
|
+
4. 接入方 `extensions.plugins`。
|
|
45
|
+
5. 接入方 OpenTelemetry instrumentations。
|
|
46
|
+
|
|
47
|
+
单个插件 `init()` 抛错不会阻断其他插件;仅在 `debug: true` 时输出 warning。Consent 撤销后再授权会重新执行插件 `init()`,插件必须在 `shutdown()` 中完整释放监听和 patch。
|
|
48
|
+
|
|
49
|
+
### flush 与 shutdown
|
|
50
|
+
|
|
51
|
+
- `flush()`:并行刷新插件,再 force flush Trace、Metric、Log provider。
|
|
52
|
+
- `shutdown()`:反向关闭插件,结束/刷新最终数据,移除页面生命周期监听,关闭三个 provider。
|
|
53
|
+
- `shutdown()` 后同一实例不能重新启动;需要重新创建实例。
|
|
54
|
+
- SDK 在 `pagehide` 和页面变为 hidden 时主动调用 `flush()`。
|
|
55
|
+
|
|
56
|
+
## 从浏览器事件到 OTLP
|
|
57
|
+
|
|
58
|
+
一次事件的公共路径是:
|
|
59
|
+
|
|
60
|
+
1. 插件或公开 API 观察浏览器事件。
|
|
61
|
+
2. 从 `RumRuntimeContext` 读取事件发生时对应的 User、Session、View、Action 属性。
|
|
62
|
+
3. 构造原生 OpenTelemetry Span、Metric datapoint 或 LogRecord。
|
|
63
|
+
4. 应用 URL/属性脱敏和事件级 Hook。
|
|
64
|
+
5. Filtering processor/exporter 校验采样与上下文。
|
|
65
|
+
6. 通过对应 OTLP HTTP exporter 上报。
|
|
66
|
+
|
|
67
|
+
不同信号的最终过滤规则不同:
|
|
68
|
+
|
|
69
|
+
| 信号 | 接受条件 | 最终 Hook |
|
|
70
|
+
| --- | --- | --- |
|
|
71
|
+
| Span | 已采样,且同时有有效 `session.id`、`view.id`;排除 SDK 上报请求和请求级丢弃标记 | `tracking.beforeSend` |
|
|
72
|
+
| Log | 同 Span;`session.start/rotate` 允许只有有效 Session | `tracking.beforeSend` |
|
|
73
|
+
| Metric | datapoint 带内部已采样标记;导出前移除该标记 | 无全局 beforeSend |
|
|
74
|
+
|
|
75
|
+
这意味着手动模式首次 `startView()` 之前,普通 Span/Log 不会导出;只创建原生 meter 数据但没有使用 SDK 采样属性的自定义 Metric 也不会导出。
|
|
76
|
+
|
|
77
|
+
## 运行时上下文与历史归属
|
|
78
|
+
|
|
79
|
+
运行时上下文维护当前属性,也保留有限的变更时间线。PerformanceObserver 经常在事件结束后才回调,因此 `startSpan(..., { startTime, contextTime })` 可以按事件真实发生时间解析其所属 Session/View/Action,避免把旧页面资源归到新 View。
|
|
80
|
+
|
|
81
|
+
### Span 与 Log
|
|
82
|
+
|
|
83
|
+
Span/Log 可携带唯一关联字段:
|
|
84
|
+
|
|
85
|
+
- `user.id`
|
|
86
|
+
- `session.id`
|
|
87
|
+
- `view.id`、`view.name`、`view.url`、`view.url_path_group`
|
|
88
|
+
- 活动期间的 `action.id`
|
|
89
|
+
|
|
90
|
+
### Metric
|
|
91
|
+
|
|
92
|
+
Metric 只保留 `view.url_path_group` 等低基数属性,不携带 `session.id`、`view.id`、`action.id`。需要从聚合指标下钻到具体访问时,查询同名语义 Span 或 View Snapshot Log,或由后端使用 exemplar/派生数据建立关联。
|
|
93
|
+
|
|
94
|
+
## Session、采样与 Consent
|
|
95
|
+
|
|
96
|
+
三者是不同控制层:
|
|
97
|
+
|
|
98
|
+
| 控制层 | 决定什么 | 运行期变化 |
|
|
99
|
+
| --- | --- | --- |
|
|
100
|
+
| `enabled` | 实例是否启动采集 | 构造后不提供 Setter |
|
|
101
|
+
| Consent | 是否安装采集副作用、创建 Session/View | `setTrackingConsent()` 可授权/撤销 |
|
|
102
|
+
| `session.sampleRate` | 有效 Session 的数据是否进入导出链路 | Session 轮换后用新 ID 重新计算 |
|
|
103
|
+
| Signal 开关 | 是否存在对应 exporter/processor/reader | 构造时固定 |
|
|
104
|
+
|
|
105
|
+
Session 采样由 `application.name + session.id` 稳定 hash 决定,同一 Session 的三类信号保持一致。插件仍可维护页面生命周期,但未采样数据会在创建或导出路径被丢弃。
|
|
106
|
+
|
|
107
|
+
## 请求采集设计
|
|
108
|
+
|
|
109
|
+
Fetch/XHR 由 `createCommonInstrumentationsPlugin()` 的单一生命周期直接 patch,不叠加官方 Fetch/XHR instrumentation:
|
|
110
|
+
|
|
111
|
+
- `excludedUrls` 在最前面完全排除请求。
|
|
112
|
+
- 开始请求时创建 `browser.resource` CLIENT Span,并登记 View/Action 活动。
|
|
113
|
+
- 只有 `allowedTracingUrls` 命中且 Trace 开启时才调用全局 propagator 注入。SDK 成功注册默认 W3C propagator 时注入 `traceparent`/已有 `tracestate`;宿主已有全局 propagator 时,实际 Header 由宿主决定。
|
|
114
|
+
- Resource Observer 把同一 URL/时间窗的 PerformanceResourceTiming 匹配回请求 Span。
|
|
115
|
+
- `request.beforeSend` 可修改请求事件属性或标记丢弃该 Span。
|
|
116
|
+
- 配置 Body 且 Log 开启时,异步生成关联 `trace.id` / `span.id` 的 `browser.request.body` Log。
|
|
117
|
+
- SDK 自身所有已启用 OTLP Endpoint 始终排除,防止递归上报。
|
|
118
|
+
|
|
119
|
+
静态资源复用同一个 Resource Observer,但 Fetch/XHR entry 只用于 timing 匹配,不再创建第二条资源 Span。
|
|
120
|
+
|
|
121
|
+
## 脱敏与 Hook 顺序
|
|
122
|
+
|
|
123
|
+
| 入口 | 作用范围 | 适合用途 |
|
|
124
|
+
| --- | --- | --- |
|
|
125
|
+
| `privacy.redactUrl` | SDK 写入的 URL 类属性 | 删除 query/hash、模板化路径 |
|
|
126
|
+
| `privacy.redactAttributes` | 通过 SDK `startSpan()`、`emitLog()` 和内置插件显式应用的属性 | 删除敏感业务字段 |
|
|
127
|
+
| `tracking.request.beforeSend` | 单个 Fetch/XHR,带原始 Request/Response/XHR 上下文 | 请求专属补充或丢弃 |
|
|
128
|
+
| Request Body `redact` | 单个请求/响应 Body,必填 | 内容级脱敏;返回 `undefined` 跳过该 Body |
|
|
129
|
+
| `tracking.beforeSend` | Span/Log 进入底层 processor 前 | 最终兜底修改或丢弃;不作用于 Metric |
|
|
130
|
+
|
|
131
|
+
第三方 instrumentation 自己生成的属性不经过 SDK 的 `redactAttributes` 构造路径。若要统一约束第三方 Span,应在 `tracking.beforeSend` 中做最终清理。
|
|
132
|
+
|
|
133
|
+
## 扩展边界
|
|
134
|
+
|
|
135
|
+
- RUM 语义、Session/View 关联、Log 或活动总线:使用 `createPlugin()`。
|
|
136
|
+
- 已有标准 OpenTelemetry instrumentation:通过 `extensions.instrumentations` 或 `useInstrumentation()` 注册。
|
|
137
|
+
- 自定义 Log 使用 `context.emitLog()`,不要直接 `context.logger.emit()`,否则不会自动合并运行时上下文。
|
|
138
|
+
- 自定义 Span 优先使用 `context.startSpan()`,它会应用运行时属性与脱敏。
|
|
139
|
+
- 当前包没有导出稳定的自定义 Metric 采样属性/helper。直接使用 `context.meter` 创建的数据点默认无法通过 `FilteringMetricExporter`;不要依赖内部 `bk.rum.sampled` 字段,也不要把 `getRuntimeAttributes()` 中的唯一 Session/View/Action ID 整体复制到 labels。需要稳定扩展时优先使用 Span/Log,或先在 SDK 内补充公共 Metric API。
|
|
140
|
+
|
|
141
|
+
完整契约与示例见[自定义插件](./custom-plugin.md)。
|