@blueking/open-telemetry 0.0.22-beta.1 → 0.0.23

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 (45) hide show
  1. package/README.md +258 -70
  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 +10 -10
  5. package/dist/core/runtime-context.d.ts +1 -1
  6. package/dist/core/sdk.d.ts +1 -1
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.js +608 -662
  9. package/dist/index.js.map +1 -1
  10. package/dist/plugins/blank-screen.d.ts +1 -1
  11. package/dist/plugins/common.d.ts +2 -2
  12. package/dist/plugins/device.d.ts +2 -2
  13. package/dist/plugins/resource.d.ts +1 -0
  14. package/dist/plugins/web-vitals.d.ts +1 -3
  15. package/dist/schema/attributes.d.ts +6 -7
  16. package/dist/schema/span.d.ts +24 -15
  17. package/package.json +1 -1
  18. package/skills/bk-rum-otele/SKILL.md +31 -30
  19. package/skills/bk-rum-otele/references/actions.md +166 -0
  20. package/skills/bk-rum-otele/references/api.md +248 -215
  21. package/skills/bk-rum-otele/references/architecture.md +139 -37
  22. package/skills/bk-rum-otele/references/blank-screen.md +190 -0
  23. package/skills/bk-rum-otele/references/capabilities.md +175 -83
  24. package/skills/bk-rum-otele/references/configuration.md +226 -151
  25. package/skills/bk-rum-otele/references/data-model.md +157 -24
  26. package/skills/bk-rum-otele/references/errors-security.md +168 -0
  27. package/skills/bk-rum-otele/references/extensions.md +237 -0
  28. package/skills/bk-rum-otele/references/framework-integration.md +318 -75
  29. package/skills/bk-rum-otele/references/getting-started.md +186 -70
  30. package/skills/bk-rum-otele/references/network.md +258 -0
  31. package/skills/bk-rum-otele/references/performance.md +198 -0
  32. package/skills/bk-rum-otele/references/privacy.md +236 -67
  33. package/skills/bk-rum-otele/references/production.md +266 -0
  34. package/skills/bk-rum-otele/references/session-context.md +185 -0
  35. package/skills/bk-rum-otele/references/telemetry-reference.md +500 -51
  36. package/skills/bk-rum-otele/references/transport-sampling.md +321 -32
  37. package/skills/bk-rum-otele/references/troubleshooting.md +341 -151
  38. package/skills/bk-rum-otele/references/views-routing.md +211 -0
  39. package/skills/bk-rum-otele/references/concepts.md +0 -60
  40. package/skills/bk-rum-otele/references/custom-plugin.md +0 -170
  41. package/skills/bk-rum-otele/references/plugins-basic.md +0 -135
  42. package/skills/bk-rum-otele/references/plugins-error-security.md +0 -86
  43. package/skills/bk-rum-otele/references/plugins-experience.md +0 -124
  44. package/skills/bk-rum-otele/references/plugins-network.md +0 -32
  45. package/skills/bk-rum-otele/references/plugins.md +0 -62
