@blueking/open-telemetry 0.0.21 → 0.0.22-beta.1
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 +11 -25
- package/dist/bk-rum.global.js +2 -12
- package/dist/bk-rum.global.js.map +1 -1
- package/dist/core/config.d.ts +8 -44
- package/dist/core/hash.d.ts +2 -0
- package/dist/core/plugin.d.ts +2 -7
- package/dist/core/processor.d.ts +0 -20
- package/dist/core/sdk.d.ts +1 -7
- package/dist/core/telemetry-attributes.d.ts +1 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1045 -1471
- package/dist/index.js.map +1 -1
- package/dist/plugins/common.d.ts +1 -1
- package/dist/plugins/csp-violation.d.ts +0 -8
- package/dist/plugins/error.d.ts +1 -5
- package/dist/plugins/long-task.d.ts +1 -3
- package/dist/plugins/web-vitals.d.ts +1 -4
- package/dist/schema/attributes.d.ts +8 -10
- package/dist/schema/span.d.ts +2 -0
- package/package.json +1 -6
- package/skills/bk-rum-otele/SKILL.md +3 -3
- package/skills/bk-rum-otele/evals/evals.json +2 -2
- package/skills/bk-rum-otele/references/api.md +10 -22
- package/skills/bk-rum-otele/references/architecture.md +38 -118
- package/skills/bk-rum-otele/references/capabilities.md +26 -28
- package/skills/bk-rum-otele/references/concepts.md +14 -106
- package/skills/bk-rum-otele/references/configuration.md +25 -66
- package/skills/bk-rum-otele/references/custom-plugin.md +10 -13
- package/skills/bk-rum-otele/references/data-model.md +23 -95
- package/skills/bk-rum-otele/references/getting-started.md +1 -1
- package/skills/bk-rum-otele/references/plugins-basic.md +7 -7
- package/skills/bk-rum-otele/references/plugins-error-security.md +1 -1
- package/skills/bk-rum-otele/references/plugins-experience.md +4 -5
- package/skills/bk-rum-otele/references/plugins-network.md +19 -128
- package/skills/bk-rum-otele/references/plugins.md +3 -3
- package/skills/bk-rum-otele/references/privacy.md +4 -25
- package/skills/bk-rum-otele/references/telemetry-reference.md +49 -279
- package/skills/bk-rum-otele/references/transport-sampling.md +15 -50
- package/skills/bk-rum-otele/references/troubleshooting.md +7 -34
- package/dist/core/metric.d.ts +0 -2
- package/dist/core/signal.d.ts +0 -3
- package/dist/core/throttle.d.ts +0 -20
- package/dist/plugins/request-body.d.ts +0 -15
|
@@ -2,122 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
# 核心概念
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## 单一原始事件通道
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
SDK 只使用 OpenTelemetry Trace:浏览器事实和本地体验语义都编码为 RUM Span,通过 `/v1/rum` 上报。浏览器不创建 Counter、Histogram 或 Log;聚合由服务端完成。
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Session、View、Action
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
11
|
+
- `session.id` 关联一次访问会话,采样以 Session 为边界。
|
|
12
|
+
- `view.id` 关联初始页面、SPA 路由、BFCache 或手动 View。
|
|
13
|
+
- `action.id` 关联一次用户动作活动窗口。
|
|
14
|
+
- `user.id` 由接入方提供,SDK 原样透传。
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
生命周期事件使用 `event.id`、`event.type`、`event.phase`、`event.timestamp`。View 额外使用 `view.version` 处理更新和乱序。
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
import { BkOpenTelemetry } from '@blueking/open-telemetry';
|
|
19
|
-
|
|
20
|
-
const bkOT = new BkOpenTelemetry({
|
|
21
|
-
application: { name: 'checkout-web' },
|
|
22
|
-
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const span = bkOT.startSpan('custom.checkout_submit', {
|
|
26
|
-
'biz.order_id': '202605270001',
|
|
27
|
-
'biz.channel': 'pc',
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
span.end();
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Session、View、User
|
|
34
|
-
|
|
35
|
-
SDK 会维护运行时公共上下文,并自动挂到后续 span/log 上:
|
|
36
|
-
|
|
37
|
-
- `user.id`:由接入方提供,SDK 原样透传,不 hash、不脱敏、不改写。
|
|
38
|
-
- `session.id`:由 session 插件生成和轮换,用于关联同一次访问会话。
|
|
39
|
-
- `view.id` / `view.name` / `view.url` / `view.url_path_group`:由 View 管理器维护,用于关联同一个页面或路由实例。
|
|
40
|
-
|
|
41
|
-
示例:登录后更新用户上下文。
|
|
42
|
-
|
|
43
|
-
```ts
|
|
44
|
-
bkOT.setUser({
|
|
45
|
-
id: 'user-12345',
|
|
46
|
-
});
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
示例:手动模式由业务路由系统创建 View。
|
|
50
|
-
|
|
51
|
-
```ts
|
|
52
|
-
// 前提:autoStart: false,且已经 await bkOT.start() 建立 Session。
|
|
53
|
-
bkOT.startView({
|
|
54
|
-
name: '商品详情',
|
|
55
|
-
url: window.location.href,
|
|
56
|
-
attributes: { 'biz.owner': 'product-team' },
|
|
57
|
-
});
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## 内置采集与扩展
|
|
61
|
-
|
|
62
|
-
SDK 将能力分为两类:
|
|
63
|
-
|
|
64
|
-
1. 内置采集:`tracking.request` 使用 SDK 自有的统一 Fetch/XHR 生命周期,负责 patch 浏览器 API、创建 `browser.resource` CLIENT Span、Trace Header 和请求 Performance Timing 匹配。
|
|
65
|
-
2. RUM 插件:View、Session、`resource`、`error`、`webVitals`、`blankScreen`、`device` 等,负责主动产生 RUM 归一数据。
|
|
66
|
-
|
|
67
|
-
用户交互统一由 SDK 的 `action` 插件采集。接入额外 instrumentation 时,应避免再注册覆盖 Fetch/XHR 或用户交互的探针,以免重复上报。
|
|
18
|
+
## 本地计算边界
|
|
68
19
|
|
|
69
|
-
|
|
70
|
-
new BkOpenTelemetry({
|
|
71
|
-
application: { name: 'demo' },
|
|
72
|
-
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
73
|
-
tracking: {
|
|
74
|
-
action: {
|
|
75
|
-
actionNameAttribute: 'data-bk-action-name',
|
|
76
|
-
maxDuration: 10000,
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
```
|
|
20
|
+
SDK 只保留必须依赖浏览器本地状态的计算:CLS、INP、View Loading Time、Action Loading Time、挫败信号和白屏判断。错误分组、计数、分位数和跨事件聚合全部交给服务端。
|
|
81
21
|
|
|
82
22
|
## 采样
|
|
83
23
|
|
|
84
|
-
`session.sampleRate`
|
|
85
|
-
|
|
86
|
-
示例:生产环境按 10% 会话采样。
|
|
87
|
-
|
|
88
|
-
```ts
|
|
89
|
-
new BkOpenTelemetry({
|
|
90
|
-
application: { name: 'demo' },
|
|
91
|
-
session: {
|
|
92
|
-
sampleRate: 0.1,
|
|
93
|
-
},
|
|
94
|
-
transport: {
|
|
95
|
-
endpoint: 'https://rum-collector.example.com',
|
|
96
|
-
},
|
|
97
|
-
});
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## 数据归一
|
|
101
|
-
|
|
102
|
-
SDK 会为 span 补充 RUM 归一字段,例如:
|
|
24
|
+
`session.sampleRate` 使用 `application.name + session.id` 做确定性采样。采样率同时写入 Resource 的 `session.sample_rate`,供后端修正总体指标。
|
|
103
25
|
|
|
104
|
-
|
|
105
|
-
- `result`:`success`、`warning`、`error`、`timeout`、`abort`
|
|
26
|
+
## 扩展
|
|
106
27
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
import { RUM_SPAN_TYPE, buildRumSpanAttributes } from '@blueking/open-telemetry';
|
|
111
|
-
|
|
112
|
-
const span = bkOT.startSpan('custom.cache_warmup', {
|
|
113
|
-
...buildRumSpanAttributes({
|
|
114
|
-
spanType: RUM_SPAN_TYPE.custom,
|
|
115
|
-
spanSubtype: 'cache_warmup',
|
|
116
|
-
}),
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
span.end();
|
|
120
|
-
```
|
|
28
|
+
自定义 RUM 插件使用 `context.startSpan()`,标准 OpenTelemetry instrumentation 通过 `extensions.instrumentations` 注册。避免重复注册 Fetch/XHR 或用户交互探针。
|
|
121
29
|
|
|
122
30
|
# 内置采集与扩展
|
|
123
31
|
|
|
@@ -147,6 +55,6 @@ new BkOpenTelemetry({
|
|
|
147
55
|
|
|
148
56
|
内置 Fetch/XHR 不再基于官方 instrumentation 叠加适配,而是由单一请求生命周期实现,避免重复 patch、重复活动计数及私有 `_addHeaders/_patchSend` 依赖。
|
|
149
57
|
|
|
150
|
-
当前扩展 instrumentation 的稳定能力边界是 Trace:Filtering Span Processor 会在 Span 创建时补充有效 RUM 上下文。
|
|
58
|
+
当前扩展 instrumentation 的稳定能力边界是 Trace:Filtering Span Processor 会在 Span 创建时补充有效 RUM 上下文。SDK 不创建 Metric Provider,第三方 instrumentation 的 Metric 不属于支持范围。
|
|
151
59
|
|
|
152
60
|
扩展必须在 `start()` 前注册;动态 Consent 重新授权时,插件可能再次执行 `init()`,所以插件的 `shutdown()` 应完整释放副作用。
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# 配置参考
|
|
4
4
|
|
|
5
|
-
`BkOpenTelemetry` 只接受当前 `BkOTOptions` 结构。`application.name` 与 `transport`
|
|
5
|
+
`BkOpenTelemetry` 只接受当前 `BkOTOptions` 结构。`application.name` 与 `transport.endpoint` 必填。
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
import { BkOpenTelemetry, type BkOTOptions } from '@blueking/open-telemetry';
|
|
@@ -20,7 +20,7 @@ const bkOT = new BkOpenTelemetry(options);
|
|
|
20
20
|
| 字段 | 类型 | 默认 | 说明 |
|
|
21
21
|
| --- | --- | --- | --- |
|
|
22
22
|
| `application` | `BkOTApplicationConfig` | 必填 | 应用 Resource 标识 |
|
|
23
|
-
| `transport` | `BkOTTransportConfig` | 必填 |
|
|
23
|
+
| `transport` | `BkOTTransportConfig` | 必填 | 单一 RUM OTLP HTTP 导出链路 |
|
|
24
24
|
| `session` | `BkOTSessionConfig` | `{ sampleRate: 1 }` | Session 存储和确定性采样 |
|
|
25
25
|
| `tracking` | `BkOTTrackingConfig` | `{}` | 内置采集、View 与事件 Hook |
|
|
26
26
|
| `context` | `BkOTContextConfig` | 无 | 初始用户与公共属性 Hook |
|
|
@@ -47,24 +47,15 @@ transport: {
|
|
|
47
47
|
endpoint: 'https://collector.example.com',
|
|
48
48
|
token: 'report-token',
|
|
49
49
|
headers: { 'X-Tenant': 'blueking' },
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
maxExportBatchSize: 512,
|
|
57
|
-
scheduledDelayMillis: 5000,
|
|
58
|
-
exportTimeoutMillis: 30000,
|
|
59
|
-
},
|
|
60
|
-
timeoutMillis: 10_000,
|
|
61
|
-
concurrencyLimit: 10,
|
|
62
|
-
},
|
|
63
|
-
metrics: {
|
|
64
|
-
intervalMillis: 60_000,
|
|
65
|
-
},
|
|
66
|
-
logs: {},
|
|
50
|
+
processor: 'batch',
|
|
51
|
+
batch: {
|
|
52
|
+
maxQueueSize: 2048,
|
|
53
|
+
maxExportBatchSize: 512,
|
|
54
|
+
scheduledDelayMillis: 5000,
|
|
55
|
+
exportTimeoutMillis: 30000,
|
|
67
56
|
},
|
|
57
|
+
timeoutMillis: 10_000,
|
|
58
|
+
concurrencyLimit: 10,
|
|
68
59
|
}
|
|
69
60
|
```
|
|
70
61
|
|
|
@@ -72,35 +63,17 @@ transport: {
|
|
|
72
63
|
|
|
73
64
|
| 字段 | 类型 | 默认 | 说明 |
|
|
74
65
|
| --- | --- | --- | --- |
|
|
75
|
-
| `endpoint` | `string` | 无 | 根地址,去掉末尾 `/`
|
|
66
|
+
| `endpoint` | `string` | 无 | 根地址,去掉末尾 `/` 后拼 `/v1/rum` |
|
|
76
67
|
| `token` | `string` | 无 | 生成 `Authorization: Bearer <token>` |
|
|
77
|
-
| `headers` | `Record<string,string>` | 无 |
|
|
78
|
-
| `
|
|
79
|
-
|
|
80
|
-
|
|
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` |
|
|
68
|
+
| `headers` | `Record<string,string>` | 无 | RUM 请求 Header |
|
|
69
|
+
| `timeoutMillis` | `number` | OTel 默认 | Exporter 超时 |
|
|
70
|
+
| `concurrencyLimit` | `number` | OTel 默认 | Exporter 并发数 |
|
|
71
|
+
| `processor` | `'batch' \| 'simple'` | `batch` | Span Processor 模式 |
|
|
72
|
+
| `batch` | `BkOTBatchConfig` | OTel 默认 | BatchSpanProcessor 参数 |
|
|
95
73
|
|
|
96
74
|
`batch` 支持 `maxQueueSize`、`maxExportBatchSize`、`scheduledDelayMillis`、`exportTimeoutMillis`。未提供时使用 OpenTelemetry `BatchSpanProcessor` 默认值。
|
|
97
75
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
- 三类信号不能全部为 `false`。
|
|
101
|
-
- 每个已开启信号必须配置单独 Endpoint,或能回退到根 `transport.endpoint`。
|
|
102
|
-
- 关闭 Trace 后不创建 Trace exporter/processor,不记录可导出的 Span,也不注入 `traceparent`。
|
|
103
|
-
- 关闭 Metric 后不创建 reader;关闭 Log 后不创建 log processor,Request Body 配置也不会产生 Log。
|
|
76
|
+
SDK 不提供 Logs/Metrics 开关或 Provider,所有 RUM 原始事件只走 `/v1/rum`。
|
|
104
77
|
|
|
105
78
|
更多行为见[传输与采样](./transport-sampling.md)。
|
|
106
79
|
|
|
@@ -132,19 +105,9 @@ URL matcher 支持字符串包含、`RegExp` 或 `(url) => boolean`。字符串
|
|
|
132
105
|
| --- | --- | --- | --- |
|
|
133
106
|
| `excludedUrls` | matcher 或 matcher[] | 无 | 命中后不采集、不注入、不计入页面活动 |
|
|
134
107
|
| `allowedTracingUrls` | matcher 或 matcher[] | 无 | W3C Trace Context 显式白名单;同源请求也必须命中,推荐 URL-aware 函数 |
|
|
135
|
-
| `beforeSend` | `(event, context) => boolean \| void` | 无 | 修改请求属性;返回 `false` 丢弃 Span
|
|
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 |
|
|
108
|
+
| `beforeSend` | `(event, context) => boolean \| void` | 无 | 修改请求属性;返回 `false` 丢弃 Span |
|
|
146
109
|
|
|
147
|
-
|
|
110
|
+
SDK 不读取或上报请求/响应 Body。
|
|
148
111
|
|
|
149
112
|
## tracking 内置能力
|
|
150
113
|
|
|
@@ -156,7 +119,7 @@ Request Body:
|
|
|
156
119
|
| `blankScreen` | `boolean \| BkOTBlankScreenPluginOptions` | `true` | 见下表 |
|
|
157
120
|
| `device` | `boolean \| BkOTDevicePluginOptions` | `true` | 见下表 |
|
|
158
121
|
| `action` | `boolean \| BkOTActionPluginOptions` | `true` | 见下表 |
|
|
159
|
-
| `longTask` | `boolean \| BkOTLongTaskPluginOptions` | `false` | `threshold=50
|
|
122
|
+
| `longTask` | `boolean \| BkOTLongTaskPluginOptions` | `false` | `threshold=50` ms |
|
|
160
123
|
| `websocket` | `boolean` | `false` | 无 |
|
|
161
124
|
| `cspViolation` | `boolean` | `false` | 无,内置同指纹 60 秒最多 5 条 |
|
|
162
125
|
|
|
@@ -196,7 +159,7 @@ tracking: {
|
|
|
196
159
|
}
|
|
197
160
|
```
|
|
198
161
|
|
|
199
|
-
该 Hook 在 Span
|
|
162
|
+
该 Hook 在 Span 进入底层 processor 前执行,可原地修改属性或返回 `false` 丢弃。异常会被吞掉,`debug: true` 时输出 warning;请求专属逻辑优先使用 `tracking.request.beforeSend`。
|
|
200
163
|
|
|
201
164
|
## context
|
|
202
165
|
|
|
@@ -204,11 +167,10 @@ tracking: {
|
|
|
204
167
|
| --- | --- | --- | --- |
|
|
205
168
|
| `user.id` | `string` | 无 | SDK 原样写入 `user.id` |
|
|
206
169
|
| `attributes.page` | `() => Attributes` | host/path | 页面、请求、错误、Action 等事件属性 |
|
|
207
|
-
| `attributes.metric` | `() => Attributes` | `{}` | 内置 Metric 的低基数自定义维度 |
|
|
208
170
|
| `attributes.error` | `() => Attributes` | `{}` | Error Span 附加属性 |
|
|
209
171
|
| `attributes.custom` | `() => Attributes` | `{}` | `reportCustomEvent()` 附加属性 |
|
|
210
172
|
|
|
211
|
-
自定义 `page` Hook 会替换默认 host/path Hook,不是合并默认实现。
|
|
173
|
+
自定义 `page` Hook 会替换默认 host/path Hook,不是合并默认实现。
|
|
212
174
|
|
|
213
175
|
## privacy
|
|
214
176
|
|
|
@@ -216,7 +178,7 @@ tracking: {
|
|
|
216
178
|
| --- | --- | --- | --- |
|
|
217
179
|
| `trackingConsent` | `'granted' \| 'not-granted'` | `granted` | 初始化授权状态 |
|
|
218
180
|
| `redactUrl` | `(url) => string` | 删除 username/password/query/hash | SDK URL 属性脱敏 |
|
|
219
|
-
| `redactAttributes` | `(attributes) => Attributes` | 原样返回 | Resource、SDK 创建的 Span
|
|
181
|
+
| `redactAttributes` | `(attributes) => Attributes` | 原样返回 | Resource、SDK 创建的 Span 和内置插件属性脱敏 |
|
|
220
182
|
|
|
221
183
|
第三方 instrumentation 的自有 Span 属性不保证经过 `redactAttributes`;需要在 `tracking.beforeSend` 做最终兜底。详见[隐私与公共属性](./privacy.md)。
|
|
222
184
|
|
|
@@ -238,11 +200,8 @@ new BkOpenTelemetry({
|
|
|
238
200
|
endpoint: 'https://collector.example.com',
|
|
239
201
|
token: 'token',
|
|
240
202
|
headers: {},
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
metrics: { intervalMillis: 60_000 },
|
|
244
|
-
logs: {},
|
|
245
|
-
},
|
|
203
|
+
processor: 'batch',
|
|
204
|
+
batch: {},
|
|
246
205
|
},
|
|
247
206
|
session: { sampleRate: 1 },
|
|
248
207
|
tracking: {
|
|
@@ -52,9 +52,9 @@ await bkOT.start();
|
|
|
52
52
|
|
|
53
53
|
## 使用 runtime context
|
|
54
54
|
|
|
55
|
-
`init(context)` 中可以访问 `tracer`、`
|
|
55
|
+
`init(context)` 中可以访问 `tracer`、`startSpan()`、`getRuntimeAttributes()` 等能力。
|
|
56
56
|
|
|
57
|
-
优先使用 `context.startSpan()
|
|
57
|
+
优先使用 `context.startSpan()`:它会合并事件发生时的运行时上下文并应用 SDK 脱敏。
|
|
58
58
|
|
|
59
59
|
```ts
|
|
60
60
|
let teardownVisibility = () => {};
|
|
@@ -63,13 +63,12 @@ const visibilityPlugin = createPlugin({
|
|
|
63
63
|
name: 'visibility-change',
|
|
64
64
|
init(context) {
|
|
65
65
|
const onVisibilityChange = () => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
const occurredAt = Date.now();
|
|
67
|
+
context.startSpan('document.visibilitychange', {
|
|
68
|
+
'event.type': 'custom',
|
|
69
|
+
'event.timestamp': occurredAt,
|
|
70
70
|
'document.visibility_state': document.visibilityState,
|
|
71
|
-
|
|
72
|
-
});
|
|
71
|
+
}, { startTime: occurredAt }).end(occurredAt);
|
|
73
72
|
};
|
|
74
73
|
|
|
75
74
|
document.addEventListener('visibilitychange', onVisibilityChange);
|
|
@@ -164,10 +163,8 @@ bkOT.useInstrumentation(new SomeWebInstrumentation());
|
|
|
164
163
|
await bkOT.start();
|
|
165
164
|
```
|
|
166
165
|
|
|
167
|
-
> Extension instrumentation 与采集生命周期一致:未授权或 SDK 停止时不会注册;授权后注册。它产生的 Span 受 Session sampler
|
|
168
|
-
|
|
169
|
-
## 自定义 Metric 注意事项
|
|
166
|
+
> Extension instrumentation 与采集生命周期一致:未授权或 SDK 停止时不会注册;授权后注册。它产生的 Span 受 Session sampler 和导出过滤约束。
|
|
170
167
|
|
|
171
|
-
|
|
168
|
+
## 自定义信号边界
|
|
172
169
|
|
|
173
|
-
|
|
170
|
+
SDK 插件上下文不提供 Meter、Logger 或 `emitLog()`。具体业务行为使用 Span;计数、分布和分位数由服务端从 Span 派生。
|
|
@@ -2,110 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
# 数据模型
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
数据模型遵循“浏览器上报原始事件,服务端派生聚合”的边界。
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 四层字段
|
|
8
8
|
|
|
9
|
-
1. OpenTelemetry
|
|
10
|
-
2. RUM
|
|
11
|
-
3.
|
|
12
|
-
4.
|
|
9
|
+
1. OpenTelemetry Resource/Span 标准字段。
|
|
10
|
+
2. RUM 事件字段:`event.id/type/phase/timestamp`。
|
|
11
|
+
3. 关联上下文:`user.id`、`session.id`、`view.id`、`action.id`。
|
|
12
|
+
4. 单事件语义:`span_type`、`span_subtype`、`result`、`error_type` 和插件原始字段。
|
|
13
13
|
|
|
14
14
|
## Span 类型
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
| --- | --- | --- |
|
|
18
|
-
| `document` | 文档加载 | View 管理器(初始加载) |
|
|
19
|
-
| `resource` | Fetch/XHR 请求与静态资源 | request、resource 采集 |
|
|
20
|
-
| `vital` | Web Vitals | webVitals 插件 |
|
|
21
|
-
| `error` | 浏览器与体验错误 | error 插件、blankScreen 插件、cspViolation 插件 |
|
|
22
|
-
| `longtask` | 长任务 | longTask 插件 |
|
|
23
|
-
| `action` | 用户动作 | action 插件、reportAction |
|
|
24
|
-
| `route` | 路由切换 | View 管理器(SPA/手动 View) |
|
|
25
|
-
| `custom` | 自定义事件 | reportCustomEvent、自定义插件、websocket 插件;`reportCustomEvent({ error })` 仍属于此类型 |
|
|
16
|
+
`document`、`route`、`session`、`resource`、`vital`、`error`、`longtask`、`action`、`websocket`、`custom`。
|
|
26
17
|
|
|
27
|
-
|
|
18
|
+
## 浏览器直接产生
|
|
28
19
|
|
|
29
|
-
|
|
20
|
+
- Session/View/Action 标识和生命周期;
|
|
21
|
+
- URL、HTTP 状态、资源体积与 Resource Timing;
|
|
22
|
+
- Error/CSP 原始字段和标准 exception event;
|
|
23
|
+
- Web Vitals 值与 attribution;
|
|
24
|
+
- WebSocket 连接生命周期;
|
|
25
|
+
- 设备、浏览器、系统和网络上下文。
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
import { RUM_SPAN_TYPE, buildRumSpanAttributes } from '@blueking/open-telemetry';
|
|
27
|
+
## 浏览器本地语义
|
|
33
28
|
|
|
34
|
-
|
|
35
|
-
...buildRumSpanAttributes({
|
|
36
|
-
spanType: RUM_SPAN_TYPE.custom,
|
|
37
|
-
spanSubtype: 'search',
|
|
38
|
-
}),
|
|
39
|
-
'biz.keyword_length': 6,
|
|
40
|
-
});
|
|
29
|
+
CLS、INP、View Loading Time、Action Loading Time、挫败信号和白屏判断依赖 DOM、Performance API 或页面活动窗口,由 SDK 计算后上报。
|
|
41
30
|
|
|
42
|
-
|
|
43
|
-
```
|
|
31
|
+
## 服务端派生
|
|
44
32
|
|
|
45
|
-
|
|
33
|
+
- Session/View duration 和各类 count;
|
|
34
|
+
- 错误率、错误 fingerprint/group;
|
|
35
|
+
- Histogram 与 P50/P75/P95/P99;
|
|
36
|
+
- 影响用户数、地理信息和采样修正;
|
|
37
|
+
- 迟到/乱序关联和 View 版本合并。
|
|
46
38
|
|
|
47
|
-
`
|
|
48
|
-
|
|
49
|
-
- `success`
|
|
50
|
-
- `warning`
|
|
51
|
-
- `error`
|
|
52
|
-
- `timeout`
|
|
53
|
-
- `abort`
|
|
54
|
-
|
|
55
|
-
请求 Resource Span 会根据状态码推导结果:`408`、`504` 为 timeout,`>= 400` 为 error,其余为 success。
|
|
56
|
-
|
|
57
|
-
`reportCustomEvent({ error })` 会设置 `result=error` 和 OpenTelemetry Span Status ERROR,但不会把 `span_type` 从 `custom` 改为 `error`。`span_type` 描述事件类别,`result` 描述结果,两者不要混用。
|
|
58
|
-
|
|
59
|
-
```ts
|
|
60
|
-
bkOT.reportCustomEvent({
|
|
61
|
-
name: 'upload_timeout',
|
|
62
|
-
error: new Error('request timeout'),
|
|
63
|
-
attributes: {
|
|
64
|
-
'biz.file_size': 1024 * 1024,
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## SDK 直接采集
|
|
70
|
-
|
|
71
|
-
以下字段由浏览器 API、接入方配置或 SDK 运行期上下文直接提供:
|
|
72
|
-
|
|
73
|
-
- 应用与环境:`service.name`、`deployment.environment.name`、`service.version`
|
|
74
|
-
- 用户与会话:`user.id`、`session.id`
|
|
75
|
-
- View:`view.id`、`view.name`、`view.url`、`view.url_path_group`、`view.loading_type`
|
|
76
|
-
- 终端信息:`device.type`、`browser.name`、`browser.version`、`os.name`、`network.effective_type`
|
|
77
|
-
- HTTP / Resource:`http.request.method`、`http.response.status_code`、`url.full`、`resource.size`
|
|
78
|
-
- Web Vitals:`vital.metric`、`vital.value`、`vital.rating`
|
|
79
|
-
- Error Span 属性:`exception.message_short`、`exception.stack_top_frame`、`exception.fingerprint`;完整异常位于标准 `exception` Span Event
|
|
80
|
-
|
|
81
|
-
## 后端派生
|
|
82
|
-
|
|
83
|
-
以下字段不在浏览器 SDK 中直接生成:
|
|
84
|
-
|
|
85
|
-
- Session 聚合:`session.duration`、`view_count`、`trace_count`、`error_count`、`action_count`
|
|
86
|
-
- View 聚合:`view.duration`、`request_count`、`resource_count`、`longtask_count`
|
|
87
|
-
- Trace 树:`relative_start`、`hierarchy_level`、`parent_span_name`、`is_critical_path`
|
|
88
|
-
- 影响面:`affected_user_count`
|
|
89
|
-
- 地理信息:`geo.country`、`geo.city`
|
|
90
|
-
|
|
91
|
-
## 高基数字段策略
|
|
92
|
-
|
|
93
|
-
高基数字段可以进入 span/log,但不应进入 metric 维度。比如订单 ID、用户输入、完整 URL query 都应谨慎使用。
|
|
94
|
-
|
|
95
|
-
```ts
|
|
96
|
-
bkOT.reportCustomEvent({
|
|
97
|
-
name: 'order_submit',
|
|
98
|
-
attributes: {
|
|
99
|
-
'biz.order_id': '202605270001',
|
|
100
|
-
'biz.order_type': 'normal',
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
上例中 `biz.order_id` 适合放在 span/log 中定位单次问题,不适合作为 metric 维度做长期聚合。
|
|
106
|
-
|
|
107
|
-
## Metric 与 View 的关联
|
|
108
|
-
|
|
109
|
-
Metric 不携带唯一的 `view.id`、`session.id` 或 `action.id`,只保留 `view.url_path_group`、`view.loading_type` 等低基数维度。这样可以按页面类型聚合,又不会因为每次访问生成新的时序而造成基数爆炸。
|
|
110
|
-
|
|
111
|
-
需要定位某一次 View 时,使用同一指标对应的 span(例如 `browser.web_vital`)或 View Snapshot Log;它们携带精确的 `session.id` 和 `view.id`。后端需要从聚合指标跳转到样本时,应通过 exemplar 或 span/log 派生聚合建立关联,而不是把 `view.id` 放进 metric labels。
|
|
39
|
+
服务端应使用 `event.id` 去重,使用 `view.id + view.version` 幂等处理 View 更新。
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# 简介
|
|
4
4
|
|
|
5
|
-
`@blueking/open-telemetry` 是面向浏览器真实用户监控(RUM)的 OpenTelemetry 封装 SDK
|
|
5
|
+
`@blueking/open-telemetry` 是面向浏览器真实用户监控(RUM)的 OpenTelemetry 封装 SDK。它将页面访问、资源加载、接口请求、JavaScript 错误、Web Vitals、空白屏、会话和用户动作等浏览器事件统一转成原始 RUM Span,通过单一 OTLP HTTP 通道上报。
|
|
6
6
|
|
|
7
7
|
## 适合解决什么问题
|
|
8
8
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
## session
|
|
10
10
|
|
|
11
|
-
`session` 维护 `session.id
|
|
11
|
+
`session` 维护 `session.id`,并在会话开始、轮换和结束时写入 `browser.session` 生命周期 Span。它是所有 RUM 事件的关联边界,获得 Consent 后始终开启,不能关闭;是否导出由 Session 采样决定。
|
|
12
12
|
|
|
13
13
|
默认规则:
|
|
14
14
|
|
|
@@ -26,9 +26,9 @@ new BkOpenTelemetry({
|
|
|
26
26
|
});
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
超时固定为 15 分钟无活动、4 小时最长生命周期,不开放配置。过期会结束当前 View、刷新旧
|
|
29
|
+
超时固定为 15 分钟无活动、4 小时最长生命周期,不开放配置。过期会结束当前 View、刷新旧 Session 的待发送数据,并丢弃此后所有不带有效 `session.id` 的 Span;下一次用户交互续期时,同时创建新的 Session 和 View。
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
**产出遥测**:`browser.session` start/rotate/end Span,并维护 `session.id`、`session.start_time`、`session.type`。
|
|
32
32
|
|
|
33
33
|
## device
|
|
34
34
|
|
|
@@ -45,11 +45,11 @@ new BkOpenTelemetry({
|
|
|
45
45
|
});
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
稳定的浏览器、系统和硬件能力写入 Resource;设备 ID、视口和网络信息保留为运行时属性,后续 Span 会自动携带。
|
|
49
49
|
|
|
50
50
|
`device.id` 默认只在当前 SDK 实例内稳定;只有显式设置 `persistentId: true` 才写入 localStorage,并按应用名隔离默认 storage key。
|
|
51
51
|
|
|
52
|
-
**产出遥测**:写入 Resource 属性(如 `browser.name`、`os.name`、`device.type`、`device.memory_gib`)和运行时属性(如 `device.id`、`browser.viewport.*`、`network.effective_type`),本身不单独产生
|
|
52
|
+
**产出遥测**:写入 Resource 属性(如 `browser.name`、`os.name`、`device.type`、`device.memory_gib`)和运行时属性(如 `device.id`、`browser.viewport.*`、`network.effective_type`),本身不单独产生 Span。
|
|
53
53
|
|
|
54
54
|
## View
|
|
55
55
|
|
|
@@ -97,11 +97,11 @@ bkOT.startView({
|
|
|
97
97
|
bkOT.setViewName('订单详情-只读');
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
`view.id` 始终由 SDK 生成,`attributes` 不能覆盖 Session/View 等保留字段。普通
|
|
100
|
+
`view.id` 始终由 SDK 生成,`attributes` 不能覆盖 Session/View 等保留字段。普通 Span 必须同时带有 `session.id` 和 `view.id` 才会进入导出链路。手动模式在首次 `startView()` 前不会导出普通 RUM 数据。
|
|
101
101
|
|
|
102
102
|
View Loading Time 默认开启:初始加载取 `loadEventEnd` 与页面活动结束时间的较大值,SPA 路由取 View 创建到页面活动结束的耗时。请求、静态资源和 DOM 变更都属于页面活动,连续 100ms 无活动视为稳定。长轮询或埋点请求应配置到 `view.excludedActivityUrls`;业务也可在真正渲染完成时调用 `setViewLoadingTime()` 覆盖自动结果。
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
**产出遥测**:`browser.view` start/update/end 原始生命周期 Span。每次事件携带 `view.version`,Loading Time 就绪或 View 名称变化时产生 update。
|
|
105
105
|
|
|
106
106
|
## action
|
|
107
107
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
插件会生成 error span,并使用 fingerprint 做窗口内节流,避免相同错误在短时间内刷屏。
|
|
18
18
|
|
|
19
|
-
**产出遥测**:span `browser.error`(JS 错误)、`browser.unhandledrejection`(Promise 异常)、`browser.resource_error`(资源加载失败),均为 `span_type=error
|
|
19
|
+
**产出遥测**:span `browser.error`(JS 错误)、`browser.unhandledrejection`(Promise 异常)、`browser.resource_error`(资源加载失败),均为 `span_type=error`,带原始 `error.message`、`error.source` 和标准 exception event。SDK 不做错误指纹、计数或节流。
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
22
|
new BkOpenTelemetry({
|
|
@@ -42,9 +42,9 @@ new BkOpenTelemetry({
|
|
|
42
42
|
|
|
43
43
|
## webVitals
|
|
44
44
|
|
|
45
|
-
`webVitals` 插件默认开启,采集 CLS、FCP、INP、LCP、TTFB。FCP/LCP/TTFB 按指标发生时刻归属 View,CLS 使用每个 View 独立的 1 秒间隔/5 秒窗口,INP 使用候选交互的近似 p98
|
|
45
|
+
`webVitals` 插件默认开启,采集 CLS、FCP、INP、LCP、TTFB。FCP/LCP/TTFB 按指标发生时刻归属 View,CLS 使用每个 View 独立的 1 秒间隔/5 秒窗口,INP 使用候选交互的近似 p98,而不是简单最大值。它只产生带 `session.id`、`view.id` 和 attribution 的原始 Span,聚合由服务端完成。
|
|
46
46
|
|
|
47
|
-
**产出遥测**:
|
|
47
|
+
**产出遥测**:span `browser.web_vital`(`span_type=vital`,含 attribution 归因)。
|
|
48
48
|
|
|
49
49
|
```ts
|
|
50
50
|
new BkOpenTelemetry({
|
|
@@ -74,7 +74,7 @@ new BkOpenTelemetry({
|
|
|
74
74
|
|
|
75
75
|
SPA 应用建议配置 `rootSelector`。根节点在确认阶段仍不存在时会以 `missing_root` 原因上报;loading 和骨架屏样本不进入空白比例分母。
|
|
76
76
|
|
|
77
|
-
**产出遥测**(仅判定为白屏时):
|
|
77
|
+
**产出遥测**(仅判定为白屏时):error span `browser.blank_screen`(`span_type=error`)。
|
|
78
78
|
|
|
79
79
|
## longTask
|
|
80
80
|
|
|
@@ -85,7 +85,6 @@ new BkOpenTelemetry({
|
|
|
85
85
|
tracking: {
|
|
86
86
|
longTask: {
|
|
87
87
|
threshold: 50,
|
|
88
|
-
warningThreshold: 100,
|
|
89
88
|
},
|
|
90
89
|
},
|
|
91
90
|
});
|
|
@@ -93,7 +92,7 @@ new BkOpenTelemetry({
|
|
|
93
92
|
|
|
94
93
|
LoAF 会补充 blocking duration、render/style/layout 阶段、最重脚本归因,并把每个脚本作为 `long_task.script` Span Event。初始化阶段的 buffered entries 延迟到后续宏任务批量处理,避免 SDK 启动自身制造阻塞。不支持 LoAF 和 Long Tasks API 的浏览器会跳过插件。
|
|
95
94
|
|
|
96
|
-
**产出遥测**:
|
|
95
|
+
**产出遥测**:span `browser.long_task`(`span_type=longtask`),计数与耗时分布由服务端派生。
|
|
97
96
|
|
|
98
97
|
## View Loading Time
|
|
99
98
|
|