@blueking/open-telemetry 0.0.10 → 0.0.12
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/dist/bk-rum.global.js +2 -2
- package/dist/bk-rum.global.js.map +1 -1
- package/dist/index.js +471 -471
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
- package/skills/bk-rum-otele/SKILL.md +108 -0
- package/skills/bk-rum-otele/evals/evals.json +29 -0
- package/skills/bk-rum-otele/references/api.md +228 -0
- package/skills/bk-rum-otele/references/concepts.md +227 -0
- package/skills/bk-rum-otele/references/configuration.md +318 -0
- package/skills/bk-rum-otele/references/custom-plugin.md +158 -0
- package/skills/bk-rum-otele/references/data-model.md +122 -0
- package/skills/bk-rum-otele/references/framework-integration.md +149 -0
- package/skills/bk-rum-otele/references/getting-started.md +179 -0
- package/skills/bk-rum-otele/references/plugins.md +451 -0
- package/skills/bk-rum-otele/references/privacy.md +117 -0
- package/skills/bk-rum-otele/references/telemetry-reference.md +228 -0
- package/skills/bk-rum-otele/references/troubleshooting.md +239 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
<!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
|
|
2
|
+
|
|
3
|
+
# 遥测参考
|
|
4
|
+
|
|
5
|
+
本页是 SDK **实际产出**的 span 名、metric 名、log 事件名和属性字段的权威速查表,供数据看板、告警规则、后端建模对齐。所有名称都与 SDK 源码保持一致,随版本更新。
|
|
6
|
+
|
|
7
|
+
> 概念与设计边界见[数据模型](./data-model.md);本页只做「叫什么名字、带哪些字段」的查询。
|
|
8
|
+
|
|
9
|
+
## 命名规则
|
|
10
|
+
|
|
11
|
+
- **信号名**:`browser.*` 表示内置浏览器事件(如 `browser.web_vital`);`action.<type>`、`custom.<name>` 是运行期动态拼接;`csp.violation`、`websocket.*` 使用领域前缀。
|
|
12
|
+
- **属性 key**:沿用 OpenTelemetry 语义约定的字段用点号(如 `http.request.method`、`exception.type`、`view.id`、`session.id`、`user.id`);RUM 归一与低基数聚合维度用下划线(如 `span_type`、`result`、`browser_name`、`device_type`)。这一区分是有意为之,字段常量集中定义在 `src/schema/attributes.ts`。
|
|
13
|
+
|
|
14
|
+
## 公共上下文属性
|
|
15
|
+
|
|
16
|
+
以下属性由运行时上下文自动挂到**几乎所有** span / log 上(metric 视插件而定),后续各清单不再重复列出:
|
|
17
|
+
|
|
18
|
+
| key | 类型 | 说明 | 低基数 |
|
|
19
|
+
| --- | --- | --- | --- |
|
|
20
|
+
| `service.name` | string | 应用名(`app.name`) | 是 |
|
|
21
|
+
| `service.version` | string | 应用版本(`app.version`,可选) | 是 |
|
|
22
|
+
| `deployment.environment.name` | string | 环境(`app.environment`) | 是 |
|
|
23
|
+
| `rum.provider` | string | 固定 `blueking` | 是 |
|
|
24
|
+
| `telemetry.sdk.language` | string | 固定 `webjs` | 是 |
|
|
25
|
+
| `user.id` | string | 接入方提供,原样透传 | 否 |
|
|
26
|
+
| `session.id` | string | session 插件生成/轮换 | 否 |
|
|
27
|
+
| `session.has_replay` | boolean | 当前固定 `false` | 是 |
|
|
28
|
+
| `view.id` | string | pageView 维护的 view 实例 ID | 否 |
|
|
29
|
+
| `view.url` | string | 当前 view URL(已脱敏) | 否 |
|
|
30
|
+
| `view.url_path_group` | string | 低基数路由模板 | 是 |
|
|
31
|
+
| `view.loading_type` | string | `initial_load` / `route_change` | 是 |
|
|
32
|
+
| `device_type` | string | `mobile` / `desktop` | 是 |
|
|
33
|
+
| `browser_name` / `browser_version` | string | 浏览器信息 | 是 |
|
|
34
|
+
| `os_name` | string | 操作系统 | 是 |
|
|
35
|
+
| `network.effective_type` | string | 网络质量(`4g` 等) | 是 |
|
|
36
|
+
|
|
37
|
+
> span 还会带上 `span_type` / `span_subtype` / `result` / `error_type` / `event_label` / `target_label` 等归一字段(见下方[归一字段](#归一字段))。默认 `attributes.page` 会额外注入 `rum.page.host` / `rum.page.path`。
|
|
38
|
+
|
|
39
|
+
## Span 清单
|
|
40
|
+
|
|
41
|
+
| span 名 | span_type | 来源 | 关键属性 | 备注 |
|
|
42
|
+
| --- | --- | --- | --- | --- |
|
|
43
|
+
| `browser.view` | `document` / `route` | pageView 插件 | `url.previous`、`event.source`、`view.end_reason` | 有持续时间,下一次 view 或 pagehide 时结束 |
|
|
44
|
+
| `browser.page_view` | `document`(初始)/ `route`(路由) | pageView 插件 | `document.referrer`(仅初始加载) | 0ms 瞬时事件 |
|
|
45
|
+
| `HTTP <METHOD>` | `http` | fetch / xhr instrumentation | `http.request.method`、`http.response.status_code`、`url.full`、`target_domain`、`target_path_template`、`status_class` | span 名由官方探针决定 |
|
|
46
|
+
| `documentLoad` / `documentFetch` / `resourceFetch` | `document` / `resource` | documentLoad instrumentation | `trace_scene=page_load` | span 名由官方探针决定 |
|
|
47
|
+
| `browser.resource` | `resource` | resource 插件 | `url.full`、`initiator_type`、`transfer_size`、`next_hop_protocol`、`cache_hit`、`resource.encoded_body_size`、`resource.decoded_body_size` | |
|
|
48
|
+
| `browser.web_vital` | `vital` | webVitals 插件 | `vital.metric`、`vital.value`、`vital.rating`、`vital.id`、`rum.navigation.type`、`vital.<lcp\|cls\|inp\|fcp\|ttfb>.*` | 每个指标一条 |
|
|
49
|
+
| `browser.blank_screen` | `error` | blankScreen 插件(判定为白屏时) | `blank_screen.score`、`blank_screen.threshold`、`blank_screen.detected`、`blank_screen.root`、`blank_screen.sample_*`、`blank_screen.center_element`、`blank_screen.dom_node_count` | |
|
|
50
|
+
| `browser.error` | `error` | error 插件(`window.error`) | `exception.*`、`error.source=window.error`、`error.window_count`、`code.filepath`、`code.lineno`、`code.column`、`error.cross_origin` | |
|
|
51
|
+
| `browser.unhandledrejection` | `error` | error 插件(Promise 异常) | `exception.*`、`error.source=unhandledrejection` | |
|
|
52
|
+
| `browser.resource_error` | `error` | error 插件(资源加载失败) | `exception.*`、`error.source=resource`、`url.full`、`html.tag` | |
|
|
53
|
+
| `browser.long_task` | `longtask` | longTask 插件 | `longtask.blocking_duration`、`longtask.attribution_script`、`target_value` | |
|
|
54
|
+
| `browser.route_change` | `route` | routeTiming 插件 | `url.full`、`url.previous`、`route.change.source`、`target_value`(耗时) | |
|
|
55
|
+
| `csp.violation` | `error` | cspViolation 插件 | `csp.blocked_uri`、`csp.violated_directive`、`csp.effective_directive`、`csp.source_file`、`csp.line_number`、`csp.status_code`、`csp.fingerprint`、`csp.window_count`、`csp.original_policy`(窗口首条) | |
|
|
56
|
+
| `websocket.connect` | `custom` | websocket 插件(仅建连阶段) | `url.full`、`url.scheme`、`server.address`、`network.protocol.name=websocket`、`target_domain` | 长连接生命周期不绑定 span |
|
|
57
|
+
| `action.<type>` | `action` | action 插件 & `reportAction()` | `action.type`、`target.tag`、`target.text_short`、`target_label` | 如 `action.click` |
|
|
58
|
+
| `custom.<name>` | `custom` | `reportCustomEvent()` / 自定义插件 | `rum.custom.name`、业务自定义属性 | 带 `error` 时附 `exception.*` |
|
|
59
|
+
|
|
60
|
+
## Metric 清单
|
|
61
|
+
|
|
62
|
+
| 名称 | 类型 | 单位 | 主要维度 | 来源 |
|
|
63
|
+
| --- | --- | --- | --- | --- |
|
|
64
|
+
| `browser.web_vital.cls` | Histogram | `1` | `vital.metric`、`vital.rating`、`rum.navigation.type`、`view.url_path_group` | webVitals |
|
|
65
|
+
| `browser.web_vital.duration` | Histogram | `ms` | 同上(FCP/INP/LCP/TTFB 靠 `vital.metric` 区分) | webVitals |
|
|
66
|
+
| `browser.blank_screen.count` | Counter | - | `view.url_path_group`、`blank_screen.root` | blankScreen |
|
|
67
|
+
| `browser.long_task.count` | Counter | - | `view.url_path_group`、`longtask.attribution_script` | longTask |
|
|
68
|
+
| `browser.long_task.duration` | Histogram | `ms` | 同上 | longTask |
|
|
69
|
+
| `browser.route_change.duration` | Histogram | `ms` | `view.url_path_group`、`route.change.source` | routeTiming |
|
|
70
|
+
| `browser.websocket.message.count` | Counter | - | `server.address`、`url.scheme`、`websocket.direction`(in/out) | websocket |
|
|
71
|
+
| `browser.websocket.message.bytes` | Counter | `By` | 同上 | websocket |
|
|
72
|
+
| `browser.websocket.error.count` | Counter | - | `server.address`、`url.scheme`、`websocket.error.phase`(connect/runtime) | websocket |
|
|
73
|
+
| `browser.websocket.connect.duration` | Histogram | `ms` | `server.address`、`url.scheme` | websocket,仅成功建连 |
|
|
74
|
+
|
|
75
|
+
> 各 metric 还会合并 `attributes.metric` hook 返回的自定义低基数维度;具体附加的公共维度(如 `attributes.page`)因插件而异。**metric 维度务必保持低基数**,不要把 URL、订单号、用户输入等放进来。
|
|
76
|
+
|
|
77
|
+
## Log 事件清单
|
|
78
|
+
|
|
79
|
+
| body | severity | 来源 | 关键属性 |
|
|
80
|
+
| --- | --- | --- | --- |
|
|
81
|
+
| `session.start` | INFO | session 插件(首次新建) | `session.id`、`session.start_time`、`session.rotate.reason=init` |
|
|
82
|
+
| `session.rotate` | INFO | session 插件(轮换) | + `session.previous_id`、`session.rotate.reason`(`inactivity` / `maxLifetime`) |
|
|
83
|
+
| `HTTP request completed` | INFO | httpBody 插件(成功请求) | `http.request.method`、`http.response.status_code`、`url.full`、`http.duration` |
|
|
84
|
+
| `HTTP request completed with error` | ERROR | httpBody 插件(错误路径) | + `http.request.body`、`http.response.body`、`http_body.request.truncated`、`http_body.response.truncated`、`exception.*` |
|
|
85
|
+
| `websocket.error` | ERROR | websocket 插件 | `url.full`、`websocket.error.phase`、`websocket.error.window_count` |
|
|
86
|
+
| `websocket.close` | INFO | websocket 插件 | `websocket.close.code`、`websocket.close.reason`、`websocket.close.was_clean` |
|
|
87
|
+
|
|
88
|
+
> 错误主数据统一走 `error` span(见 Span 清单),SDK **不再**为同一个错误额外 emit error log,避免重复计数。
|
|
89
|
+
|
|
90
|
+
## 属性字典
|
|
91
|
+
|
|
92
|
+
### 归一字段
|
|
93
|
+
|
|
94
|
+
由 `buildRumSpanAttributes` 等构造器写入,用于跨事件类型统一检索。
|
|
95
|
+
|
|
96
|
+
| key | 类型 | 说明 | 低基数 |
|
|
97
|
+
| --- | --- | --- | --- |
|
|
98
|
+
| `span_type` | string | `document`/`http`/`resource`/`vital`/`error`/`longtask`/`action`/`route`/`custom` | 是 |
|
|
99
|
+
| `span_subtype` | string | 子类型,如 `fetch`/`xhr`/`js`/`promise`/`lcp` | 是 |
|
|
100
|
+
| `result` | string | `success`/`warning`/`error`/`timeout`/`abort` | 是 |
|
|
101
|
+
| `error_type` | string | 错误细分,如 `http_5xx`/`network_timeout`/`slow`/`none` | 是 |
|
|
102
|
+
| `duration_bucket` | string | `<100ms`/`100~500ms`/`500ms~2s`/`>2s` | 是 |
|
|
103
|
+
| `event_label` | string | 中文事件标签,如 `API 调用`/`错误` | 是 |
|
|
104
|
+
| `target_label` | string | 跨类型主标签,用于统一检索 | 中 |
|
|
105
|
+
| `target_value` | number/string/bool | 主数值(状态码、耗时、字节数等) | 否 |
|
|
106
|
+
| `target_domain` | string | 目标域名 | 中 |
|
|
107
|
+
| `target_path_template` | string | 目标低基数路径模板 | 是 |
|
|
108
|
+
| `status_class` | string | HTTP 状态段,如 `2xx`/`5xx` | 是 |
|
|
109
|
+
| `trace_scene` | string | `page_load` / `route_change` | 是 |
|
|
110
|
+
|
|
111
|
+
### HTTP / Resource
|
|
112
|
+
|
|
113
|
+
| key | 类型 | 说明 |
|
|
114
|
+
| --- | --- | --- |
|
|
115
|
+
| `http.request.method` | string | 请求方法(大写) |
|
|
116
|
+
| `http.response.status_code` | number | 响应状态码 |
|
|
117
|
+
| `url.full` | string | 完整 URL(已脱敏) |
|
|
118
|
+
| `url.previous` | string | 跳转前 URL |
|
|
119
|
+
| `transfer_size` | number | 传输字节数 |
|
|
120
|
+
| `cache_hit` | boolean | 是否命中缓存 |
|
|
121
|
+
| `next_hop_protocol` | string | 协议,如 `h2` |
|
|
122
|
+
| `initiator_type` | string | 资源发起类型 |
|
|
123
|
+
| `resource.encoded_body_size` / `resource.decoded_body_size` | number | 资源体积 |
|
|
124
|
+
| `http.duration` | number | httpBody 插件记录的请求耗时(ms) |
|
|
125
|
+
| `http.request.body` / `http.response.body` | string | 仅 httpBody 错误路径,经 `redact` 脱敏 |
|
|
126
|
+
| `http_body.request.truncated` / `http_body.response.truncated` | boolean | body 是否被截断 |
|
|
127
|
+
|
|
128
|
+
### Web Vitals
|
|
129
|
+
|
|
130
|
+
| key | 类型 | 说明 |
|
|
131
|
+
| --- | --- | --- |
|
|
132
|
+
| `vital.metric` | string | `cls`/`fcp`/`inp`/`lcp`/`ttfb` |
|
|
133
|
+
| `vital.value` | number | 指标值 |
|
|
134
|
+
| `vital.rating` | string | `good`/`needs-improvement`/`poor` |
|
|
135
|
+
| `vital.id` | string | 单条度量唯一 ID(仅 span) |
|
|
136
|
+
| `rum.navigation.type` | string | 导航类型,含 `back-forward-cache` 等 |
|
|
137
|
+
| `vital.lcp.*` / `vital.cls.*` / `vital.inp.*` / `vital.fcp.*` / `vital.ttfb.*` | mixed | attribution 归因明细(仅 span) |
|
|
138
|
+
|
|
139
|
+
### 错误 / 异常
|
|
140
|
+
|
|
141
|
+
| key | 类型 | 说明 |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| `exception.type` | string | 异常类型/名称 |
|
|
144
|
+
| `exception.message` | string | 异常消息 |
|
|
145
|
+
| `exception.message_short` | string | 消息前 80 字符 |
|
|
146
|
+
| `exception.stacktrace` | string | 堆栈 |
|
|
147
|
+
| `exception.stack_top_frame` | string | 栈顶帧 |
|
|
148
|
+
| `exception.fingerprint` | string | 节流分组指纹(djb2 hash) |
|
|
149
|
+
| `error.source` | string | `window.error`/`unhandledrejection`/`resource`/`csp` |
|
|
150
|
+
| `error.handled` | boolean | 是否被业务捕获(自动采集恒为 `false`) |
|
|
151
|
+
| `error.window_count` | number | 当前节流窗口内同指纹总触发次数 |
|
|
152
|
+
| `error.cross_origin` | boolean | 跨域脚本错误(`Script error.`) |
|
|
153
|
+
| `code.filepath` / `code.lineno` / `code.column` | string/number | JS 错误位置 |
|
|
154
|
+
| `html.tag` | string | 资源错误的元素标签 |
|
|
155
|
+
|
|
156
|
+
### 设备 / 浏览器 / 网络
|
|
157
|
+
|
|
158
|
+
| key | 类型 | 说明 |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| `device.id` | string | 设备终身标识(localStorage 持久) |
|
|
161
|
+
| `device.memory` / `device.cpu_cores` | number | 硬件能力 |
|
|
162
|
+
| `device.platform` / `device.mobile` | string/bool | UA-CH 平台信息 |
|
|
163
|
+
| `browser.viewport.width` / `browser.viewport.height` | number | 视口尺寸 |
|
|
164
|
+
| `browser.screen.width` / `browser.screen.height` | number | 屏幕尺寸 |
|
|
165
|
+
| `network.connection_type` / `network.downlink` / `network.rtt` / `network.save_data` | mixed | 网络信息 |
|
|
166
|
+
| `user_agent.name` / `user_agent.version` / `user_agent.os.name` | string | UA 解析结果 |
|
|
167
|
+
|
|
168
|
+
### 用户动作 / 会话
|
|
169
|
+
|
|
170
|
+
| key | 类型 | 说明 |
|
|
171
|
+
| --- | --- | --- |
|
|
172
|
+
| `action.type` | string | 动作类型 |
|
|
173
|
+
| `target.tag` | string | 目标元素标签 |
|
|
174
|
+
| `target.text_short` | string | 目标文本前 32 字符 |
|
|
175
|
+
| `session.start_time` | number | 会话开始时间戳 |
|
|
176
|
+
| `session.previous_id` | string | 轮换前的 session.id |
|
|
177
|
+
| `session.rotate.reason` | string | `init`/`inactivity`/`maxLifetime` |
|
|
178
|
+
|
|
179
|
+
### Long Task
|
|
180
|
+
|
|
181
|
+
| key | 类型 | 说明 |
|
|
182
|
+
| --- | --- | --- |
|
|
183
|
+
| `longtask.blocking_duration` | number | 长任务时长(ms) |
|
|
184
|
+
| `longtask.attribution_script` | string | 归因脚本 |
|
|
185
|
+
|
|
186
|
+
### CSP
|
|
187
|
+
|
|
188
|
+
| key | 类型 | 说明 |
|
|
189
|
+
| --- | --- | --- |
|
|
190
|
+
| `csp.blocked_uri` | string | 被拦截资源(URL 类值已脱敏) |
|
|
191
|
+
| `csp.violated_directive` / `csp.effective_directive` | string | 违反的指令 |
|
|
192
|
+
| `csp.disposition` | string | `enforce` / `report` |
|
|
193
|
+
| `csp.source_file` | string | 触发脚本(已脱敏) |
|
|
194
|
+
| `csp.line_number` / `csp.column_number` | number | 位置 |
|
|
195
|
+
| `csp.status_code` | number | 状态码 |
|
|
196
|
+
| `csp.fingerprint` / `csp.window_count` | string/number | 节流指纹与窗口内触发次数 |
|
|
197
|
+
| `csp.original_policy` | string | 完整策略,仅窗口首条携带 |
|
|
198
|
+
|
|
199
|
+
### WebSocket
|
|
200
|
+
|
|
201
|
+
| key | 类型 | 说明 |
|
|
202
|
+
| --- | --- | --- |
|
|
203
|
+
| `url.scheme` | string | `ws` / `wss` |
|
|
204
|
+
| `server.address` | string | 目标 host |
|
|
205
|
+
| `network.protocol.name` | string | 固定 `websocket` |
|
|
206
|
+
| `websocket.direction` | string | `in` / `out`(仅 metric) |
|
|
207
|
+
| `websocket.error.phase` | string | `connect` / `runtime` |
|
|
208
|
+
| `websocket.error.window_count` | number | 错误日志节流窗口内触发次数 |
|
|
209
|
+
| `websocket.close.code` / `websocket.close.reason` / `websocket.close.was_clean` | mixed | 关闭事件详情 |
|
|
210
|
+
|
|
211
|
+
### 白屏
|
|
212
|
+
|
|
213
|
+
| key | 类型 | 说明 |
|
|
214
|
+
| --- | --- | --- |
|
|
215
|
+
| `blank_screen.score` | number | 空白样本比例 |
|
|
216
|
+
| `blank_screen.threshold` | number | 判定阈值 |
|
|
217
|
+
| `blank_screen.detected` | boolean | 是否判为白屏 |
|
|
218
|
+
| `blank_screen.root` | string | 采样根选择器 |
|
|
219
|
+
| `blank_screen.sample_total` / `blank_screen.sample_valid` / `blank_screen.sample_loading` | number | 采样统计 |
|
|
220
|
+
| `blank_screen.center_element` | string | 视口中心元素选择器 |
|
|
221
|
+
| `blank_screen.dom_node_count` | number | body 下 DOM 节点总数 |
|
|
222
|
+
|
|
223
|
+
### 自定义事件
|
|
224
|
+
|
|
225
|
+
| key | 类型 | 说明 |
|
|
226
|
+
| --- | --- | --- |
|
|
227
|
+
| `rum.custom.name` | string | `reportCustomEvent()` 的事件名 |
|
|
228
|
+
| `rum.page.host` / `rum.page.path` | string | 默认 `attributes.page` 注入的页面上下文 |
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
<!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
|
|
2
|
+
|
|
3
|
+
# 调试与排障
|
|
4
|
+
|
|
5
|
+
本页按接入阶段常见问题组织。
|
|
6
|
+
|
|
7
|
+
## 本地看不到数据
|
|
8
|
+
|
|
9
|
+
先打开 debug,并使用 simple span processor。
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
new BkOpenTelemetry({
|
|
13
|
+
debug: true,
|
|
14
|
+
spanProcessor: 'simple',
|
|
15
|
+
sampling: {
|
|
16
|
+
rate: 1,
|
|
17
|
+
},
|
|
18
|
+
transport: {
|
|
19
|
+
endpoint: 'http://localhost:4318',
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
检查点:
|
|
25
|
+
|
|
26
|
+
- Collector 是否监听 `4318`。
|
|
27
|
+
- 浏览器 Network 中是否有 `/v1/traces`、`/v1/metrics`、`/v1/logs` 请求。
|
|
28
|
+
- 是否被采样丢弃。
|
|
29
|
+
- `enabled` 是否为 `false`。
|
|
30
|
+
|
|
31
|
+
## 手动事件没有上报
|
|
32
|
+
|
|
33
|
+
`reportAction()` 和 `reportCustomEvent()` 受采样控制。未采样时会静默丢弃。
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
new BkOpenTelemetry({
|
|
37
|
+
debug: true,
|
|
38
|
+
sampling: {
|
|
39
|
+
rate: 1,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 自定义插件注册失败
|
|
45
|
+
|
|
46
|
+
`use()` 必须在 `start()` 前调用。如果需要注册插件,关闭自动启动。
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
const bkOT = new BkOpenTelemetry({
|
|
50
|
+
autoStart: false,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
bkOT.use(myPlugin);
|
|
54
|
+
|
|
55
|
+
await bkOT.start();
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 空白屏误报
|
|
59
|
+
|
|
60
|
+
SPA 应用应配置 `rootSelector` 和 loading/skeleton 忽略选择器。
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
new BkOpenTelemetry({
|
|
64
|
+
plugins: {
|
|
65
|
+
blankScreen: {
|
|
66
|
+
rootSelector: '#app',
|
|
67
|
+
ignoreSelectors: ['.bk-loading', '.skeleton'],
|
|
68
|
+
checkDelay: 5000,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 接口 span 太多
|
|
75
|
+
|
|
76
|
+
先确认是否有多个 SDK 实例重复初始化,尤其是微前端场景。其次可以关闭不需要的 instrumentation。
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
new BkOpenTelemetry({
|
|
80
|
+
instrumentations: {
|
|
81
|
+
fetch: true,
|
|
82
|
+
xhr: false,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## URL 或用户信息泄露风险
|
|
88
|
+
|
|
89
|
+
配置 URL 和属性脱敏。
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
new BkOpenTelemetry({
|
|
93
|
+
privacy: {
|
|
94
|
+
redactUrl: url => url.replace(/([?&]token=)[^&]+/g, '$1***'),
|
|
95
|
+
redactAttributes: attributes => {
|
|
96
|
+
const next = { ...attributes };
|
|
97
|
+
delete next['user.email'];
|
|
98
|
+
return next;
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Long Task 没有数据
|
|
105
|
+
|
|
106
|
+
Long Task API 并非所有浏览器都支持。Firefox 不支持时插件会跳过。
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
new BkOpenTelemetry({
|
|
110
|
+
plugins: {
|
|
111
|
+
longTask: {
|
|
112
|
+
threshold: 50,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## HTTP body 没有数据
|
|
119
|
+
|
|
120
|
+
`httpBody` 只在错误路径采集,且默认关闭。
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
new BkOpenTelemetry({
|
|
124
|
+
plugins: {
|
|
125
|
+
httpBody: {
|
|
126
|
+
maxBodySize: 4096,
|
|
127
|
+
redact: ({ body }) => body,
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## WebSocket 采集异常
|
|
134
|
+
|
|
135
|
+
WebSocket 插件会 Proxy 全局 `WebSocket`。如果应用或第三方库也 patch 了 WebSocket,应避免重复 patch。
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
new BkOpenTelemetry({
|
|
139
|
+
plugins: {
|
|
140
|
+
websocket: true,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
# FAQ
|
|
146
|
+
|
|
147
|
+
## SDK 会采集哪些数据?
|
|
148
|
+
|
|
149
|
+
默认采集页面访问、资源加载、fetch/xhr、JavaScript 错误、Web Vitals、空白屏、设备信息和会话信息。动作、HTTP body、Long Task、路由耗时、CSP、WebSocket 默认关闭。
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
new BkOpenTelemetry({
|
|
153
|
+
plugins: {
|
|
154
|
+
action: true,
|
|
155
|
+
longTask: true,
|
|
156
|
+
routeTiming: true,
|
|
157
|
+
websocket: true,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## `user.id` 会被 SDK 脱敏吗?
|
|
163
|
+
|
|
164
|
+
不会。`user.id` 由接入方提供,SDK 原样透传。如果业务要求 hash,需要在传入前处理。
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
new BkOpenTelemetry({
|
|
168
|
+
user: {
|
|
169
|
+
id: hashUserId(rawUserId),
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## `sampling.rate` 是 trace 级采样吗?
|
|
175
|
+
|
|
176
|
+
不是。它是会话级 sticky 采样,同一会话内保持一致。
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
new BkOpenTelemetry({
|
|
180
|
+
sampling: {
|
|
181
|
+
rate: 0.2,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 为什么开启了 userInteraction 还需要 action 插件?
|
|
187
|
+
|
|
188
|
+
`userInteraction` 是 OpenTelemetry 官方 instrumentation,产生的是官方用户交互 span;`action` 插件和 `reportAction()` 会写入 SDK 的 RUM action 归一字段。需要稳定的业务动作模型时,推荐使用 `action` 或 `reportAction()`。
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
bkOT.reportAction({
|
|
192
|
+
type: 'click',
|
|
193
|
+
targetText: '确认提交',
|
|
194
|
+
attributes: {
|
|
195
|
+
'biz.scene': 'strategy-create',
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## 可以只上报 traces,不上报 metrics/logs 吗?
|
|
201
|
+
|
|
202
|
+
当前 SDK 会初始化三类 provider。可以在 Collector 或网关层按信号丢弃,也可以为不同信号配置不同 endpoint。
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
new BkOpenTelemetry({
|
|
206
|
+
transport: {
|
|
207
|
+
signals: {
|
|
208
|
+
endpoints: {
|
|
209
|
+
traces: 'https://trace-gateway.example.com/v1/traces',
|
|
210
|
+
metrics: 'https://metric-gateway.example.com/v1/metrics',
|
|
211
|
+
logs: 'https://log-gateway.example.com/v1/logs',
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## 为什么不建议多个实例同时运行?
|
|
219
|
+
|
|
220
|
+
fetch、xhr、userInteraction、websocket 等能力会 patch 全局 API。多个实例可能重复 patch、重复上报或互相影响。
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
if (!window.__BK_RUM_INSTANCE__) {
|
|
224
|
+
window.__BK_RUM_INSTANCE__ = new BkOpenTelemetry({
|
|
225
|
+
transport: {
|
|
226
|
+
endpoint: 'https://rum-collector.example.com',
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## 如何在页面离开前尽量 flush?
|
|
233
|
+
|
|
234
|
+
SDK 已监听部分页面生命周期事件。业务也可以在关键流程后主动调用 `flush()`。
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
await saveCriticalConfig();
|
|
238
|
+
await bkOT.flush();
|
|
239
|
+
```
|