@@ -0,0 +1,211 @@
1
+ <!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
2
+
3
+ # View、路由与页面稳定时间
4
+
5
+ View 表示一次可独立分析的页面体验。初始文档加载、SPA 路由、BFCache 恢复、Session 续期和业务手动划分都可以创建新 View。View 是普通 RUM Span 的必要上下文,不能关闭。
6
+
7
+ ## View 类型
8
+
9
+ | `view.loading_type` | 创建场景 | `span_type` |
10
+ | --- | --- | --- |
11
+ | `initial_load` | 初始自动 View;手动模式第一次 `startView()` | `view` |
12
+ | `route_change` | SPA 自动路由;手动模式后续 `startView()` | `view` |
13
+ | `bf_cache` | 从 Back/Forward Cache 恢复 | `view` |
14
+ | `session_renewal` | Session 过期后新 Session 接管当前页面 | `view` |
15
+
16
+ 每个 View 都生成新的 `view.id`。View 名称、URL、路由分组和自定义属性作为运行时上下文挂到其间发生的普通 Span。
17
+
18
+ ## 自动路由模式
19
+
20
+ `tracking.view.tracking` 默认为 `auto`。SDK:
21
+
22
+ - 启动时创建初始 View;
23
+ - 观察 `history.pushState()`、`history.replaceState()`、`popstate` 和 `hashchange`;
24
+ - pathname 改变时创建新 View;
25
+ - 非页内锚点的 hash path 改变时创建新 View;
26
+ - query-only 变化不创建 View;
27
+ - 指向当前页面真实元素 ID 的 hash 视为页内锚点,不创建 View。
28
+
29
+ 路由触发源写入 `view.source`,初始加载为 `load`,手动调用为 `manual`,其余使用对应 History/浏览器事件名。
30
+
31
+ ## 手动 View 模式
32
+
33
+ 框架路由希望完全控制边界时:
34
+
35
+ ```ts
36
+ const bkOT = new BkOpenTelemetry({
37
+ application: { name: 'order-web' },
38
+ autoStart: false,
39
+ transport: { endpoint: 'https://rum.example.com' },
40
+ tracking: {
41
+ view: { tracking: 'manual' },
42
+ },
43
+ });
44
+
45
+ await bkOT.start();
46
+ bkOT.startView({
47
+ name: '订单详情',
48
+ url: location.href,
49
+ attributes: { 'biz.page_owner': 'order-team' },
50
+ });
51
+ ```
52
+
53
+ 必须先建立采样有效的 Session。`startView()` 在尚未启动、未授权、未采样或没有 Session 时被忽略。手动模式第一次 `startView()` 之前没有有效 View,因此普通 Span 不会导出。
54
+
55
+ `attributes` 会经过 `redactAttributes`,并删除 SDK 所有保留字段;业务无法通过 View attributes 覆盖 `session.*`、`view.*`、`span_type` 或 `outcome.*`。
56
+
57
+ ## View 名称和路由分组
58
+
59
+ 默认 `view.url_path_group` 是 URL pathname,`view.name` 默认等于该分组。
60
+
61
+ ```ts
62
+ tracking: {
63
+ view: {
64
+ getPathGroup(url) {
65
+ return new URL(url, location.href).pathname
66
+ .replace(/\/orders\/[^/]+/, '/orders/:id')
67
+ .replace(/\/users\/[^/]+/, '/users/:id');
68
+ },
69
+ },
70
+ }
71
+ ```
72
+
73
+ `getPathGroup()` 应返回低基数、稳定的路由模板。当前业务 View 默认实现不会自动把数字、UUID 或其他业务 ID 替换为 `:id`,接入方必须按自己的路由规则显式提供模板。
74
+
75
+ 运行期可修改名称:
76
+
77
+ ```ts
78
+ bkOT.setViewName('订单详情-只读');
79
+ ```
80
+
81
+ 名称变化不会创建新 View,但会更新运行时上下文并发送 `browser.view` update。传入与当前相同名称时不发送更新。
82
+
83
+ ## URL 与前序页面
84
+
85
+ - `view.url`:当前 URL,经 `privacy.redactUrl`。
86
+ - `view.url_path_group`:聚合路由模板。
87
+ - `url.previous`:前一个原始 URL 经脱敏;初始加载为空字符串。
88
+ - `document.referrer`:仅初始自动加载写入并脱敏。
89
+
90
+ 用于路由判断的是原始 URL,写入遥测的是脱敏 URL。自定义 `redactUrl` 不会影响是否切换 View。
91
+
92
+ ## View 生命周期 Span
93
+
94
+ Span 名固定为 `browser.view`:
95
+
96
+ | phase | 触发 |
97
+ | --- | --- |
98
+ | `start` | 创建 View |
99
+ | `update` | Loading Time 就绪、手动覆盖 Loading Time、名称变化 |
100
+ | `end` | 新 View、pagehide、BFCache、Session 过期或 SDK shutdown |
101
+
102
+ 每条生命周期 Span 都是瞬时事件,并携带递增的 `view.version`。常见 `view.end_reason`:
103
+
104
+ - 新自动路由的触发源,例如 `pushState`、`popstate`
105
+ - `manual`
106
+ - `bfcache`
107
+ - `pagehide`
108
+ - `session_expired`
109
+ - `shutdown`
110
+
111
+ 服务端应按 `view.id + view.version` 幂等合并,而不是依赖网络到达顺序。
112
+
113
+ ## 初始导航时间
114
+
115
+ 初始 View 尝试从 `PerformanceNavigationTiming` 读取:
116
+
117
+ | 字段 | 浏览器原值 | 单位 |
118
+ | --- | --- | --- |
119
+ | `view.first_byte` | `responseStart` | 相对 `performance.timeOrigin` 的 ms |
120
+ | `view.dom_interactive` | `domInteractive` | 同上 |
121
+ | `view.dom_content_loaded` | `domContentLoadedEventEnd` | 同上 |
122
+ | `view.dom_complete` | `domComplete` | 同上 |
123
+ | `view.load_event` | `loadEventEnd` | 同上 |
124
+
125
+ 值必须有限且大于 0 才写入。它们是相对导航起点的时间,不是 epoch 时间戳。
126
+
127
+ ## 自动 View Loading Time
128
+
129
+ `tracking.view.loadingTime` 默认 `true`。SDK 同时等待:
130
+
131
+ 1. 页面活动进入稳定状态;
132
+ 2. 初始加载的 `window.load` / `loadEventEnd` 可用。
133
+
134
+ 页面活动包括:
135
+
136
+ - Fetch/XHR 开始和结束;
137
+ - 静态 Resource 完成;
138
+ - DOM Mutation;
139
+ - `window.open` 等活动总线事件。
140
+
141
+ 页面从 View 创建后先观察 100ms:没有任何页面活动时,活动侧不提供候选值;发生过活动后,所有请求完成且连续 100ms 无新活动即认为稳定。
142
+
143
+ - 初始加载:只要能取得 `loadEventEnd`,即使前 100ms 没有其他活动,也可生成 Loading Time;最终取 `loadEventEnd` 与页面活动结束耗时的较大值。
144
+ - SPA/BFCache/Session Renewal:只有观察到页面活动时才生成自动 Loading Time,取 View 开始到页面活动结束的耗时。
145
+ - 页面在计算期间变为 hidden:取消自动计算,不上报不可靠结果。
146
+
147
+ `view.loading_time.source=auto` 表示自动计算。
148
+
149
+ ## 排除长轮询和无关活动
150
+
151
+ 持续连接、埋点和轮询可能让页面永远无法稳定:
152
+
153
+ ```ts
154
+ tracking: {
155
+ view: {
156
+ excludedActivityUrls: [
157
+ /\/events\/stream(?:\?|$)/,
158
+ url => new URL(url).pathname === '/health',
159
+ ],
160
+ },
161
+ }
162
+ ```
163
+
164
+ 匹配项支持字符串包含、正则和函数。该配置只决定请求/资源是否延长 View/Action 活动窗口,不等于关闭请求 Span;完全不采集应使用 `tracking.request.excludedUrls`。
165
+
166
+ DOM 子树可使用导出的 `EXCLUDED_ACTIVITY_MUTATIONS_ATTRIBUTE` 对应属性 `data-bk-excluded-activity-mutations` 标记,使其 Mutation 不延长页面活动。
167
+
168
+ ## 手动覆盖 Loading Time
169
+
170
+ 业务知道真实渲染完成点时:
171
+
172
+ ```ts
173
+ await renderAsyncContent();
174
+ bkOT.setViewLoadingTime();
175
+ ```
176
+
177
+ SDK 计算“调用时刻 - View 开始时间”,取消仍在进行的自动计算,并发送 update:
178
+
179
+ - `view.loading_time.source=manual`
180
+ - 多次调用以后一次为准;每次都会产生新版本 update。
181
+ - 没有采样有效 View 时忽略。
182
+
183
+ ## BFCache
184
+
185
+ 页面以 `pagehide.persisted=true` 进入 BFCache 时:
186
+
187
+ 1. 结束当前 View,`view.end_reason=bfcache`。
188
+ 2. 保存旧 View 的名称、URL 和自定义属性。
189
+ 3. `pageshow.persisted=true` 时创建新的 `bf_cache` View。
190
+
191
+ 冻结时间不会计入旧 View 或恢复后的新 View。如果恢复时 Session 已过期,SDK等到新 Session 建立后再创建 `session_renewal` View。
192
+
193
+ ## 常见问题
194
+
195
+ ### SPA 只有初始 View
196
+
197
+ 检查路由是否只改变 query;自动模式明确忽略 query-only 变化。需要以 query 区分业务页面时使用手动 View。
198
+
199
+ ### View Loading Time 一直没有出现
200
+
201
+ 检查:
202
+
203
+ - 页面是否在计算期间进入后台;
204
+ - 页面是否完全没有可观察活动;
205
+ - 是否有未结束长轮询;
206
+ - `tracking.view.loadingTime` 是否为 `false`;
207
+ - 是否在手动模式首次 `startView()` 前观察数据。
208
+
209
+ ### View 数量过多
210
+
211
+ 确认是否同时使用自动模式和框架 `startView()`。手动同步路由时必须设 `tracking: 'manual'`。
@@ -1,60 +0,0 @@
1
- <!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
2
-
3
- # 核心概念
4
-
5
- ## 单一原始事件通道
6
-
7
- SDK 只使用 OpenTelemetry Trace:浏览器事实和本地体验语义都编码为 RUM Span,通过 `/v1/rum` 上报。浏览器不创建 Counter、Histogram 或 Log;聚合由服务端完成。
8
-
9
- ## Session、View、Action
10
-
11
- - `session.id` 关联一次访问会话,采样以 Session 为边界。
12
- - `view.id` 关联初始页面、SPA 路由、BFCache 或手动 View。
13
- - `action.id` 关联一次用户动作活动窗口。
14
- - `user.id` 由接入方提供,SDK 原样透传。
15
-
16
- 生命周期事件使用 `event.id`、`event.type`、`event.phase`、`event.timestamp`。View 额外使用 `view.version` 处理更新和乱序。
17
-
18
- ## 本地计算边界
19
-
20
- SDK 只保留必须依赖浏览器本地状态的计算:CLS、INP、View Loading Time、Action Loading Time、挫败信号和白屏判断。错误分组、计数、分位数和跨事件聚合全部交给服务端。
21
-
22
- ## 采样
23
-
24
- `session.sampleRate` 使用 `application.name + session.id` 做确定性采样。采样率同时写入 Resource 的 `session.sample_rate`,供后端修正总体指标。
25
-
26
- ## 扩展
27
-
28
- 自定义 RUM 插件使用 `context.startSpan()`,标准 OpenTelemetry instrumentation 通过 `extensions.instrumentations` 注册。避免重复注册 Fetch/XHR 或用户交互探针。
29
-
30
- # 内置采集与扩展
31
-
32
- `tracking` 只配置 SDK 内置采集能力;`extensions` 只注册接入方提供的扩展实例。
33
-
34
- ```ts
35
- new BkOpenTelemetry({
36
- application: { name: 'demo' },
37
- transport: { endpoint: 'https://collector.example.com' },
38
- tracking: {
39
- request: true,
40
- error: true,
41
- longTask: false,
42
- },
43
- extensions: {
44
- plugins: [myRumPlugin],
45
- instrumentations: [myOtelInstrumentation],
46
- },
47
- });
48
- ```
49
-
50
- | 类型 | 配置位置 | 适用场景 |
51
- | --- | --- | --- |
52
- | 内置采集 | `tracking` | View、请求、资源、错误、Web Vitals、Action 等 |
53
- | RUM 插件 | `extensions.plugins` / `use()` | 需要 Session/View、日志、指标和活动总线的浏览器语义 |
54
- | OTel instrumentation | `extensions.instrumentations` / `useInstrumentation()` | 已有标准 instrumentation,直接使用 SDK 私有 provider |
55
-
56
- 内置 Fetch/XHR 不再基于官方 instrumentation 叠加适配,而是由单一请求生命周期实现,避免重复 patch、重复活动计数及私有 `_addHeaders/_patchSend` 依赖。
57
-
58
- 当前扩展 instrumentation 的稳定能力边界是 Trace:Filtering Span Processor 会在 Span 创建时补充有效 RUM 上下文。SDK 不创建 Metric Provider,第三方 instrumentation 的 Metric 不属于支持范围。
59
-
60
- 扩展必须在 `start()` 前注册;动态 Consent 重新授权时,插件可能再次执行 `init()`,所以插件的 `shutdown()` 应完整释放副作用。
@@ -1,170 +0,0 @@
1
- <!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
2
-
3
- # 自定义插件
4
-
5
- 自定义插件适合封装业务事件、补充特定浏览器 API 采集,或接入额外 OpenTelemetry instrumentation。
6
-
7
- ## 插件契约
8
-
9
- 插件由 `createPlugin()` 创建,核心字段是 `name`、`enabled`、`init`、`flush`、`shutdown`。
10
-
11
- ```ts
12
- import { createPlugin } from '@blueking/open-telemetry';
13
-
14
- const bizPlugin = createPlugin({
15
- name: 'biz-plugin',
16
- enabled: config => config.enabled,
17
- init(context) {
18
- const span = context.startSpan('custom.biz_plugin_init', {
19
- 'biz.plugin': 'ready',
20
- });
21
- span.end();
22
- },
23
- flush() {
24
- // 可在这里刷新插件内部缓存
25
- },
26
- shutdown() {
27
- // 可在这里移除事件监听
28
- },
29
- });
30
- ```
31
-
32
- ## 注册插件
33
-
34
- `use()` 必须在 `start()` 之前调用。
35
-
36
- ```ts
37
- import { BkOpenTelemetry } from '@blueking/open-telemetry';
38
- import { bizPlugin } from './biz-plugin';
39
-
40
- const bkOT = new BkOpenTelemetry({
41
- application: { name: 'plugin-demo' },
42
- autoStart: false,
43
- transport: {
44
- endpoint: 'https://rum-collector.example.com',
45
- },
46
- });
47
-
48
- bkOT.use(bizPlugin);
49
-
50
- await bkOT.start();
51
- ```
52
-
53
- ## 使用 runtime context
54
-
55
- `init(context)` 中可以访问 `tracer`、`startSpan()`、`getRuntimeAttributes()` 等能力。
56
-
57
- 优先使用 `context.startSpan()`:它会合并事件发生时的运行时上下文并应用 SDK 脱敏。
58
-
59
- ```ts
60
- let teardownVisibility = () => {};
61
-
62
- const visibilityPlugin = createPlugin({
63
- name: 'visibility-change',
64
- init(context) {
65
- const onVisibilityChange = () => {
66
- const occurredAt = Date.now();
67
- context.startSpan('document.visibilitychange', {
68
- 'event.type': 'custom',
69
- 'event.timestamp': occurredAt,
70
- 'document.visibility_state': document.visibilityState,
71
- }, { startTime: occurredAt }).end(occurredAt);
72
- };
73
-
74
- document.addEventListener('visibilitychange', onVisibilityChange);
75
- teardownVisibility = () => document.removeEventListener('visibilitychange', onVisibilityChange);
76
- },
77
- shutdown() {
78
- teardownVisibility();
79
- },
80
- });
81
- ```
82
-
83
- ## 清理事件监听
84
-
85
- 插件应在 `shutdown()` 中释放自己注册的监听器。
86
-
87
- ```ts
88
- const resizePlugin = createPlugin({
89
- name: 'window-resize',
90
- init(context) {
91
- const onResize = () => {
92
- const span = context.startSpan('custom.window_resize', {
93
- 'window.inner_width': window.innerWidth,
94
- 'window.inner_height': window.innerHeight,
95
- });
96
- span.end();
97
- };
98
-
99
- window.addEventListener('resize', onResize);
100
-
101
- this.shutdown = () => {
102
- window.removeEventListener('resize', onResize);
103
- };
104
- },
105
- });
106
- ```
107
-
108
- 更推荐使用闭包保存清理函数,避免依赖 `this`。
109
-
110
- ```ts
111
- const createResizePlugin = () => {
112
- let teardown = () => {};
113
-
114
- return createPlugin({
115
- name: 'window-resize',
116
- init(context) {
117
- const onResize = () => {
118
- const span = context.startSpan('custom.window_resize');
119
- span.end();
120
- };
121
-
122
- window.addEventListener('resize', onResize);
123
- teardown = () => window.removeEventListener('resize', onResize);
124
- },
125
- shutdown() {
126
- teardown();
127
- },
128
- });
129
- };
130
- ```
131
-
132
- ## 注册额外 instrumentation
133
-
134
- 第三方 OpenTelemetry instrumentation 放在 `extensions.instrumentations`,或通过 `useInstrumentation()` 链式注册。两者区别详见 [内置采集与扩展](./concepts.md)。
135
-
136
- 配置式:
137
-
138
- ```ts
139
- const bkOT = new BkOpenTelemetry({
140
- application: { name: 'extension-demo' },
141
- transport: {
142
- endpoint: 'https://rum-collector.example.com',
143
- },
144
- extensions: {
145
- instrumentations: [new SomeWebInstrumentation()],
146
- },
147
- });
148
- ```
149
-
150
- 链式(适合运行时动态追加,必须在 `start()` 之前):
151
-
152
- ```ts
153
- const bkOT = new BkOpenTelemetry({
154
- application: { name: 'extension-demo' },
155
- autoStart: false,
156
- transport: {
157
- endpoint: 'https://rum-collector.example.com',
158
- },
159
- });
160
-
161
- bkOT.useInstrumentation(new SomeWebInstrumentation());
162
-
163
- await bkOT.start();
164
- ```
165
-
166
- > Extension instrumentation 与采集生命周期一致:未授权或 SDK 停止时不会注册;授权后注册。它产生的 Span 受 Session sampler 和导出过滤约束。
167
-
168
- ## 自定义信号边界
169
-
170
- SDK 插件上下文不提供 Meter、Logger 或 `emitLog()`。具体业务行为使用 Span;计数、分布和分位数由服务端从 Span 派生。
@@ -1,135 +0,0 @@
1
- <!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
2
-
3
- # 基础采集插件
4
-
5
- 基础插件负责建立 RUM 数据的关联上下文:哪个用户、哪个会话、哪个页面、哪个设备。
6
-
7
- 以下片段聚焦对应的 `session` 或 `tracking` 配置,实际初始化仍需提供必填的 `application.name` 和有效的 `transport` endpoint 配置。
8
-
9
- ## session
10
-
11
- `session` 维护 `session.id`,并在会话开始、轮换和结束时写入 `browser.session` 生命周期 Span。它是所有 RUM 事件的关联边界,获得 Consent 后始终开启,不能关闭;是否导出由 Session 采样决定。
12
-
13
- 默认规则:
14
-
15
- - 不活跃超过 15 分钟后过期,下一次用户交互时轮换。
16
- - 会话最长 4 小时。
17
- - storage key 会按 endpoint host 隔离。
18
- - 页面重新可见只续期有效会话,不会复活已过期会话。
19
- - 跨 Tab 共享持久化状态,但已过期的 Tab 需要自身发生用户交互后才接管新会话。
20
-
21
- ```ts
22
- new BkOpenTelemetry({
23
- session: {
24
- storageKey: 'bk-rum-session',
25
- },
26
- });
27
- ```
28
-
29
- 超时固定为 15 分钟无活动、4 小时最长生命周期,不开放配置。过期会结束当前 View、刷新旧 Session 的待发送数据,并丢弃此后所有不带有效 `session.id` 的 Span;下一次用户交互续期时,同时创建新的 Session 和 View。
30
-
31
- **产出遥测**:`browser.session` start/rotate/end Span,并维护 `session.id`、`session.start_time`、`session.type`。
32
-
33
- ## device
34
-
35
- `device` 插件采集设备、浏览器、系统、视口和网络信息。默认开启。
36
-
37
- ```ts
38
- new BkOpenTelemetry({
39
- tracking: {
40
- device: {
41
- persistentId: true,
42
- storageKey: 'bk-rum-device',
43
- },
44
- },
45
- });
46
- ```
47
-
48
- 稳定的浏览器、系统和硬件能力写入 Resource;设备 ID、视口和网络信息保留为运行时属性,后续 Span 会自动携带。
49
-
50
- `device.id` 默认只在当前 SDK 实例内稳定;只有显式设置 `persistentId: true` 才写入 localStorage,并按应用名隔离默认 storage key。
51
-
52
- **产出遥测**:写入 Resource 属性(如 `browser.name`、`os.name`、`device.type`、`device.memory_gib`)和运行时属性(如 `device.id`、`browser.viewport.*`、`network.effective_type`),本身不单独产生 Span。
53
-
54
- ## View
55
-
56
- View 管理器负责初始页面、SPA 路由、手动 View、BFCache 和 Session 续期。它与 Session 一样不可关闭,并维护:
57
-
58
- - `view.id`
59
- - `view.name`
60
- - `view.url`
61
- - `view.url_path_group`
62
- - `view.loading_type`
63
- - `view.loading_time`
64
-
65
- ```ts
66
- new BkOpenTelemetry({
67
- tracking: {
68
- view: {
69
- tracking: 'auto',
70
- loadingTime: true,
71
- excludedActivityUrls: [/\/events\/stream$/],
72
- getPathGroup: url => {
73
- const { pathname } = new URL(url, window.location.href);
74
- return pathname.replace(/\/\d+/g, '/:id');
75
- },
76
- },
77
- },
78
- });
79
- ```
80
-
81
- 自动模式只在 pathname 或非锚点 hash path 变化时切换 View;query-only 和页内锚点变化不会切换。手动模式使用 `view.tracking: 'manual'`,并调用 `startView({ name, url, attributes })`。
82
-
83
- ```ts
84
- const bkOT = new BkOpenTelemetry({
85
- application: { name: 'order-web' },
86
- autoStart: false,
87
- transport: { endpoint: 'https://rum-collector.example.com' },
88
- tracking: { view: { tracking: 'manual' } },
89
- });
90
-
91
- await bkOT.start();
92
- bkOT.startView({
93
- name: '订单详情',
94
- url: window.location.href,
95
- attributes: { 'biz.owner': 'order-team' },
96
- });
97
- bkOT.setViewName('订单详情-只读');
98
- ```
99
-
100
- `view.id` 始终由 SDK 生成,`attributes` 不能覆盖 Session/View 等保留字段。普通 Span 必须同时带有 `session.id` 和 `view.id` 才会进入导出链路。手动模式在首次 `startView()` 前不会导出普通 RUM 数据。
101
-
102
- View Loading Time 默认开启:初始加载取 `loadEventEnd` 与页面活动结束时间的较大值,SPA 路由取 View 创建到页面活动结束的耗时。请求、静态资源和 DOM 变更都属于页面活动,连续 100ms 无活动视为稳定。长轮询或埋点请求应配置到 `view.excludedActivityUrls`;业务也可在真正渲染完成时调用 `setViewLoadingTime()` 覆盖自动结果。
103
-
104
- **产出遥测**:`browser.view` start/update/end 原始生命周期 Span。每次事件携带 `view.version`,Loading Time 就绪或 View 名称变化时产生 update。
105
-
106
- ## action
107
-
108
- `action` 插件默认开启。它自动监听 click,观察交互后的请求、DOM 变更、资源、错误和长任务,在页面活动稳定后生成一个 `action` span。
109
-
110
- **产出遥测**:span `action.<type>`(如 `action.click`,`span_type=action`)。`reportAction()` 走同一套字段。
111
-
112
- ```ts
113
- new BkOpenTelemetry({
114
- tracking: {
115
- action: {
116
- actionNameAttribute: 'data-bk-action-name',
117
- maxDuration: 10000,
118
- nameCollection: 'explicit',
119
- },
120
- },
121
- });
122
- ```
123
-
124
- 自动命名在默认 `explicit` 模式只向上查找 `data-bk-action-name`;没有显式名称时退回目标元素标签名。设置 `nameCollection: 'text'` 后才会继续读取 label、按钮值、`aria-label`、`alt`、`name`、`title`、`placeholder` 和 DOM 文本,并自行评估隐私风险。
125
-
126
- 对关键业务动作,推荐使用 `reportAction()` 显式上报,字段更稳定。
127
-
128
- ```ts
129
- bkOT.reportAction({
130
- name: '立即支付',
131
- attributes: {
132
- 'biz.order_id': '202605270001',
133
- },
134
- });
135
- ```
@@ -1,86 +0,0 @@
1
- <!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
2
-
3
- # 错误与安全插件
4
-
5
- 以下片段聚焦 `tracking` 配置,实际初始化仍需提供必填的 `application.name` 和有效的 `transport` endpoint 配置。
6
-
7
- 错误类插件帮助定位 JavaScript 异常、Promise 异常、资源加载失败、CSP 违规和空白屏等问题。
8
-
9
- ## error
10
-
11
- `error` 插件默认开启,监听:
12
-
13
- - `window.error`
14
- - `unhandledrejection`
15
- - 资源加载错误
16
-
17
- 插件会生成 error span,并使用 fingerprint 做窗口内节流,避免相同错误在短时间内刷屏。
18
-
19
- **产出遥测**:span `browser.error`(JS 错误)、`browser.unhandledrejection`(Promise 异常)、`browser.resource_error`(资源加载失败),均为 `span_type=error`,带原始 `error.message`、`error.source` 和标准 exception event。SDK 不做错误指纹、计数或节流。
20
-
21
- ```ts
22
- new BkOpenTelemetry({
23
- tracking: {
24
- error: {
25
- maxPerWindow: 5,
26
- windowMs: 60_000,
27
- },
28
- },
29
- });
30
- ```
31
-
32
- ## 手动上报错误事件
33
-
34
- 业务捕获到错误后,可以通过 `reportCustomEvent()` 上报。
35
-
36
- ```ts
37
- try {
38
- await submitOrder();
39
- } catch (error) {
40
- bkOT.reportCustomEvent({
41
- name: 'submit_order_failed',
42
- error: error instanceof Error ? error : new Error(String(error)),
43
- attributes: {
44
- 'biz.order_id': '202605270001',
45
- },
46
- });
47
- }
48
- ```
49
-
50
- ## cspViolation
51
-
52
- `cspViolation` 插件默认关闭。开启后监听浏览器 `securitypolicyviolation` 事件,并写入 error span。
53
-
54
- **产出遥测**:span `csp.violation`(`span_type=error`),带 `csp.*` 字段;完整策略 `csp.original_policy` 仅在节流窗口首条携带。
55
-
56
- ```ts
57
- new BkOpenTelemetry({
58
- tracking: {
59
- cspViolation: true,
60
- },
61
- });
62
- ```
63
-
64
- 建议与站点 CSP 响应头一起使用。
65
-
66
- ```http
67
- Content-Security-Policy: default-src 'self'; report-uri /csp-report
68
- ```
69
-
70
- ## blankScreen 与错误排查
71
-
72
- 空白屏通常是错误、资源失败或首屏渲染失败的结果。建议同时开启 `blankScreen`、`error`、`resource`。
73
-
74
- ```ts
75
- new BkOpenTelemetry({
76
- tracking: {
77
- blankScreen: {
78
- rootSelector: '#app',
79
- },
80
- error: true,
81
- resource: true,
82
- },
83
- });
84
- ```
85
-
86
- 通过 `view.id` 和 `session.id` 可以把空白屏、JS 错误、资源失败关联到同一次页面访问。