@blueking/open-telemetry 0.0.31 → 0.0.32
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 +61 -24
- package/dist/bk-rum.global.js +1 -1
- package/dist/bk-rum.global.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/bk-rum-otele/references/actions.md +15 -9
- package/skills/bk-rum-otele/references/api.md +5 -2
- package/skills/bk-rum-otele/references/architecture.md +2 -2
- package/skills/bk-rum-otele/references/blank-screen.md +8 -17
- package/skills/bk-rum-otele/references/capabilities.md +2 -2
- package/skills/bk-rum-otele/references/configuration.md +4 -4
- package/skills/bk-rum-otele/references/data-model.md +11 -13
- package/skills/bk-rum-otele/references/errors-security.md +5 -4
- package/skills/bk-rum-otele/references/extensions.md +8 -0
- package/skills/bk-rum-otele/references/framework-integration.md +1 -1
- package/skills/bk-rum-otele/references/getting-started.md +19 -1
- package/skills/bk-rum-otele/references/network.md +17 -18
- package/skills/bk-rum-otele/references/performance.md +12 -23
- package/skills/bk-rum-otele/references/privacy.md +1 -1
- package/skills/bk-rum-otele/references/session-context.md +13 -9
- package/skills/bk-rum-otele/references/span-protocol.md +23 -22
- package/skills/bk-rum-otele/references/telemetry-reference.md +68 -73
- package/skills/bk-rum-otele/references/transport-sampling.md +18 -13
- package/skills/bk-rum-otele/references/troubleshooting.md +1 -1
- package/skills/bk-rum-otele/references/views-routing.md +1 -0
package/package.json
CHANGED
|
@@ -6,9 +6,11 @@ Action 表示一次用户操作以及操作后引发的页面活动。SDK 默认
|
|
|
6
6
|
|
|
7
7
|
## 自动 Action 生命周期
|
|
8
8
|
|
|
9
|
+
插件在 `window` 上以 capture + passive 监听 `click`,**只处理主键点击**(`event.button === 0`)。右键、中键和辅助键点击不创建 Action。
|
|
10
|
+
|
|
9
11
|
一次 click 的处理过程:
|
|
10
12
|
|
|
11
|
-
1. 从 Event 取得真实发生时间和 composed target
|
|
13
|
+
1. 从 Event 取得真实发生时间和 composed target(`composedPath()[0]`,因此能穿透 Shadow DOM 拿到真实内部元素)。
|
|
12
14
|
2. 生成 `action.id`,保存当时的 Session/View 上下文。
|
|
13
15
|
3. 把当前活动的 `action.id` 字符串写入运行时上下文,后续请求、资源、错误和 Long Task 自动关联。多个点击窗口重叠时取最近一次。
|
|
14
16
|
4. 观察请求、DOM Mutation、Resource、Long Task、Error 和部分用户行为。
|
|
@@ -33,7 +35,7 @@ Action 表示一次用户操作以及操作后引发的页面活动。SDK 默认
|
|
|
33
35
|
|
|
34
36
|
Error 会把 Action 标记为发生过活动、更新结束时间并标记 `error_click`;Long Task 也只影响 Action Activity。View Loading Time 的稳定判断会忽略 Error 和 Long Task。`view.excludedActivityUrls` 命中的请求/资源不参与 Action 活动。
|
|
35
37
|
|
|
36
|
-
点击后 100ms 内没有任何页面活动时,Action
|
|
38
|
+
点击后 100ms 内没有任何页面活动时,Action 以零持续时间结束(Span 起止时间相同);它仍可能被识别为 Dead Click。持续时间用 OTLP 起止时间表达,不写 `action.loading_time` Attribute。
|
|
37
39
|
|
|
38
40
|
## 自动命名
|
|
39
41
|
|
|
@@ -116,12 +118,12 @@ Action 活动窗口内发生由 Activity Bus 通知的前端错误时,标记 `
|
|
|
116
118
|
|
|
117
119
|
- `action.id`
|
|
118
120
|
- `action.type=click`
|
|
119
|
-
- `action.name`
|
|
120
121
|
- `action.target.name`
|
|
121
122
|
- `action.target.tag`
|
|
122
|
-
- `action.loading_time`,只有观察到页面活动时存在,单位 ms
|
|
123
123
|
- `action.frustration.type`,按 `rage_click`、`dead_click`、`error_click` 固定顺序的数组
|
|
124
124
|
|
|
125
|
+
有页面活动时,持续时间体现在 Span 起止时间上,不写 `action.name` 或 `action.loading_time` Attribute。完整字段见[遥测字段字典](./telemetry-reference.md#action-字段)。
|
|
126
|
+
|
|
125
127
|
SDK 不在 Action Span 中写请求数、资源数、错误数或 Long Task 数;服务端通过 `action.id` 关联原始事件后派生。
|
|
126
128
|
|
|
127
129
|
## 手动 Action
|
|
@@ -135,11 +137,11 @@ bkOT.reportAction({
|
|
|
135
137
|
});
|
|
136
138
|
```
|
|
137
139
|
|
|
138
|
-
它立即创建并结束 `action
|
|
140
|
+
它立即创建并结束 Span `action.立即支付`(即 `action.<name>`):
|
|
139
141
|
|
|
140
142
|
- 新生成独立 `action.id`;
|
|
141
143
|
- `action.type=custom`;
|
|
142
|
-
- `action
|
|
144
|
+
- Span 名为 `action.<传入 name>`;
|
|
143
145
|
- `span_type=action`、`outcome.type=success`;
|
|
144
146
|
- 不建立活动窗口;
|
|
145
147
|
- 不计算 Loading Time 或挫败信号;
|
|
@@ -155,11 +157,15 @@ bkOT.reportAction({
|
|
|
155
157
|
|
|
156
158
|
### Action 名称只有标签名
|
|
157
159
|
|
|
158
|
-
这是默认隐私行为。为元素或祖先添加 `data-bk-action-name`,或显式配置其他 `actionNameAttribute
|
|
160
|
+
这是默认隐私行为。为元素或祖先添加 `data-bk-action-name`,或显式配置其他 `actionNameAttribute`。向上查找会跨越 Shadow DOM 边界(`parentElement` 为空时改用 `ShadowRoot.host`),因此 Web Component 内部元素也能继承宿主上的 data 属性。
|
|
161
|
+
|
|
162
|
+
### 右键或中键点击没有 Action
|
|
163
|
+
|
|
164
|
+
预期行为,只有 `event.button === 0` 的主键点击会创建 Action。需要记录其他交互时用 `reportAction()`。
|
|
159
165
|
|
|
160
|
-
###
|
|
166
|
+
### 点击有请求但 Span 持续时间为 0
|
|
161
167
|
|
|
162
|
-
检查请求是否命中 `view.excludedActivityUrls`,click 是否在请求开始前被其他监听逻辑延迟,以及 Action 是否在未采样/无 View
|
|
168
|
+
检查请求是否命中 `view.excludedActivityUrls`,click 是否在请求开始前被其他监听逻辑延迟,以及 Action 是否在未采样/无 View 状态发生。持续时间看 Span 起止时间,不要查 `action.loading_time` Attribute。
|
|
163
169
|
|
|
164
170
|
### Dead Click 过多
|
|
165
171
|
|
|
@@ -30,6 +30,8 @@ CDN bundle 的默认导出会挂到:
|
|
|
30
30
|
window.BkOpenTelemetry
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
它只提供这个构造函数,不挂载 ESM 入口里的插件工厂、schema 常量或 TypeScript 类型。
|
|
34
|
+
|
|
33
35
|
## 生命周期 API
|
|
34
36
|
|
|
35
37
|
### `start(): Promise<void>`
|
|
@@ -178,7 +180,7 @@ interface BkOTActionEventPayload {
|
|
|
178
180
|
}
|
|
179
181
|
```
|
|
180
182
|
|
|
181
|
-
立即创建并结束 `action
|
|
183
|
+
立即创建并结束 Span,名为 `action.<name>`(例如 `reportAction({ name: '立即购买' })` 得到 `action.立即购买`),写入新的 `action.id`、`action.type=custom`、`span_type=action` 和 `outcome.type=success`。它不是持续的自动 Action 窗口,不会等待或关联调用之后的请求。不要把它理解成固定 Span 名 `action.custom`。
|
|
182
184
|
|
|
183
185
|
未命中 Session 采样时静默丢弃。
|
|
184
186
|
|
|
@@ -282,6 +284,7 @@ span.end(endedAt);
|
|
|
282
284
|
| `startTime` | OTel `TimeInput`;浏览器场景常用 epoch milliseconds |
|
|
283
285
|
| `contextTime` | 用哪个 epoch ms 回查 Session/View/Action;缺省时复用数字型 `startTime` |
|
|
284
286
|
| `kind` | SpanKind,默认 `INTERNAL` |
|
|
287
|
+
| `links` | `Link[]`,关联其他 Trace。OpenTelemetry 只允许在创建时传入,Span 结束前无法追加;内置请求插件用它把后端 Trace 关联回 `browser.resource` |
|
|
285
288
|
|
|
286
289
|
运行时属性先合并,显式 `attributes` 后合并,因此显式同名字段优先;整体再经过 `redactAttributes`。未采样时返回 OTel non-recording Span,调用方仍可安全 `end()`。
|
|
287
290
|
|
|
@@ -325,7 +328,7 @@ import { resolveConfig } from '@blueking/open-telemetry';
|
|
|
325
328
|
| `RUM_ATTRIBUTES` | SDK 公共字段 key 常量表 |
|
|
326
329
|
| `RUM_SPAN_TYPE` | RUM Span 大类常量表 |
|
|
327
330
|
| `RUM_SPAN_OUTCOME` | success/warning/error/timeout/abort 常量表 |
|
|
328
|
-
| `buildRumSpanAttributes` | 根据 spanType/outcome
|
|
331
|
+
| `buildRumSpanAttributes` | 根据 spanType/outcome 生成 `span_type` 与 `outcome.type`;当前不写 `outcome.reason` |
|
|
329
332
|
|
|
330
333
|
内置插件工厂适合 SDK 定制或组合插件。普通接入使用 `tracking` 开关即可;不要把同一个内置工厂再放进 `extensions.plugins`,否则可能重复监听和上报。
|
|
331
334
|
|
|
@@ -44,7 +44,7 @@ SDK 只创建 OpenTelemetry Trace Provider。Session、View、请求、资源、
|
|
|
44
44
|
|
|
45
45
|
1. `resolveConfig()` 校验 `application.name` 和 `transport.endpoint`。
|
|
46
46
|
2. 解析应用、传输、采样、Hook 和默认配置。
|
|
47
|
-
3. 创建 OpenTelemetry Resource;默认 Device 开启时会在此同步读取 UA
|
|
47
|
+
3. 创建 OpenTelemetry Resource;默认 Device 开启时会在此同步读取 UA / UA-CH(浏览器名与版本、OS、`mobile` 标记)快照,这一步早于 Consent 插件生命周期。
|
|
48
48
|
4. 创建 `OTLPTraceExporter`,目标固定为 `<endpoint>/v1/rum`。
|
|
49
49
|
5. 按 `transport.processor` 创建 `BatchSpanProcessor` 或 `SimpleSpanProcessor`。
|
|
50
50
|
6. 在外层包裹 `FilteringSpanProcessor`。
|
|
@@ -107,7 +107,7 @@ SDK 只创建 OpenTelemetry Trace Provider。Session、View、请求、资源、
|
|
|
107
107
|
`RumRuntimeContext` 保存后续 Span 自动继承的属性:
|
|
108
108
|
|
|
109
109
|
- `user.id`
|
|
110
|
-
- `session.id`、`session.
|
|
110
|
+
- `session.id`、`session.type`、`session.has_replay`
|
|
111
111
|
- `view.id`、`view.url`、`view.url_template`、`view.loading_type`,以及显式命名后才出现的 `view.name`
|
|
112
112
|
- 活动窗口内的 `action.id`
|
|
113
113
|
- Device 插件产生的视口、屏幕、网络和设备 ID
|
|
@@ -118,11 +118,10 @@ tracking: {
|
|
|
118
118
|
- `body` 中存在足够的可见内容时不报告白屏;
|
|
119
119
|
- 只有回退采样的空白比例仍达到阈值,才进入二次确认;
|
|
120
120
|
- `blank_screen.reason=missing_root`
|
|
121
|
-
- `
|
|
122
|
-
-
|
|
123
|
-
- 二次确认仍为空白才上报。
|
|
121
|
+
- empty ratio 和 `empty_sample_count` 来自回退后的实际检测结果,不是固定 `1`
|
|
122
|
+
- 二次确认仍为空白才上报
|
|
124
123
|
|
|
125
|
-
根节点缺失本身不再作为白屏证据,避免 Vue 等框架替换初始挂载容器后,在 SPA View 切换时持续误报。`missing_root` 表示配置根节点缺失且回退后的视口也符合白屏条件;排障时仍应检查 selector
|
|
124
|
+
根节点缺失本身不再作为白屏证据,避免 Vue 等框架替换初始挂载容器后,在 SPA View 切换时持续误报。`missing_root` 表示配置根节点缺失且回退后的视口也符合白屏条件;排障时仍应检查 selector 是否稳定。当前 Span **不写** `root_found`、`root_selector`、`center_element` 或各类 sample_count 分项(除 `empty_sample_count`)。
|
|
126
125
|
|
|
127
126
|
## 上报字段
|
|
128
127
|
|
|
@@ -131,22 +130,15 @@ tracking: {
|
|
|
131
130
|
| 字段 | 说明 |
|
|
132
131
|
| --- | --- |
|
|
133
132
|
| `blank_screen.reason` | `missing_root` / `empty_viewport` |
|
|
134
|
-
| `blank_screen.empty_ratio` |
|
|
135
|
-
| `blank_screen.sample_count` | 固定 9 |
|
|
136
|
-
| `blank_screen.valid_sample_count` | 9 - ignored |
|
|
133
|
+
| `blank_screen.empty_ratio` | 空白有效点比例,即 `emptyCount / validCount` |
|
|
137
134
|
| `blank_screen.empty_sample_count` | 空白点数 |
|
|
138
|
-
| `blank_screen.ignored_sample_count` | Loading/Skeleton 点数 |
|
|
139
|
-
| `blank_screen.root_selector` | 当前配置 |
|
|
140
|
-
| `blank_screen.root_found` | 根节点是否存在 |
|
|
141
|
-
| `blank_screen.center_element` | 中心点最上层元素的 `tag` 或 `tag#id` |
|
|
142
135
|
|
|
143
136
|
分类固定:
|
|
144
137
|
|
|
145
138
|
- `span_type=error`
|
|
146
139
|
- `outcome.type=error`
|
|
147
|
-
- `outcome.reason=blank_screen`
|
|
148
140
|
|
|
149
|
-
|
|
141
|
+
不写 `outcome.reason`,不设置 OpenTelemetry Status ERROR,也不记录 exception Event。完整字段见[遥测字段字典](./telemetry-reference.md#白屏字段)。
|
|
150
142
|
|
|
151
143
|
## 每个 View 最多一次
|
|
152
144
|
|
|
@@ -181,10 +173,9 @@ new BkOpenTelemetry({
|
|
|
181
173
|
|
|
182
174
|
1. `reason` 是否为 `missing_root`。
|
|
183
175
|
2. `rootSelector` 是否指向真正承载内容的稳定节点。
|
|
184
|
-
3. `
|
|
176
|
+
3. `empty_ratio` 是否只是略高于阈值。
|
|
185
177
|
4. 页面是否用 Canvas、iframe 或背景图承载主要内容。
|
|
186
|
-
5. `
|
|
187
|
-
6.
|
|
188
|
-
7. View Loading Activity 是否没有覆盖业务的异步过程。
|
|
178
|
+
5. 异步渲染是否晚于 `checkDelay + confirmationDelay`。
|
|
179
|
+
6. View Loading Activity 是否没有覆盖业务的异步过程。
|
|
189
180
|
|
|
190
181
|
完整字段见[遥测字段字典](./telemetry-reference.md#白屏字段)。
|
|
@@ -31,7 +31,7 @@ SDK 只产生原始 RUM Span:
|
|
|
31
31
|
| 资源加载错误 | `tracking.error` | 开 | capture error | `browser.resource_error` | [错误与安全](./errors-security.md) |
|
|
32
32
|
| Web Vitals | `tracking.webVitals` | 开 | web-vitals、PerformanceObserver | `browser.web_vital` | [性能体验](./performance.md) |
|
|
33
33
|
| 自动 Action | `tracking.action` | 开 | click、Activity 总线 | `action.click` | [用户操作](./actions.md) |
|
|
34
|
-
| 手动 Action | `reportAction()` | 可调用 | 业务调用 | `action.custom
|
|
34
|
+
| 手动 Action | `reportAction()` | 可调用 | 业务调用 | `action.<name>`(`action.type=custom`) | [用户操作](./actions.md) |
|
|
35
35
|
| Custom event | `reportCustomEvent()` | 可调用 | 业务调用 | `custom.<name>` | [API](./api.md) |
|
|
36
36
|
| Blank Screen | `tracking.blankScreen` | 开 | DOM 九点采样、页面活动 | `browser.blank_screen` | [白屏](./blank-screen.md) |
|
|
37
37
|
| Device | `tracking.device` | 开 | UA/UA-CH、Screen、Network Information | Resource/运行时属性 | [Session 上下文](./session-context.md) |
|
|
@@ -122,7 +122,7 @@ SDK 不做错误节流、fingerprint 和分组。CSP 插件每次 violation 建
|
|
|
122
122
|
|
|
123
123
|
## Web Vitals 与 Long Task
|
|
124
124
|
|
|
125
|
-
Vitals:CLS、FCP、INP、LCP、TTFB
|
|
125
|
+
Vitals:CLS、FCP、INP、LCP、TTFB。每条 Span 带 `vital.metric`、`vital.value`、`vital.id`;内部 rating 只映射为 `outcome.type`。CLS/INP 按当前 View 聚合定稿。LCP/TTFB 带部分 attribution,FCP/CLS 当前没有独立归因字段。详见[性能体验](./performance.md)。
|
|
126
126
|
|
|
127
127
|
Long Task 优先 Long Animation Frame 获取脚本归因,不支持时回退 Long Tasks。默认关闭,threshold 默认 50ms。
|
|
128
128
|
|
|
@@ -65,10 +65,10 @@ new BkOpenTelemetry({
|
|
|
65
65
|
| `headers` | `Record<string, string>` | 无 | 自定义头;同名时覆盖 token 生成的头 |
|
|
66
66
|
| `processor` | `'batch' \| 'simple'` | `'batch'` | 批量或逐 Span 导出 |
|
|
67
67
|
| `batch` | `BkOTBatchConfig` | OTel 默认值 | 仅 batch 模式生效 |
|
|
68
|
-
| `timeoutMillis` | `number` |
|
|
69
|
-
| `concurrencyLimit` | `number` |
|
|
68
|
+
| `timeoutMillis` | `number` | 未配置时沿用 OTel exporter | exporter 请求及重试的总期限,必须大于 0。当前锁定的 `@opentelemetry/exporter-trace-otlp-http` 默认约为 `10000` |
|
|
69
|
+
| `concurrencyLimit` | `number` | 未配置时沿用 OTel exporter | exporter 并发 Promise 上限。当前锁定依赖默认约为 `30` |
|
|
70
70
|
|
|
71
|
-
`batch`
|
|
71
|
+
`batch` 子项由 SDK 原样传给 `BatchSpanProcessor`,本包不硬编码。未配置时沿用锁定的 `@opentelemetry/sdk-trace-base` 默认值(当前常见为):
|
|
72
72
|
|
|
73
73
|
| 配置 | 默认 | 说明 |
|
|
74
74
|
| --- | ---: | --- |
|
|
@@ -214,7 +214,7 @@ SPA 应将 `rootSelector` 指向真实挂载节点。详见[白屏检测](./blan
|
|
|
214
214
|
| `persistentId` | `boolean` | `false` | 是否把匿名设备 ID 持久化到 localStorage |
|
|
215
215
|
| `storageKey` | `string` | `BK_RUM_DEVICE_ID_<应用 hash>` | 持久设备 ID 的 key |
|
|
216
216
|
|
|
217
|
-
`persistentId: false` 时,每次 Device 插件初始化都会创建新的设备 ID,只在当前采集周期内稳定;撤销再授予 Consent 会重新初始化插件并换 ID。`tracking.device: false`
|
|
217
|
+
`persistentId: false` 时,每次 Device 插件初始化都会创建新的设备 ID,只在当前采集周期内稳定;撤销再授予 Consent 会重新初始化插件并换 ID。`tracking.device: false` 还会阻止 `user_agent.*` 与 `device.type` 这四个 Resource 属性生成。详见[Session、用户与设备上下文](./session-context.md)。
|
|
218
218
|
|
|
219
219
|
## longTask
|
|
220
220
|
|
|
@@ -30,7 +30,7 @@ resourceSpans[]
|
|
|
30
30
|
| Resource | `service.name`、`telemetry.sdk.version`、`session.sample_rate` | SDK 实例固定 | 配置解析和 Device Resource |
|
|
31
31
|
| OpenTelemetry Span | `traceId`、`spanId`、`kind`、开始/结束时间、Status | 单个 Span | OpenTelemetry Provider |
|
|
32
32
|
| RUM 运行时上下文 | `session.id`、`view.id`、`action.id`、`user.id` | 随运行时变化 | `RumRuntimeContext` |
|
|
33
|
-
| RUM 分类与结果 | `span_type`、`outcome.type
|
|
33
|
+
| RUM 分类与结果 | `span_type`、`outcome.type` | 单个原始 Span | 内置插件或手动 API |
|
|
34
34
|
| 领域字段 | `resource.*`、`vital.*`、`error.*`、`blank_screen.*` | 单项能力决定 | 对应插件 |
|
|
35
35
|
|
|
36
36
|
服务端派生字段不属于以上五层,不应伪装成浏览器原始字段。
|
|
@@ -45,11 +45,11 @@ Resource 在构造时创建,同一 SDK 实例的全部 Span 共用。基础字
|
|
|
45
45
|
| `service.version` | `application.version`,未配置时不存在 |
|
|
46
46
|
| `deployment.environment.name` | `application.environment`,默认 `production` |
|
|
47
47
|
| `session.sample_rate` | 解析后的 `session.sampleRate` |
|
|
48
|
-
| `telemetry.sdk.name` | 固定
|
|
48
|
+
| `telemetry.sdk.name` | 固定 `blueking` |
|
|
49
49
|
| `telemetry.sdk.language` | 固定 `webjs` |
|
|
50
50
|
| `telemetry.sdk.version` | 当前 npm 包版本 |
|
|
51
51
|
|
|
52
|
-
默认开启 Device
|
|
52
|
+
默认开启 Device 时,还会写入 `user_agent.name`、`user_agent.version`、`user_agent.os.name` 和 `device.type` 四个字段,全部来自 UA / UA-CH 解析。SDK 不读取设备内存或逻辑处理器数。Resource 会在构造时经过一次 `privacy.redactAttributes`,之后不会随运行时状态更新。
|
|
53
53
|
|
|
54
54
|
## 关联模型
|
|
55
55
|
|
|
@@ -106,19 +106,17 @@ View 每次发出 start/update/end 都会递增 `view.version`。服务端应以
|
|
|
106
106
|
| ---------------- | --------------------------------------------------------------------------------------------------- |
|
|
107
107
|
| `span_type` | 大类:`session`、`view`、`resource`、`vital`、`error`、`long_task`、`action`、`websocket`、`custom` |
|
|
108
108
|
| `outcome.type` | `success`、`warning`、`error`、`timeout`、`abort` |
|
|
109
|
-
| `outcome.reason` | 可选结果原因,例如 `network`、`network_timeout`、`http_4xx`、`http_5xx` |
|
|
110
109
|
|
|
111
|
-
`span_type` 表示 Span 类别,`outcome.type` 表示结果,两者不要混用。例如带异常的 `custom.checkout` 仍是 `span_type=custom`,但 `outcome.type=error` 且 Span Status 为 ERROR。具体子类由 `resource.type`、`vital.metric`、`error.source`
|
|
110
|
+
`span_type` 表示 Span 类别,`outcome.type` 表示结果,两者不要混用。例如带异常的 `custom.checkout` 仍是 `span_type=custom`,但 `outcome.type=error` 且 Span Status 为 ERROR。具体子类由 `resource.type`、`vital.metric`、`error.source`、`blank_screen.reason` 等领域字段表达。当前 SDK **不写** `outcome.reason`。
|
|
112
111
|
|
|
113
|
-
HTTP
|
|
112
|
+
HTTP 结果只映射 `outcome.type`:
|
|
114
113
|
|
|
115
|
-
- `408`、`504` → `
|
|
116
|
-
- 其他 `4xx` → `
|
|
117
|
-
- `
|
|
118
|
-
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
- 其他状态 → `outcome.type=success`,不写 reason
|
|
114
|
+
- `408`、`504` 以及 Fetch TimeoutError / XHR `timeout` → `timeout`
|
|
115
|
+
- 其他 `4xx` / `5xx`、Fetch 网络异常、XHR `error` → `error`
|
|
116
|
+
- Fetch AbortError 或 XHR `abort` → `abort`
|
|
117
|
+
- 其他状态 → `success`
|
|
118
|
+
|
|
119
|
+
状态码和失败细节见 [遥测字段字典 · 请求与静态资源](./telemetry-reference.md#请求与静态资源字段)。
|
|
122
120
|
|
|
123
121
|
## Span Kind 与 Status
|
|
124
122
|
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
- `code.lineno`
|
|
27
27
|
- `code.column`
|
|
28
28
|
|
|
29
|
-
跨域脚本只暴露 `Script error
|
|
29
|
+
跨域脚本只暴露 `Script error.`,且 `code.filepath` 为空、没有 exception stack。SDK 不为这种情况写额外标记字段(没有 `error.cross_origin`),排查时按 `error.message === 'Script error.'` 识别。要获得完整错误和 Stack,脚本资源需要正确配置 CORS,并使用合适的 `crossorigin` 属性。
|
|
30
30
|
|
|
31
31
|
## 未处理 Promise Rejection
|
|
32
32
|
|
|
@@ -45,7 +45,9 @@ Reason 是 Error 时保留其名称;其他对象尝试 JSON stringify,失败
|
|
|
45
45
|
- `outcome.type=error`
|
|
46
46
|
- `error.source=resource`
|
|
47
47
|
- `url.full`:从 `src`、`href` 或 `currentSrc` 读取并脱敏
|
|
48
|
-
- `
|
|
48
|
+
- `error.message`:固定格式 `Resource load failed: <小写标签名> <原始 URL>`
|
|
49
|
+
|
|
50
|
+
失败元素的标签名只出现在 `error.message` 中,没有独立的 `html.tag` 字段。注意该 message 里的 URL 是**未脱敏**的原始值,只有 `url.full` 经过 `redactUrl`;URL 可能含敏感信息时应用 `redactAttributes` 重写 `error.message`。
|
|
49
51
|
|
|
50
52
|
该事件与 Performance Resource Span 不同:它表示浏览器资源元素加载失败,可能没有 HTTP Status 或 Resource Timing。
|
|
51
53
|
|
|
@@ -55,7 +57,7 @@ Reason 是 Error 时保留其名称;其他对象尝试 JSON stringify,失败
|
|
|
55
57
|
|
|
56
58
|
| Event 字段 | 说明 |
|
|
57
59
|
| --- | --- |
|
|
58
|
-
| `exception.type` | Error name
|
|
60
|
+
| `exception.type` | Error 的 `name`;非 Error 值时为 `window.error`、`UnhandledRejection` 或 `ResourceError` |
|
|
59
61
|
| `exception.message` | 完整消息 |
|
|
60
62
|
| `exception.stacktrace` | Error 存在 Stack 时 |
|
|
61
63
|
|
|
@@ -119,7 +121,6 @@ tracking: {
|
|
|
119
121
|
插件监听 `document.securitypolicyviolation`,每个浏览器事件创建 `csp.violation` Error Span:
|
|
120
122
|
|
|
121
123
|
- `outcome.type=error`
|
|
122
|
-
- `outcome.reason=csp`
|
|
123
124
|
- `error.source=csp`
|
|
124
125
|
- `csp.blocked_uri`
|
|
125
126
|
- `csp.violated_directive`
|
|
@@ -87,6 +87,10 @@ await bkOT.start();
|
|
|
87
87
|
| `applyRedact()` | 执行属性脱敏 |
|
|
88
88
|
| `flush()` | 请求 SDK 刷新 |
|
|
89
89
|
| `registerInstrumentations()` | 插件内注册额外 Instrumentation |
|
|
90
|
+
| `setUser()` | 更新 `user.id` |
|
|
91
|
+
| `setView()` / `onViewCommand()` | 直接操作 View 上下文与命令流,仅供替换内置 View 插件的场景 |
|
|
92
|
+
|
|
93
|
+
`setView()`、`onViewCommand()`、`onViewChange()`、`notifyActivity()` 和 `onActivity()` 只存在于 Plugin Context,**不在** `BkOTInstance` 公开接口上;业务代码应使用 `startView()` / `setViewName()`。
|
|
90
94
|
|
|
91
95
|
## 创建正确的自定义 Span
|
|
92
96
|
|
|
@@ -210,6 +214,10 @@ SDK 对每个 Instrumentation:
|
|
|
210
214
|
|
|
211
215
|
Instrumentation 创建的 Span 由 `FilteringSpanProcessor.onStart()` 补充缺失的 RUM 上下文。它显式设置的同名属性优先,不会被 Processor 覆盖。
|
|
212
216
|
|
|
217
|
+
Instrumentation 不需要自己判断采样:Provider 上的 `RumSessionSampler` 在 Session 未采样时让所有 Span 变成 non-recording。但导出条件仍然适用——Instrumentation Span 必须在创建时就处于有效 Session + View 上下文中,否则会在 `onEnd` 被过滤掉。因此在 `start()` 之前或 manual View 尚未建立时产生的第三方 Span 会静默丢弃。
|
|
218
|
+
|
|
219
|
+
过滤层识别自上报请求时会同时检查 `url.full` 和 `http.url`。标准 OTel HTTP Instrumentation 写的是 `http.url`,所以它对 Collector 自身的请求也能被正确排除,不会形成上报回环。
|
|
220
|
+
|
|
213
221
|
限制:
|
|
214
222
|
|
|
215
223
|
- 当前稳定边界只有 Trace;
|
|
@@ -340,7 +340,7 @@ consentManager.onChange(async allowed => {
|
|
|
340
340
|
|
|
341
341
|
如果使用 manual View,授权后需要确认新的 Session 已创建,再按当前 Router 状态调用 `startView()`。自动模式会由 View 插件建立当前 View。
|
|
342
342
|
|
|
343
|
-
这个示例适用于“授权前可以构造、但不能采集和发送”的策略。若合规要求授权前连 UA/UA-CH
|
|
343
|
+
这个示例适用于“授权前可以构造、但不能采集和发送”的策略。若合规要求授权前连 UA / UA-CH 这类 Device Resource 快照都不能读取,应把 `new BkOpenTelemetry()` 本身也延迟到首次授权后;只设置 `trackingConsent: 'not-granted'` 不会推迟构造阶段的 Device Resource 读取。
|
|
344
344
|
|
|
345
345
|
## 微前端
|
|
346
346
|
|
|
@@ -147,6 +147,22 @@ context: {
|
|
|
147
147
|
|
|
148
148
|
SDK 原样透传 `user.id`,不会 hash。不要直接发送手机号、邮箱或可枚举的敏感账号标识。
|
|
149
149
|
|
|
150
|
+
需要先弹同意再采集时,不要依赖默认 `trackingConsent: 'granted'`:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
const rum = new BkOpenTelemetry({
|
|
154
|
+
application: { name: 'order-center' },
|
|
155
|
+
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
156
|
+
privacy: { trackingConsent: 'not-granted' },
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
async function onConsentGranted() {
|
|
160
|
+
await rum.setTrackingConsent('granted');
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
默认 Consent 仍会在构造期读取 Device Resource(UA、设备类型)。若授权前不能读取设备信息,应推迟整个 `new BkOpenTelemetry()`。完整边界见[隐私、Consent 与字段治理](./privacy.md)。
|
|
165
|
+
|
|
150
166
|
## 8. 手动上报业务事件
|
|
151
167
|
|
|
152
168
|
手动 Action:
|
|
@@ -187,7 +203,7 @@ rum.reportCustomEvent({
|
|
|
187
203
|
## 9. CDN 接入
|
|
188
204
|
|
|
189
205
|
```html
|
|
190
|
-
<script src="https://unpkg.com/@blueking/open-telemetry/dist/bk-rum.global.js"></script>
|
|
206
|
+
<script src="https://unpkg.com/@blueking/open-telemetry@0.0.29/dist/bk-rum.global.js"></script>
|
|
191
207
|
<script>
|
|
192
208
|
window.rum = new window.BkOpenTelemetry({
|
|
193
209
|
application: {
|
|
@@ -204,6 +220,8 @@ rum.reportCustomEvent({
|
|
|
204
220
|
|
|
205
221
|
生产 CDN 地址应固定 npm package 版本并使用你们认可的 CDN/SRI 策略,不要长期跟随 latest。全局 bundle 包含所需依赖,公开类名是 `window.BkOpenTelemetry`。
|
|
206
222
|
|
|
223
|
+
CDN 入口**只暴露**这个类(以及 `export default`),不能像 ESM 那样从包里具名导入 `createXxxPlugin`、`RUM_ATTRIBUTES` 或 TypeScript 类型。需要插件工厂或 schema 常量时请走 npm ESM 构建。
|
|
224
|
+
|
|
207
225
|
## 默认会采集什么
|
|
208
226
|
|
|
209
227
|
最小配置默认开启:
|
|
@@ -53,18 +53,17 @@ Span 开始时间使用请求开始时间,结束时间优先使用匹配到的
|
|
|
53
53
|
|
|
54
54
|
## Outcome 与 Status
|
|
55
55
|
|
|
56
|
-
| 条件 | `outcome.type` |
|
|
57
|
-
| ---------------------------------- | -------------- |
|
|
58
|
-
| `408` / `504` | `timeout` |
|
|
59
|
-
| 其他 `4xx`
|
|
60
|
-
|
|
|
61
|
-
| Fetch
|
|
62
|
-
| Fetch
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
SDK 不根据业务响应 JSON 中的 code 判断成功或失败;需要业务口径时使用 `request.beforeSend` 增加属性,或上报自定义事件。
|
|
56
|
+
| 条件 | `outcome.type` | OTel Status |
|
|
57
|
+
| ---------------------------------- | -------------- | --------------------------- |
|
|
58
|
+
| `408` / `504` | `timeout` | ERROR |
|
|
59
|
+
| 其他 `4xx` / `5xx` | `error` | ERROR |
|
|
60
|
+
| Fetch AbortError / XHR `abort` | `abort` | UNSET,不记录 exception |
|
|
61
|
+
| Fetch TimeoutError / XHR `timeout` | `timeout` | ERROR,Fetch 记录 exception |
|
|
62
|
+
| Fetch 其他 reject / XHR `error` | `error` | ERROR,Fetch 记录 exception |
|
|
63
|
+
| XHR `load` 但无法取得有效状态 | `error` | ERROR |
|
|
64
|
+
| 其余 | `success` | UNSET |
|
|
65
|
+
|
|
66
|
+
当前 SDK **不写** `outcome.reason`。HTTP 失败请用 `http.response.status_code` 细分。SDK 不根据业务响应 JSON 中的 code 判断成功或失败;需要业务口径时使用 `request.beforeSend` 增加属性,或上报自定义事件。
|
|
68
67
|
|
|
69
68
|
## URL 排除
|
|
70
69
|
|
|
@@ -275,12 +274,12 @@ Timing-Allow-Origin: https://your-web.example.com
|
|
|
275
274
|
|
|
276
275
|
`tracking.websocket=true` 时,SDK 使用 Proxy 包装全局 `WebSocket` 构造器,并保持静态常量、`instanceof` 和子类构造行为。每条连接生成 `websocket.connection.id`,随后发送四类瞬时 CLIENT Span:
|
|
277
276
|
|
|
278
|
-
| phase | 时机 | 额外字段
|
|
279
|
-
| --------- | --------------------- |
|
|
280
|
-
| `connect` | 构造 WebSocket 后立即 | 基础目标字段
|
|
281
|
-
| `open` | `open` Event | 无
|
|
282
|
-
| `error` | `error` Event | `websocket.error.phase
|
|
283
|
-
| `close` | `close` Event | code、reason、was_clean
|
|
277
|
+
| phase | 时机 | 额外字段 |
|
|
278
|
+
| --------- | --------------------- | --------------------------------------------- |
|
|
279
|
+
| `connect` | 构造 WebSocket 后立即 | 基础目标字段 |
|
|
280
|
+
| `open` | `open` Event | 无 |
|
|
281
|
+
| `error` | `error` Event | `websocket.error.phase`:`connect` 或 `runtime` |
|
|
282
|
+
| `close` | `close` Event | code、reason、was_clean |
|
|
284
283
|
|
|
285
284
|
Span 名统一为 `browser.websocket`,通过 `websocket.phase` 区分,不使用长连接 Span。基础字段包括:
|
|
286
285
|
|
|
@@ -24,25 +24,16 @@
|
|
|
24
24
|
|
|
25
25
|
- `vital.metric`
|
|
26
26
|
- `vital.value`
|
|
27
|
-
- `vital.rating=good|needs-improvement|poor`
|
|
28
27
|
- `vital.id`
|
|
29
28
|
- `span_type=vital`
|
|
30
|
-
- `outcome.type=success
|
|
29
|
+
- `outcome.type=success`,仅内部 rating=good
|
|
31
30
|
- `outcome.type=warning`,其他 rating
|
|
32
31
|
|
|
33
|
-
Vital Span 是瞬时 INTERNAL Span。非法 `NaN`、`Infinity`
|
|
32
|
+
Vital Span 是瞬时 INTERNAL Span。非法 `NaN`、`Infinity` 不上报。当前 **不写** `vital.rating` 或 `navigationType` Attribute;good/poor 只通过 `outcome.type` 体现。
|
|
34
33
|
|
|
35
34
|
## Navigation Type
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- `navigate`
|
|
40
|
-
- `reload`
|
|
41
|
-
- `back-forward`
|
|
42
|
-
- `back-forward-cache`
|
|
43
|
-
- `prerender`
|
|
44
|
-
- `restore`
|
|
45
|
-
- `unknown`
|
|
36
|
+
web-vitals 指标对象可能带 `navigationType`,但当前插件 **不会** 把它写入 Span。不要按该字段查询 Collector 数据。
|
|
46
37
|
|
|
47
38
|
## FCP、LCP 与 TTFB 的 View 归属
|
|
48
39
|
|
|
@@ -52,8 +43,8 @@ Attribution 字段:
|
|
|
52
43
|
|
|
53
44
|
| 指标 | 字段 |
|
|
54
45
|
| --- | --- |
|
|
55
|
-
| LCP | `vital.lcp.url`、`target`、`element_render_delay`、`resource_load_duration
|
|
56
|
-
| FCP |
|
|
46
|
+
| LCP | `vital.lcp.url`、`target`、`element_render_delay`、`resource_load_duration` |
|
|
47
|
+
| FCP | 当前无独立归因字段 |
|
|
57
48
|
| TTFB | `vital.ttfb.waiting_duration`、`dns_duration`、`connection_duration`、`request_duration` |
|
|
58
49
|
|
|
59
50
|
LCP URL 经过 `redactUrl`;DOM target 等字段可能包含高基数或业务语义,应纳入隐私审查。
|
|
@@ -66,16 +57,16 @@ SDK 不直接使用整页生命周期累计的 web-vitals CLS,而是按 SDK Vi
|
|
|
66
57
|
- 相邻 Shift 间隔小于 1 秒且窗口总长小于 5 秒时进入同一 session window;
|
|
67
58
|
- 取所有 session window 中累计值最大的一个;
|
|
68
59
|
- 数值保留四位小数;
|
|
69
|
-
- 记录该窗口中最大的单次 Shift
|
|
60
|
+
- 记录该窗口中最大的单次 Shift 及目标元素(仅用于内部累计 `vital.value`,**不上报** `vital.cls.largest_shift_*`);
|
|
70
61
|
- View 结束时发送一条 CLS Span,即使值为 0。
|
|
71
62
|
|
|
72
|
-
Rating
|
|
63
|
+
Rating 阈值(只影响 `outcome.type`,不写 `vital.rating`):
|
|
73
64
|
|
|
74
|
-
- `<= 0.1`:good
|
|
75
|
-
- `<= 0.25`:needs-improvement
|
|
76
|
-
- `> 0.25`:poor
|
|
65
|
+
- `<= 0.1`:good → `success`
|
|
66
|
+
- `<= 0.25`:needs-improvement → `warning`
|
|
67
|
+
- `> 0.25`:poor → `warning`
|
|
77
68
|
|
|
78
|
-
|
|
69
|
+
当前 **不上报** `vital.cls.load_state`。按 View 汇总的 CLS 传入空 attribution。
|
|
79
70
|
|
|
80
71
|
## 每个 View 的 INP
|
|
81
72
|
|
|
@@ -137,15 +128,13 @@ tracking: {
|
|
|
137
128
|
|
|
138
129
|
- `long_task.id`
|
|
139
130
|
- `long_task.entry_type=long-animation-frame|long-task`
|
|
140
|
-
- `long_task.duration`
|
|
141
131
|
- `long_task.name`
|
|
142
|
-
- LoAF 的 `long_task.start_time`
|
|
143
132
|
- LoAF 原生 `long_task.blocking_duration`
|
|
144
133
|
- LoAF 的 `long_task.first_ui_event_timestamp`
|
|
145
134
|
- LoAF 的 `long_task.render_start`
|
|
146
135
|
- LoAF 的 `long_task.style_and_layout_start`
|
|
147
136
|
|
|
148
|
-
Span 开始时间是 `performance.timeOrigin + entry.startTime
|
|
137
|
+
Span 开始时间是 `performance.timeOrigin + entry.startTime`,结束时间加上 `entry.duration`;持续时间只体现在 Span 起止时间上,没有独立的 `long_task.duration` 或 `long_task.start_time` Attribute。该 Span 也会通知 Action Activity,使活动中的 Action 能关联此 Long Task。
|
|
149
138
|
|
|
150
139
|
## LoAF 脚本 Event
|
|
151
140
|
|
|
@@ -52,7 +52,7 @@ await rum.setTrackingConsent('not-granted');
|
|
|
52
52
|
- SDK 不提供 Consent UI、Cookie 分类或法律依据记录;
|
|
53
53
|
- 页面中有多个 SDK 实例时,全局 OTel 对象按引用计数释放,但全局监听仍可能重复,因此仍应使用单实例。
|
|
54
54
|
|
|
55
|
-
构造阶段有一个重要边界:`new BkOpenTelemetry()` 会先解析配置并创建 OpenTelemetry Resource。只要 `tracking.device !== false`,这个过程会同步读取 UA
|
|
55
|
+
构造阶段有一个重要边界:`new BkOpenTelemetry()` 会先解析配置并创建 OpenTelemetry Resource。只要 `tracking.device !== false`,这个过程会同步读取 `navigator.userAgent` 与 UA-CH(`userAgentData.platform` / `mobile`),生成 `user_agent.*` 和 `device.type` 四个 Resource 字段,即使初始 Consent 是 `not-granted` 或 `enabled: false`;这些值此时不会发送,Device 插件的 ID/视口/网络监听也不会启动。如果你的合规定义连“读取 User-Agent”都必须晚于授权,应在获得授权后再构造 SDK,而不是只依赖 `trackingConsent`。
|
|
56
56
|
|
|
57
57
|
## URL 脱敏
|
|
58
58
|
|
|
@@ -39,7 +39,13 @@ SDK 使用以下固定规则:
|
|
|
39
39
|
|
|
40
40
|
## 跨 Tab 行为
|
|
41
41
|
|
|
42
|
-
默认 storage key
|
|
42
|
+
默认 storage key 按 `application.name` 与 **解析后 Endpoint 的 host** 计算:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
bk_ot_session__${hash36(application.name + "\0" + endpointHost)}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`hash36` 是 djb2 风格非密码学 hash,转成 36 进制。同一浏览器 origin 下,不同 `application.name` 或不同 Collector host 不会共用 Session。多个同源 Tab 默认共享同一 key 下的 Session Record。
|
|
43
49
|
|
|
44
50
|
- 其他 Tab 只延长当前相同 Session 时,本 Tab 会更新自己的过期 Timer。
|
|
45
51
|
- 其他 Tab 使 Session 过期或替换 ID 时,本 Tab 会停用自己的 Session。
|
|
@@ -75,22 +81,21 @@ new BkOpenTelemetry({
|
|
|
75
81
|
|
|
76
82
|
Span 名固定为 `browser.session`:
|
|
77
83
|
|
|
78
|
-
| `session.phase` | 使用时机 |
|
|
84
|
+
| `session.phase` | 使用时机 | 内部 lifecycle reason(不上报为 Attribute) |
|
|
79
85
|
| --- | --- | --- |
|
|
80
86
|
| `start` | 首次创建 | `init` |
|
|
81
87
|
| `rotate` | 旧 Session 过期后新建 | `inactivity`、`maxLifetime` |
|
|
82
88
|
| `end` | 当前 Session 失效 | `inactivity`、`maxLifetime`、`external` |
|
|
83
89
|
|
|
84
|
-
|
|
90
|
+
实际上报字段只有:
|
|
85
91
|
|
|
86
92
|
- `session.id`
|
|
87
|
-
- `session.start_time`
|
|
88
93
|
- `session.type=user`
|
|
89
94
|
- `session.has_replay=false`
|
|
90
|
-
- `session.lifecycle.reason`
|
|
91
|
-
- `session.previous_id`,仅存在前一个 ID 时出现
|
|
92
95
|
- `session.phase`
|
|
93
96
|
|
|
97
|
+
过期原因通过 `onSessionLifecycle` 通知插件,**不会**写成 `session.lifecycle.reason` 或 `session.start_time`。完整字段见[遥测字段字典](./telemetry-reference.md#session-字段)。
|
|
98
|
+
|
|
94
99
|
生命周期 Span 是瞬时事件,持续时间由服务端根据时间戳推导。
|
|
95
100
|
|
|
96
101
|
## User 上下文
|
|
@@ -121,10 +126,9 @@ SDK 只维护 `user.id`,并原样透传:不 hash、不截断、不验证、
|
|
|
121
126
|
| `user_agent.name` | UA 简单识别:Edge/Chrome/Firefox/Safari/Other | 否 |
|
|
122
127
|
| `user_agent.version` | UA 主版本 | 未识别版本时 |
|
|
123
128
|
| `user_agent.os.name` | UA / UA-CH platform | 否,无法识别为 `Other` |
|
|
124
|
-
| `device.type` | UA-CH mobile 或移动 UA |
|
|
125
|
-
| `device.memory_gib` | `navigator.deviceMemory` | 浏览器未实现时 |
|
|
129
|
+
| `device.type` | UA-CH mobile 或移动 UA 特征 | 否,仅为 `mobile` 或 `desktop` |
|
|
126
130
|
|
|
127
|
-
关闭 `tracking.device` 时,这些 Device Resource
|
|
131
|
+
关闭 `tracking.device` 时,这些 Device Resource 字段不写入。当前不读取 `navigator.deviceMemory`,因此没有 `device.memory_gib`。
|
|
128
132
|
|
|
129
133
|
## Device 运行时属性
|
|
130
134
|
|