@blueking/open-telemetry 0.0.21 → 0.0.22
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 +10 -48
- 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/runtime-context.d.ts +1 -1
- package/dist/core/sdk.d.ts +2 -8
- package/dist/core/telemetry-attributes.d.ts +1 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1074 -1484
- 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/device.d.ts +2 -2
- package/dist/plugins/error.d.ts +1 -5
- package/dist/plugins/long-task.d.ts +1 -3
- package/dist/plugins/resource.d.ts +1 -0
- package/dist/plugins/web-vitals.d.ts +2 -7
- 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 +12 -14
- 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 +28 -69
- 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 +4 -7
- package/skills/bk-rum-otele/references/plugins-experience.md +8 -9
- 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,285 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
# 遥测参考
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
| `browser.name` / `browser.version` | Resource | string | 归一化浏览器信息 | 是 |
|
|
27
|
-
| `os.name` | Resource | string | 操作系统 | 是 |
|
|
28
|
-
| `device.memory_gib` | Resource | number | 浏览器暴露的近似设备内存(GiB) | 是 |
|
|
29
|
-
| `device.logical_processor_count` | Resource | number | 浏览器暴露的逻辑处理器数量 | 是 |
|
|
30
|
-
| `user.id` | Runtime | string | 接入方提供,原样透传 | 否 |
|
|
31
|
-
| `session.id` | Runtime | string | session 插件生成/轮换 | 否 |
|
|
32
|
-
| `session.has_replay` | Runtime | boolean | 当前固定 `false` | 是 |
|
|
33
|
-
| `view.id` | Runtime | string | View 管理器生成的实例 ID | 否 |
|
|
34
|
-
| `view.name` | Runtime | string | 自动模式默认使用路由分组;手动模式可指定 | 是 |
|
|
35
|
-
| `view.url` | Runtime | string | 当前 view URL(已脱敏) | 否 |
|
|
36
|
-
| `view.url_path_group` | Runtime | string | 低基数路由模板 | 是 |
|
|
37
|
-
| `view.loading_type` | Runtime | string | `initial_load` / `route_change` / `session_renewal` / `bf_cache` | 是 |
|
|
38
|
-
| `device.id` | Runtime | string | 当前实例或持久化匿名设备 ID | 否 |
|
|
39
|
-
| `network.effective_type` | Runtime | string | 网络质量(`4g` 等) | 是 |
|
|
40
|
-
|
|
41
|
-
> span 还会带上 `span_type` / `span_subtype` / `result` / `error_type` 等归一字段(见下方[归一字段](#归一字段))。接入方可通过 `context.attributes.page` 注入额外的页面属性。
|
|
5
|
+
SDK 只产出 RUM Span,不产出 OpenTelemetry Metric 或 Log。计数、直方图、分位数和错误分组由服务端从原始 Span 派生。
|
|
6
|
+
|
|
7
|
+
## 公共字段
|
|
8
|
+
|
|
9
|
+
| 字段 | 类型 | 说明 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `event.id` | string | 每条原始事件的唯一 ID,服务端去重键 |
|
|
12
|
+
| `event.type` | string | `session`、`view`、`resource`、`error`、`vital`、`action`、`websocket` 等 |
|
|
13
|
+
| `event.phase` | string | 生命周期事件阶段;非生命周期事件可不带 |
|
|
14
|
+
| `event.timestamp` | number | 浏览器事件发生的 epoch ms |
|
|
15
|
+
| `session.id` | string | Session 关联 ID |
|
|
16
|
+
| `session.start_time` | number | Session 开始时间 |
|
|
17
|
+
| `session.type` | string | 当前为 `user` |
|
|
18
|
+
| `session.sample_rate` | number | Resource 字段,范围 `0..1` |
|
|
19
|
+
| `view.id` | string | View 关联 ID |
|
|
20
|
+
| `view.name` | string | View 名称 |
|
|
21
|
+
| `view.url` | string | 脱敏后的 URL |
|
|
22
|
+
| `view.url_path_group` | string | 服务端聚合用路由模板 |
|
|
23
|
+
| `action.id` | string/string[] | Action 关联 ID |
|
|
24
|
+
| `span_type` / `span_subtype` | string | RUM 分类 |
|
|
25
|
+
| `result` / `error_type` | string | 单事件结果分类 |
|
|
42
26
|
|
|
43
27
|
## Span 清单
|
|
44
28
|
|
|
45
|
-
|
|
|
46
|
-
| --- | --- | --- |
|
|
47
|
-
| `browser.
|
|
48
|
-
| `browser.
|
|
49
|
-
| `browser.resource` | `resource` |
|
|
50
|
-
| `browser.
|
|
51
|
-
| `browser.
|
|
52
|
-
| `browser.
|
|
53
|
-
| `browser.
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
| `browser.long_task.blocking_duration` | Histogram | `ms` | 同上 | longTask,仅 LoAF |
|
|
74
|
-
| `browser.websocket.message.count` | Counter | - | `server.address`、`server.port`、`url.scheme`、`websocket.direction`(in/out) | websocket |
|
|
75
|
-
| `browser.websocket.message.bytes` | Counter | `By` | 同上 | websocket |
|
|
76
|
-
| `browser.websocket.error.count` | Counter | - | `server.address`、`server.port`、`url.scheme`、`websocket.error.phase`(connect/runtime) | websocket |
|
|
77
|
-
| `browser.websocket.connect.duration` | Histogram | `ms` | `server.address`、`server.port`、`url.scheme` | websocket,仅成功建连 |
|
|
78
|
-
|
|
79
|
-
> 各 metric 只会合并 `context.attributes.metric` hook 返回的自定义低基数维度,不会合并 `context.attributes.page`,也不会携带 `session.id`、`view.id` 或 `action.id`。`view.url_path_group` 中明显的数字 ID、UUID、长十六进制段会归一为 `:id`。精确 View 关联请查询对应 span 或 View Snapshot Log。**metric 维度务必保持低基数**,不要把 URL、订单号、用户输入等放进来。
|
|
80
|
-
|
|
81
|
-
## Log 事件清单
|
|
82
|
-
|
|
83
|
-
| eventName / body | severity | 来源 | 关键属性 |
|
|
84
|
-
| --- | --- | --- | --- |
|
|
85
|
-
| `session.start` | INFO | session 插件(首次新建) | `session.id`、`session.start_time`、`session.rotate.reason=init` |
|
|
86
|
-
| `session.rotate` | INFO | session 插件(轮换) | + `session.previous_id`、`session.rotate.reason`(`inactivity` / `maxLifetime`) |
|
|
87
|
-
| `browser.view` | INFO | View 管理器 | `view.snapshot.type=create\|update\|final`、`view.document_version`、`view.duration`、`view.is_active`、`view.loading_time` |
|
|
88
|
-
| `browser.request.body` | ERROR(错误请求)/ INFO(`capture: 'all'` 的成功请求) | Fetch/XHR request patch(仅显式配置 `request.body`) | 通过 OTel Log Context 关联 Trace/Span;属性含 `request.body` / `response.body`、`*.body.content_type`、`*.body.truncated` |
|
|
89
|
-
| `websocket.error` | ERROR | websocket 插件 | `url.full`、`websocket.error.phase`、`websocket.error.window_occurrence_index` |
|
|
90
|
-
| `websocket.close` | INFO | websocket 插件 | `websocket.close.code`、`websocket.close.reason`、`websocket.close.was_clean` |
|
|
91
|
-
|
|
92
|
-
> 内置 Log 的 `eventName` 与 `body` 当前使用同一个事件名;查询与 `tracking.beforeSend` 应优先使用 `eventName`。
|
|
93
|
-
|
|
94
|
-
> 错误主数据统一走 `error` span(见 Span 清单),SDK **不再**为同一个错误额外 emit error log,避免重复计数。
|
|
95
|
-
|
|
96
|
-
## 属性字典
|
|
97
|
-
|
|
98
|
-
### 归一字段
|
|
99
|
-
|
|
100
|
-
由 `buildRumSpanAttributes` 等构造器写入,用于跨事件类型统一检索。
|
|
101
|
-
|
|
102
|
-
| key | 类型 | 说明 | 低基数 |
|
|
103
|
-
| --- | --- | --- | --- |
|
|
104
|
-
| `span_type` | string | `document`/`resource`/`vital`/`error`/`longtask`/`action`/`route`/`custom` | 是 |
|
|
105
|
-
| `span_subtype` | string | 子类型,如 `fetch`/`xhr`/`js`/`promise`/`lcp` | 是 |
|
|
106
|
-
| `result` | string | `success`/`warning`/`error`/`timeout`/`abort` | 是 |
|
|
107
|
-
| `error_type` | string | 错误细分,如 `http_5xx`/`network_timeout`/`slow`/`none` | 是 |
|
|
108
|
-
|
|
109
|
-
### View / Navigation
|
|
110
|
-
|
|
111
|
-
| key | 类型 | 出现位置 | 说明 |
|
|
112
|
-
| --- | --- | --- | --- |
|
|
113
|
-
| `view.id` / `view.name` / `view.url` / `view.url_path_group` | string | Span / Log | View 标识、名称、脱敏 URL 与低基数路由模板 |
|
|
114
|
-
| `view.loading_type` | string | Span / Log / Metric | `initial_load` / `route_change` / `session_renewal` / `bf_cache` |
|
|
115
|
-
| `view.loading_time` | number | Span / Log;同时作为 Metric 值 | View 从开始到页面活动稳定的耗时(ms) |
|
|
116
|
-
| `view.loading_time.source` | string | Span / Log | `auto` / `manual` |
|
|
117
|
-
| `view.first_byte` | number | 初始 View Span / Log | Navigation Timing 的 `responseStart`(相对 `performance.timeOrigin`,ms) |
|
|
118
|
-
| `view.dom_interactive` / `view.dom_content_loaded` | number | 初始 View Span / Log | DOM interactive / DOMContentLoaded 时间(相对 `performance.timeOrigin`,ms) |
|
|
119
|
-
| `view.dom_complete` / `view.load_event` | number | 初始 View Span / Log | DOM complete / load event 时间(相对 `performance.timeOrigin`,ms) |
|
|
120
|
-
| `url.previous` | string | Span / Log | 前一个 View URL(已脱敏) |
|
|
121
|
-
| `document.referrer` | string | 初始 View Span / Log | 页面 referrer(已脱敏) |
|
|
122
|
-
| `event.source` | string | Span / Log | View 创建触发源,如 `load`、`pushState`、`popstate`、`manual`、`bfCache`、`sessionRenewal` |
|
|
123
|
-
| `view.end_reason` | string | Span / final Log | 下一 View 的触发源,或 `pagehide` / `session_expired` / `shutdown` |
|
|
124
|
-
| `event.type` | string | Log | 固定 `view` |
|
|
125
|
-
| `view.snapshot.type` | string | Log | `create` / `update` / `final` |
|
|
126
|
-
| `view.document_version` | number | Log | 当前 View Snapshot 的递增版本号 |
|
|
127
|
-
| `view.duration` | number | Log | 从 View 开始到 Snapshot 的耗时(ms) |
|
|
128
|
-
| `view.is_active` | boolean | Log | 非 final Snapshot 为 `true` |
|
|
129
|
-
|
|
130
|
-
### HTTP / Resource
|
|
131
|
-
|
|
132
|
-
| key | 类型 | 说明 |
|
|
133
|
-
| --- | --- | --- |
|
|
134
|
-
| `http.request.method` | string | 请求方法(大写) |
|
|
135
|
-
| `http.response.status_code` | number | 响应状态码 |
|
|
136
|
-
| `url.full` | string | 完整 URL(已脱敏) |
|
|
137
|
-
| `server.address` | string | 目标主机名 |
|
|
138
|
-
| `server.port` | number | 目标显式端口(存在时) |
|
|
139
|
-
| `resource.type` | string | `fetch`/`xhr` 或静态资源 initiator type |
|
|
140
|
-
| `resource.redirect.start/duration` | number | 重定向阶段相对开始时间 / 耗时(ms) |
|
|
141
|
-
| `resource.dns.start/duration` | number | DNS 阶段相对开始时间 / 耗时(ms) |
|
|
142
|
-
| `resource.connect.start/duration` | number | TCP 建连阶段相对开始时间 / 耗时(ms) |
|
|
143
|
-
| `resource.ssl.start/duration` | number | TLS 握手阶段相对开始时间 / 耗时(ms) |
|
|
144
|
-
| `resource.first_byte.start/duration` | number | 等待首字节阶段相对开始时间 / 耗时(ms) |
|
|
145
|
-
| `resource.download.start/duration` | number | 响应下载阶段相对开始时间 / 耗时(ms) |
|
|
146
|
-
| `resource.worker.start/duration` | number | Service Worker 阶段相对开始时间 / 耗时(ms) |
|
|
147
|
-
| `resource.delivery_type` | string | `cache` / `navigational-prefetch` 等浏览器交付类型 |
|
|
148
|
-
| `resource.render_blocking_status` | string | `blocking` / `non-blocking` |
|
|
149
|
-
| `resource.size` | number | 传输字节数 |
|
|
150
|
-
| `url.previous` | string | 跳转前 URL |
|
|
151
|
-
| `resource.cache.hit` | boolean | 是否命中缓存 |
|
|
152
|
-
| `resource.protocol` | string | 协议,如 `h2` |
|
|
153
|
-
| `resource.encoded_body_size` / `resource.decoded_body_size` | number | 资源体积 |
|
|
154
|
-
| `request.body` / `response.body` | string | 仅 `browser.request.body` Log;经过接入方 `redact` 且受长度限制 |
|
|
155
|
-
| `request.body.content_type` / `response.body.content_type` | string | body Content-Type(可获取时) |
|
|
156
|
-
| `request.body.truncated` / `response.body.truncated` | boolean | body 是否因长度限制而截断 |
|
|
157
|
-
|
|
158
|
-
### Web Vitals
|
|
159
|
-
|
|
160
|
-
| key | 类型 | 说明 |
|
|
161
|
-
| --- | --- | --- |
|
|
162
|
-
| `vital.metric` | string | `cls`/`fcp`/`inp`/`lcp`/`ttfb` |
|
|
163
|
-
| `vital.value` | number | 指标值 |
|
|
164
|
-
| `vital.rating` | string | `good`/`needs-improvement`/`poor` |
|
|
165
|
-
| `vital.id` | string | 单条度量唯一 ID(仅 span) |
|
|
166
|
-
| `rum.navigation.type` | string | 导航类型,含 `back-forward-cache` 等 |
|
|
167
|
-
| `vital.lcp.*` / `vital.cls.*` / `vital.inp.*` / `vital.fcp.*` / `vital.ttfb.*` | mixed | attribution 归因明细(仅 span) |
|
|
168
|
-
|
|
169
|
-
### 错误 / 异常
|
|
170
|
-
|
|
171
|
-
以下字段位于 Error Span 顶层属性:
|
|
172
|
-
|
|
173
|
-
| key | 类型 | 说明 |
|
|
174
|
-
| --- | --- | --- |
|
|
175
|
-
| `exception.message_short` | string | 消息前 80 字符 |
|
|
176
|
-
| `exception.stack_top_frame` | string | 栈顶帧 |
|
|
177
|
-
| `exception.fingerprint` | string | 节流分组指纹(djb2 hash) |
|
|
178
|
-
| `error.source` | string | `window.error`/`unhandledrejection`/`resource`/`csp` |
|
|
179
|
-
| `error.handled` | boolean | 是否被业务捕获(自动采集恒为 `false`) |
|
|
180
|
-
| `error.window_occurrence_index` | number | 当前节流窗口内该已上报 span 的触发序号;总量查询 `browser.error.count` |
|
|
181
|
-
| `error.cross_origin` | boolean | 跨域脚本错误(`Script error.`) |
|
|
182
|
-
| `code.filepath` / `code.lineno` / `code.column` | string/number | JS 错误位置 |
|
|
183
|
-
| `html.tag` | string | 资源错误的元素标签 |
|
|
184
|
-
|
|
185
|
-
`error.subtype` 仅作为 `browser.error.count` Metric 维度,取值为 `js` / `promise` / `resource_load`,不写入 Error Span 顶层属性。
|
|
186
|
-
|
|
187
|
-
完整异常由 `recordException()` 写入名为 `exception` 的标准 Span Event,不在 Span 顶层属性中:
|
|
188
|
-
|
|
189
|
-
| Event 属性 | 类型 | 说明 |
|
|
190
|
-
| --- | --- | --- |
|
|
191
|
-
| `exception.type` | string | 异常类型/名称 |
|
|
192
|
-
| `exception.message` | string | 异常消息 |
|
|
193
|
-
| `exception.stacktrace` | string | 堆栈(存在时) |
|
|
194
|
-
|
|
195
|
-
### 设备 / 浏览器 / 网络
|
|
196
|
-
|
|
197
|
-
| key | 类型 | 说明 |
|
|
198
|
-
| --- | --- | --- |
|
|
199
|
-
| `device.id` | string | 匿名设备标识;默认仅当前 SDK 实例稳定,`tracking.device.persistentId=true` 时持久化 |
|
|
200
|
-
| `device.memory_gib` | number | Resource 中的近似设备内存(GiB) |
|
|
201
|
-
| `device.logical_processor_count` | number | Resource 中的逻辑处理器数量 |
|
|
202
|
-
| `browser.viewport.width` / `browser.viewport.height` | number | 视口尺寸 |
|
|
203
|
-
| `browser.screen.width` / `browser.screen.height` | number | 屏幕尺寸 |
|
|
204
|
-
| `network.effective_type` | string | 网络质量,如 `4g` |
|
|
205
|
-
| `network.connection_type` / `network.downlink` / `network.rtt` / `network.save_data` | mixed | 网络信息 |
|
|
206
|
-
| `browser.name` / `browser.version` / `os.name` | string | Resource 中的 UA 解析结果 |
|
|
207
|
-
| `device.type` | string | Resource 中的 `mobile` / `desktop` |
|
|
208
|
-
|
|
209
|
-
### 用户动作 / 会话
|
|
210
|
-
|
|
211
|
-
| key | 类型 | 说明 |
|
|
212
|
-
| --- | --- | --- |
|
|
213
|
-
| `action.type` | string | 动作类型 |
|
|
214
|
-
| `action.id` | string / string[] | action 自身 ID;关联事件上为 action ID 数组 |
|
|
215
|
-
| `action.name` | string | 可读动作名称 |
|
|
216
|
-
| `action.target.name` | string | 自动 action 的目标元素名称 |
|
|
217
|
-
| `action.target.tag` | string | 自动 action 的目标元素标签 |
|
|
218
|
-
| `action.loading_time` | number | 点击后页面活动稳定耗时(ms) |
|
|
219
|
-
| `action.resource.count` | number | action 关联资源数 |
|
|
220
|
-
| `action.error.count` | number | action 关联错误数 |
|
|
221
|
-
| `action.long_task.count` | number | action 关联长任务数 |
|
|
222
|
-
| `action.frustration.type` | string[] | `rage_click` / `dead_click` / `error_click` |
|
|
223
|
-
| `action.frustration.count` | number | 当前 action 的挫败信号数量 |
|
|
224
|
-
| `session.start_time` | number | 会话开始时间戳 |
|
|
225
|
-
| `session.previous_id` | string | 轮换前的 session.id |
|
|
226
|
-
| `session.rotate.reason` | string | `init`/`inactivity`/`maxLifetime` |
|
|
227
|
-
|
|
228
|
-
### Long Task
|
|
229
|
-
|
|
230
|
-
| key | 类型 | 说明 |
|
|
231
|
-
| --- | --- | --- |
|
|
232
|
-
| `long_task.id` | string | 长任务或长动画帧 ID |
|
|
233
|
-
| `long_task.entry_type` | string | `long-animation-frame` / `long-task` |
|
|
234
|
-
| `long_task.start_time` | number | LoAF 相对 `performance.timeOrigin` 的开始时间(ms) |
|
|
235
|
-
| `long_task.duration` / `long_task.blocking_duration` | number | 总耗时 / 主线程阻塞耗时(ms) |
|
|
236
|
-
| `long_task.is_frozen_frame` | boolean | 总耗时是否达到 700ms |
|
|
237
|
-
| `long_task.culprit` | string | 最重脚本 URL、函数或 legacy attribution |
|
|
238
|
-
| `long_task.script.count` | number | LoAF 脚本数 |
|
|
239
|
-
| `long_task.first_ui_event_timestamp` | number | LoAF 首个 UI Event 时间戳 |
|
|
240
|
-
| `long_task.render_start` / `long_task.style_and_layout_start` | number | LoAF 渲染与样式布局阶段起点 |
|
|
241
|
-
| `long_task.culprit.*` | mixed | 最重脚本的耗时、强制布局耗时、函数名与 invoker 类型 |
|
|
242
|
-
| `long_task.script.*` | mixed | `long_task.script` Span Event 上的脚本耗时、URL、函数、invoker 和强制布局归因 |
|
|
243
|
-
|
|
244
|
-
### CSP
|
|
245
|
-
|
|
246
|
-
| key | 类型 | 说明 |
|
|
247
|
-
| --- | --- | --- |
|
|
248
|
-
| `csp.blocked_uri` | string | 被拦截资源(URL 类值已脱敏) |
|
|
249
|
-
| `csp.violated_directive` / `csp.effective_directive` | string | 违反的指令 |
|
|
250
|
-
| `csp.disposition` | string | `enforce` / `report` |
|
|
251
|
-
| `csp.source_file` | string | 触发脚本(已脱敏) |
|
|
252
|
-
| `csp.line_number` / `csp.column_number` | number | 位置 |
|
|
253
|
-
| `csp.status_code` | number | 状态码 |
|
|
254
|
-
| `csp.fingerprint` / `csp.window_occurrence_index` | string/number | 节流指纹与该已上报 span 的窗口触发序号 |
|
|
255
|
-
| `csp.original_policy` | string | 完整策略,仅窗口首条携带 |
|
|
256
|
-
|
|
257
|
-
### WebSocket
|
|
258
|
-
|
|
259
|
-
| key | 类型 | 说明 |
|
|
260
|
-
| --- | --- | --- |
|
|
261
|
-
| `url.scheme` | string | `ws` / `wss` |
|
|
262
|
-
| `server.address` | string | 目标 hostname,不包含端口 |
|
|
263
|
-
| `server.port` | number | 目标显式端口(存在时) |
|
|
264
|
-
| `network.protocol.name` | string | 固定 `websocket` |
|
|
265
|
-
| `websocket.direction` | string | `in` / `out`(仅 metric) |
|
|
266
|
-
| `websocket.error.phase` | string | `connect` / `runtime` |
|
|
267
|
-
| `websocket.error.window_occurrence_index` | number | 该已上报错误日志在节流窗口内的触发序号;总量查询 `browser.websocket.error.count` |
|
|
268
|
-
| `websocket.close.code` / `websocket.close.reason` / `websocket.close.was_clean` | mixed | 关闭事件详情 |
|
|
269
|
-
|
|
270
|
-
### 白屏
|
|
271
|
-
|
|
272
|
-
| key | 类型 | 说明 |
|
|
273
|
-
| --- | --- | --- |
|
|
274
|
-
| `blank_screen.empty_ratio` | number | 有效样本中的空白比例 |
|
|
275
|
-
| `blank_screen.reason` | string | `empty_viewport` / `missing_root` |
|
|
276
|
-
| `blank_screen.root_selector` / `blank_screen.root_found` | string/boolean | 根选择器与是否存在 |
|
|
277
|
-
| `blank_screen.sample_count` / `blank_screen.valid_sample_count` | number | 总样本数 / 有效样本数 |
|
|
278
|
-
| `blank_screen.empty_sample_count` / `blank_screen.ignored_sample_count` | number | 空白样本数 / loading 忽略样本数 |
|
|
279
|
-
| `blank_screen.center_element` | string | 视口中心元素选择器 |
|
|
280
|
-
|
|
281
|
-
### 自定义事件
|
|
282
|
-
|
|
283
|
-
| key | 类型 | 说明 |
|
|
284
|
-
| --- | --- | --- |
|
|
285
|
-
| `rum.custom.name` | string | `reportCustomEvent()` 的事件名 |
|
|
286
|
-
| `rum.page.host` / `rum.page.path` | string | 默认 `context.attributes.page` 页面上下文;配置自定义 page hook 后由接入方决定字段 |
|
|
29
|
+
| Span 名 | `event.type` | 关键字段 |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| `browser.session` | `session` | `event.phase=start\|rotate\|end`、`session.lifecycle.reason`、`session.previous_id` |
|
|
32
|
+
| `browser.view` | `view` | `event.phase=start\|update\|end`、`view.version`、`view.started_at`、`view.loading_type`、`view.loading_time`、`view.end_reason` |
|
|
33
|
+
| `browser.resource` | `resource` | `url.full`、`resource.type`、HTTP 状态、体积和 Resource Timing 阶段 |
|
|
34
|
+
| `browser.error` | `error` | `error.source=window.error`、`error.message`、代码位置;完整异常写入标准 exception event |
|
|
35
|
+
| `browser.unhandledrejection` | `error` | `error.source=unhandledrejection`、`error.message`、标准 exception event |
|
|
36
|
+
| `browser.resource_error` | `error` | `error.source=resource`、`url.full`、`html.tag` |
|
|
37
|
+
| `browser.web_vital` | `vital` | `vital.metric`、`vital.value`、`vital.rating`、`vital.id` 和 attribution |
|
|
38
|
+
| `action.click` | `action` | `action.loading_time`、目标和 `action.frustration.type`;不含资源/错误/长任务计数 |
|
|
39
|
+
| `action.custom` | `action` | 手动 Action 名称和属性 |
|
|
40
|
+
| `browser.blank_screen` | `error` | 白屏采样点、比例、根节点和原因 |
|
|
41
|
+
| `browser.long_task` | `long_task` | Long Task/LoAF 原始耗时;LoAF 脚本和旧 API attribution span event;仅 LoAF 带原生 blocking duration |
|
|
42
|
+
| `csp.violation` | `error` | CSP violation 原始字段;不做指纹或客户端节流 |
|
|
43
|
+
| `browser.websocket` | `websocket` | `event.phase=connect\|open\|error\|close`、`websocket.connection.id`、关闭码;不采集消息 |
|
|
44
|
+
| `custom.<name>` | `custom` | 手动自定义事件属性和可选异常 |
|
|
45
|
+
|
|
46
|
+
## View 本地语义
|
|
47
|
+
|
|
48
|
+
`view.loading_time`、CLS、INP、Action Loading Time、挫败信号和白屏必须依赖浏览器活动窗口或 DOM/Performance API,在 SDK 本地计算后作为事件语义上报。View 的每次 start/update/end 都增加 `view.version`;服务端应按 `view.id + view.version` 幂等合并,并容忍乱序到达。
|
|
49
|
+
|
|
50
|
+
## 服务端派生要求
|
|
51
|
+
|
|
52
|
+
- 使用 `event.id` 去重。
|
|
53
|
+
- 通过 `session.id`、`view.id`、`action.id` 关联事件。
|
|
54
|
+
- 从原始事件计算 View/Session 时长、资源/错误/Action 数量和错误率。
|
|
55
|
+
- 从 `vital.value`、资源/长任务耗时计算 Histogram 与分位数。
|
|
56
|
+
- 在服务端生成错误指纹、错误组和风暴控制,不在浏览器丢弃原始错误。
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# 传输与采样
|
|
4
4
|
|
|
5
|
-
## Endpoint
|
|
5
|
+
## 单一 Endpoint
|
|
6
6
|
|
|
7
|
-
`transport.endpoint`
|
|
7
|
+
`transport.endpoint` 是必填根地址,SDK 去掉末尾斜杠后拼接 `/v1/rum`。没有 `/v1/metrics`、`/v1/logs` 或独立信号开关。
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
new BkOpenTelemetry({
|
|
@@ -12,54 +12,20 @@ new BkOpenTelemetry({
|
|
|
12
12
|
transport: {
|
|
13
13
|
endpoint: 'https://collector.example.com',
|
|
14
14
|
token: 'report-token',
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
maxExportBatchSize: 512,
|
|
22
|
-
scheduledDelayMillis: 5000,
|
|
23
|
-
exportTimeoutMillis: 30000,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
metrics: { endpoint: 'https://metric.example.com/v1/metrics', intervalMillis: 60_000 },
|
|
27
|
-
logs: { endpoint: 'https://log.example.com/v1/logs' },
|
|
15
|
+
processor: 'batch',
|
|
16
|
+
batch: {
|
|
17
|
+
maxQueueSize: 2048,
|
|
18
|
+
maxExportBatchSize: 512,
|
|
19
|
+
scheduledDelayMillis: 5000,
|
|
20
|
+
exportTimeoutMillis: 30000,
|
|
28
21
|
},
|
|
22
|
+
timeoutMillis: 10_000,
|
|
23
|
+
concurrencyLimit: 10,
|
|
29
24
|
},
|
|
30
25
|
});
|
|
31
26
|
```
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
三类信号默认全部开启。设为 `false` 时,不创建对应 exporter、processor 或 metric reader:
|
|
36
|
-
|
|
37
|
-
```ts
|
|
38
|
-
new BkOpenTelemetry({
|
|
39
|
-
application: { name: 'trace-only-demo' },
|
|
40
|
-
transport: {
|
|
41
|
-
signals: {
|
|
42
|
-
traces: { endpoint: 'https://trace.example.com/v1/rum' },
|
|
43
|
-
metrics: false,
|
|
44
|
-
logs: false,
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
校验规则:
|
|
51
|
-
|
|
52
|
-
- 至少开启一种信号,三类不能全部为 `false`。
|
|
53
|
-
- 每个开启信号必须有独立 endpoint,或能回退到根 `transport.endpoint`。
|
|
54
|
-
- 关闭 Trace 后不记录 Span,也不会向 `allowedTracingUrls` 注入 `traceparent`。
|
|
55
|
-
- 关闭 Metric 后不启动周期导出定时器。
|
|
56
|
-
- 关闭 Log 不影响 Session/View 上下文维护,但不会产生 Session、View Snapshot、HTTP body 等 Log。
|
|
57
|
-
|
|
58
|
-
只开启 Metric 时没有精确 `view.id` 下钻链路;需要从指标定位具体 View 时,至少开启 Trace。
|
|
59
|
-
|
|
60
|
-
请求头优先级:`token` 生成的 Authorization < `transport.headers` < 单 signal `headers`。
|
|
61
|
-
|
|
62
|
-
浏览器 OTLP HTTP exporter 负责实际传输,SDK 在 `pagehide` 和页面进入 hidden 时触发 flush。`shutdown()` 会先结束 View 和插件,再 flush final Snapshot,最后关闭 provider。
|
|
28
|
+
`token` 生成默认 `Authorization: Bearer <token>`,显式 `headers` 可覆盖它。SDK 在 `pagehide` 和页面进入 hidden 时触发 flush。
|
|
63
29
|
|
|
64
30
|
## Session 级确定性采样
|
|
65
31
|
|
|
@@ -72,8 +38,7 @@ new BkOpenTelemetry({
|
|
|
72
38
|
```
|
|
73
39
|
|
|
74
40
|
- `1` 表示全量,`0` 表示全部丢弃。
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
Metric exporter 只接受带内部采样标记的数据点,并在传输前移除该标记。Metric 只保留低基数 `view.url_path_group`,精确 View 关联由 span/log/View Snapshot 的 `view.id` 提供。
|
|
41
|
+
- 采样由 `application.name + session.id` 的稳定 hash 决定。
|
|
42
|
+
- Session 轮换后使用新 ID 重新计算。
|
|
43
|
+
- `session.sample_rate` 写入 Resource,供后端做采样率修正。
|
|
44
|
+
- 未采样 Session 不创建可导出的 RUM Span。
|
|
@@ -17,9 +17,7 @@ new BkOpenTelemetry({
|
|
|
17
17
|
},
|
|
18
18
|
transport: {
|
|
19
19
|
endpoint: 'http://localhost:4318',
|
|
20
|
-
|
|
21
|
-
traces: { processor: 'simple' },
|
|
22
|
-
},
|
|
20
|
+
processor: 'simple',
|
|
23
21
|
},
|
|
24
22
|
});
|
|
25
23
|
```
|
|
@@ -27,7 +25,7 @@ new BkOpenTelemetry({
|
|
|
27
25
|
检查点:
|
|
28
26
|
|
|
29
27
|
- Collector 是否监听 `4318`。
|
|
30
|
-
- 浏览器 Network 中是否有 `/v1/rum
|
|
28
|
+
- 浏览器 Network 中是否有 `/v1/rum` 请求。
|
|
31
29
|
- 是否被采样丢弃。
|
|
32
30
|
- `enabled` 是否为 `false`。
|
|
33
31
|
|
|
@@ -131,28 +129,9 @@ new BkOpenTelemetry({
|
|
|
131
129
|
});
|
|
132
130
|
```
|
|
133
131
|
|
|
134
|
-
## HTTP
|
|
135
|
-
|
|
136
|
-
请求/响应 body 默认关闭。需要采集时配置 `tracking.request.body`,并提供必填的 `redact`:
|
|
137
|
-
|
|
138
|
-
```ts
|
|
139
|
-
new BkOpenTelemetry({
|
|
140
|
-
application: { name: 'rum-debug' },
|
|
141
|
-
transport: { endpoint: 'https://rum-collector.example.com' },
|
|
142
|
-
tracking: {
|
|
143
|
-
request: {
|
|
144
|
-
body: {
|
|
145
|
-
capture: 'errors',
|
|
146
|
-
allowedContentTypes: ['application/json'],
|
|
147
|
-
maxSize: 10 * 1024,
|
|
148
|
-
redact: ({ body }) => body.replace(/"password"\s*:\s*"[^"]+"/g, '"password":"***"'),
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
```
|
|
132
|
+
## HTTP Body 没有数据
|
|
154
133
|
|
|
155
|
-
|
|
134
|
+
这是预期行为:SDK 不读取或上报请求/响应 Body。
|
|
156
135
|
|
|
157
136
|
## WebSocket 采集异常
|
|
158
137
|
|
|
@@ -231,22 +210,16 @@ bkOT.reportAction({
|
|
|
231
210
|
|
|
232
211
|
## 可以只上报 traces,不上报 metrics/logs 吗?
|
|
233
212
|
|
|
234
|
-
|
|
213
|
+
SDK 固定只上报 RUM Trace,不创建 Metrics/Logs Provider,无需配置开关。
|
|
235
214
|
|
|
236
215
|
```ts
|
|
237
216
|
new BkOpenTelemetry({
|
|
238
217
|
application: { name: 'demo' },
|
|
239
|
-
transport: {
|
|
240
|
-
signals: {
|
|
241
|
-
traces: { endpoint: 'https://trace-gateway.example.com/v1/rum' },
|
|
242
|
-
metrics: false,
|
|
243
|
-
logs: false,
|
|
244
|
-
},
|
|
245
|
-
},
|
|
218
|
+
transport: { endpoint: 'https://trace-gateway.example.com' },
|
|
246
219
|
});
|
|
247
220
|
```
|
|
248
221
|
|
|
249
|
-
|
|
222
|
+
Endpoint 会解析为 `https://trace-gateway.example.com/v1/rum`。
|
|
250
223
|
|
|
251
224
|
## 为什么不建议多个实例同时运行?
|
|
252
225
|
|
package/dist/core/metric.d.ts
DELETED
package/dist/core/signal.d.ts
DELETED
package/dist/core/throttle.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 简易 djb2 字符串 hash。结果稳定、短(base36),足以区分常见 fingerprint 字符串组合。
|
|
3
|
-
* 不是密码学安全 hash,仅用于事件聚合分组场景。
|
|
4
|
-
*/
|
|
5
|
-
export declare const hashString: (input: string) => string;
|
|
6
|
-
export interface ThrottleResult {
|
|
7
|
-
/** 是否允许本次上报 */
|
|
8
|
-
allowed: boolean;
|
|
9
|
-
/** 当前窗口内同 fingerprint 的触发序号(含本次) */
|
|
10
|
-
count: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* 时间窗节流:同一 key 在 windowMs 窗口内最多允许 maxPerWindow 次通过;
|
|
14
|
-
* 超出则被拦截,但 `count` 仍累加,供调用方维护内部统计。
|
|
15
|
-
*
|
|
16
|
-
* 长会话场景下避免 records 无限累积——按窗口长度节奏轻量清理一次过期 entry。
|
|
17
|
-
*/
|
|
18
|
-
export declare const createThrottle: (windowMs: number, maxPerWindow: number) => {
|
|
19
|
-
allow(key: string): ThrottleResult;
|
|
20
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { BkOTRequestBodyConfig, BkOTRequestContext, BkOTRequestEvent } from '../core/config';
|
|
2
|
-
import type { BkOTRuntimeContext } from '../core/plugin';
|
|
3
|
-
import type { Span } from '@opentelemetry/api';
|
|
4
|
-
interface CaptureRequestBodyLogOptions {
|
|
5
|
-
bodyConfig: BkOTRequestBodyConfig;
|
|
6
|
-
domainContext: BkOTRequestContext;
|
|
7
|
-
event: BkOTRequestEvent;
|
|
8
|
-
fetchRequest?: Request | RequestInit;
|
|
9
|
-
occurredAt?: number;
|
|
10
|
-
runtimeContext: Pick<BkOTRuntimeContext, 'emitLog'>;
|
|
11
|
-
span: Span;
|
|
12
|
-
}
|
|
13
|
-
export declare const prepareFetchRequestBodySource: (request: Request | RequestInit) => Request | RequestInit | undefined;
|
|
14
|
-
export declare const captureRequestBodyLog: ({ bodyConfig, domainContext, event, fetchRequest, occurredAt, runtimeContext, span, }: CaptureRequestBodyLogOptions) => Promise<void>;
|
|
15
|
-
export {};
|