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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +11 -25
  2. package/dist/bk-rum.global.js +2 -12
  3. package/dist/bk-rum.global.js.map +1 -1
  4. package/dist/core/config.d.ts +8 -44
  5. package/dist/core/hash.d.ts +2 -0
  6. package/dist/core/plugin.d.ts +2 -7
  7. package/dist/core/processor.d.ts +0 -20
  8. package/dist/core/sdk.d.ts +1 -7
  9. package/dist/core/telemetry-attributes.d.ts +1 -2
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.js +1045 -1463
  12. package/dist/index.js.map +1 -1
  13. package/dist/plugins/common.d.ts +1 -1
  14. package/dist/plugins/csp-violation.d.ts +0 -8
  15. package/dist/plugins/error.d.ts +1 -5
  16. package/dist/plugins/long-task.d.ts +1 -3
  17. package/dist/plugins/web-vitals.d.ts +1 -4
  18. package/dist/schema/attributes.d.ts +8 -10
  19. package/dist/schema/span.d.ts +2 -0
  20. package/package.json +2 -6
  21. package/skills/bk-rum-otele/SKILL.md +9 -5
  22. package/skills/bk-rum-otele/evals/evals.json +2 -2
  23. package/skills/bk-rum-otele/references/api.md +10 -22
  24. package/skills/bk-rum-otele/references/architecture.md +38 -118
  25. package/skills/bk-rum-otele/references/capabilities.md +26 -28
  26. package/skills/bk-rum-otele/references/concepts.md +14 -106
  27. package/skills/bk-rum-otele/references/configuration.md +25 -66
  28. package/skills/bk-rum-otele/references/custom-plugin.md +10 -13
  29. package/skills/bk-rum-otele/references/data-model.md +23 -95
  30. package/skills/bk-rum-otele/references/getting-started.md +1 -1
  31. package/skills/bk-rum-otele/references/plugins-basic.md +135 -0
  32. package/skills/bk-rum-otele/references/plugins-error-security.md +86 -0
  33. package/skills/bk-rum-otele/references/plugins-experience.md +124 -0
  34. package/skills/bk-rum-otele/references/plugins-network.md +32 -0
  35. package/skills/bk-rum-otele/references/plugins.md +3 -486
  36. package/skills/bk-rum-otele/references/privacy.md +4 -25
  37. package/skills/bk-rum-otele/references/telemetry-reference.md +49 -243
  38. package/skills/bk-rum-otele/references/transport-sampling.md +15 -50
  39. package/skills/bk-rum-otele/references/troubleshooting.md +7 -34
  40. package/dist/core/metric.d.ts +0 -2
  41. package/dist/core/signal.d.ts +0 -3
  42. package/dist/core/throttle.d.ts +0 -20
  43. package/dist/plugins/request-body.d.ts +0 -15
@@ -2,249 +2,55 @@
2
2
 
3
3
  # 遥测参考
4
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**:标准字段与 RUM 领域字段均使用点号命名空间(如 `http.request.method`、`exception.type`、`view.id`、`session.id`、`browser.name`);跨类型检索字段使用下划线(如 `span_type`、`span_subtype`、`result`)。字段常量集中定义在 `src/schema/attributes.ts`。
13
-
14
- ## 公共 Resource 与运行时上下文属性
15
-
16
- Resource 属性由三类信号共享;运行时上下文属性自动挂到**几乎所有** span / log 上(metric 视插件而定)。后续各清单不再重复列出:
17
-
18
- | key | 归属 | 类型 | 说明 | 低基数 |
19
- | --- | --- | --- | --- | --- |
20
- | `service.name` | Resource | string | 应用名(`application.name`) | 是 |
21
- | `service.version` | Resource | string | 应用版本(`application.version`,可选) | 是 |
22
- | `deployment.environment.name` | Resource | string | 环境(`application.environment`) | 是 |
23
- | `rum.schema.version` | Resource | string | 当前固定 `2` | 是 |
24
- | `telemetry.sdk.name` / `telemetry.sdk.language` / `telemetry.sdk.version` | Resource | string | SDK 名、语言和包版本 | 是 |
25
- | `device.type` | Resource | string | `mobile` / `desktop` | 是 |
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
- | span 名 | span_type | 来源 | 关键属性 | 备注 |
46
- | --- | --- | --- | --- | --- |
47
- | `browser.view` | `document` / `route` | View 管理器 | `view.name`、`view.loading_time`、`view.loading_time.source`、`url.previous`、`event.source`、`view.end_reason` | 有持续时间,下一次 View 或 pagehide 时结束 |
48
- | `browser.resource` | `resource` | Fetch/XHR request 采集 | `resource.type=fetch\|xhr`、`url.full`、`http.request.method`、`http.response.status_code`、网络阶段属性 | span kind 为 CLIENT;Fetch/XHR 共用同一实现 |
49
- | `browser.resource` | `resource` | resource 插件 | `resource.type`、`url.full`、`resource.size`、网络阶段、`resource.render_blocking_status`、`resource.protocol`、`resource.cache.hit` | 仅静态资源,跳过 Fetch/XHR |
50
- | `browser.web_vital` | `vital` | webVitals 插件 | `vital.metric`、`vital.value`、`vital.rating`、`vital.id`、`rum.navigation.type`、`vital.<lcp\|cls\|inp\|fcp\|ttfb>.*` | 每个指标一条 |
51
- | `browser.blank_screen` | `error` | blankScreen 插件(二次确认白屏时) | `blank_screen.empty_ratio`、`blank_screen.reason`、`blank_screen.root_selector`、`blank_screen.root_found`、`blank_screen.*_sample_count`、`blank_screen.center_element` | 每个 View 最多一条 |
52
- | `browser.error` | `error` | error 插件(`window.error`) | `exception.fingerprint`、`exception.message_short`、`exception.stack_top_frame`、`error.source=window.error`、`error.window_occurrence_index`、`code.filepath`、`code.lineno`、`code.column`、`error.cross_origin` | 完整异常写入标准 `exception` Span Event |
53
- | `browser.unhandledrejection` | `error` | error 插件(Promise 异常) | `exception.fingerprint`、`error.source=unhandledrejection` | 完整异常写入标准 `exception` Span Event |
54
- | `browser.resource_error` | `error` | error 插件(资源加载失败) | `exception.fingerprint`、`error.source=resource`、`url.full`、`html.tag` | 完整异常写入标准 `exception` Span Event |
55
- | `browser.long_task` | `longtask` | longTask 插件 | `long_task.id`、`long_task.entry_type`、`long_task.start_time`、`long_task.duration`、`long_task.blocking_duration`、`long_task.culprit`、`long_task.script.count` | LoAF 脚本详情写入 `long_task.script` Span Event |
56
- | `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_occurrence_index`、`csp.original_policy`(窗口首条) | |
57
- | `websocket.connect` | `custom` | websocket 插件(仅建连阶段) | `url.full`、`url.scheme`、`server.address`、`network.protocol.name=websocket` | 长连接生命周期不绑定 span |
58
- | `action.click` / `action.custom` | `action` | action 插件 / `reportAction()` | `action.id/name/type/target.*`、`action.loading_time`、`action.frustration.*`、`action.*.count` | 自动点击或手动动作;挫败信号仅自动点击 |
59
- | `custom.<name>` | `custom` | `reportCustomEvent()` / 自定义插件 | `rum.custom.name`、业务自定义属性 | 带 `error` 时记录 exception、设置错误 Status/Result,`span_type` 仍为 `custom` |
60
-
61
- ## Metric 清单
62
-
63
- | 名称 | 类型 | 单位 | 主要维度 | 来源 |
64
- | --- | --- | --- | --- | --- |
65
- | `browser.web_vital.cls` | Histogram | `1` | `vital.metric`、`vital.rating`、`rum.navigation.type`、`view.url_path_group` | webVitals |
66
- | `browser.web_vital.duration` | Histogram | `ms` | 同上(FCP/INP/LCP/TTFB 靠 `vital.metric` 区分) | webVitals |
67
- | `browser.view.loading_time` | Histogram | `ms` | `view.url_path_group`、`view.loading_type` | View 管理器,View 结束时记录最终值 |
68
- | `browser.blank_screen.count` | Counter | - | `view.url_path_group`、`blank_screen.root_selector`、`blank_screen.reason` | blankScreen |
69
- | `browser.error.count` | Counter | - | `view.url_path_group`、`error.source`、`error.subtype` | error,span 节流前精确累计 |
70
- | `browser.csp_violation.count` | Counter | - | `view.url_path_group`、`csp.disposition`、`csp.effective_directive` | cspViolation,span 节流前精确累计 |
71
- | `browser.long_task.count` | Counter | - | `view.url_path_group`、`long_task.entry_type` | longTask |
72
- | `browser.long_task.duration` | Histogram | `ms` | 同上 | longTask |
73
- | `browser.long_task.blocking_duration` | Histogram | `ms` | 同上 | longTask,仅 LoAF |
74
- | `browser.websocket.message.count` | Counter | - | `server.address`、`url.scheme`、`websocket.direction`(in/out) | websocket |
75
- | `browser.websocket.message.bytes` | Counter | `By` | 同上 | websocket |
76
- | `browser.websocket.error.count` | Counter | - | `server.address`、`url.scheme`、`websocket.error.phase`(connect/runtime) | websocket |
77
- | `browser.websocket.connect.duration` | Histogram | `ms` | `server.address`、`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
- | 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
- > 错误主数据统一走 `error` span(见 Span 清单),SDK **不再**为同一个错误额外 emit error log,避免重复计数。
93
-
94
- ## 属性字典
95
-
96
- ### 归一字段
97
-
98
- 由 `buildRumSpanAttributes` 等构造器写入,用于跨事件类型统一检索。
99
-
100
- | key | 类型 | 说明 | 低基数 |
101
- | --- | --- | --- | --- |
102
- | `span_type` | string | `document`/`resource`/`vital`/`error`/`longtask`/`action`/`route`/`custom` | 是 |
103
- | `span_subtype` | string | 子类型,如 `fetch`/`xhr`/`js`/`promise`/`lcp` | 是 |
104
- | `result` | string | `success`/`warning`/`error`/`timeout`/`abort` | 是 |
105
- | `error_type` | string | 错误细分,如 `http_5xx`/`network_timeout`/`slow`/`none` | 是 |
106
-
107
- ### HTTP / Resource
108
-
109
- | key | 类型 | 说明 |
110
- | --- | --- | --- |
111
- | `http.request.method` | string | 请求方法(大写) |
112
- | `http.response.status_code` | number | 响应状态码 |
113
- | `url.full` | string | 完整 URL(已脱敏) |
114
- | `server.address` | string | 目标主机名 |
115
- | `server.port` | number | 目标显式端口(存在时) |
116
- | `resource.type` | string | `fetch`/`xhr` 或静态资源 initiator type |
117
- | `resource.redirect.start/duration` | number | 重定向阶段相对开始时间 / 耗时(ms) |
118
- | `resource.dns.start/duration` | number | DNS 阶段相对开始时间 / 耗时(ms) |
119
- | `resource.connect.start/duration` | number | TCP 建连阶段相对开始时间 / 耗时(ms) |
120
- | `resource.ssl.start/duration` | number | TLS 握手阶段相对开始时间 / 耗时(ms) |
121
- | `resource.first_byte.start/duration` | number | 等待首字节阶段相对开始时间 / 耗时(ms) |
122
- | `resource.download.start/duration` | number | 响应下载阶段相对开始时间 / 耗时(ms) |
123
- | `resource.worker.start/duration` | number | Service Worker 阶段相对开始时间 / 耗时(ms) |
124
- | `resource.delivery_type` | string | `cache` / `navigational-prefetch` 等浏览器交付类型 |
125
- | `resource.render_blocking_status` | string | `blocking` / `non-blocking` |
126
- | `resource.size` | number | 传输字节数 |
127
- | `url.previous` | string | 跳转前 URL |
128
- | `resource.cache.hit` | boolean | 是否命中缓存 |
129
- | `resource.protocol` | string | 协议,如 `h2` |
130
- | `resource.encoded_body_size` / `resource.decoded_body_size` | number | 资源体积 |
131
- | `request.body` / `response.body` | string | 仅 `browser.request.body` Log;经过接入方 `redact` 且受长度限制 |
132
- | `request.body.content_type` / `response.body.content_type` | string | body Content-Type(可获取时) |
133
- | `request.body.truncated` / `response.body.truncated` | boolean | body 是否因长度限制而截断 |
134
-
135
- ### Web Vitals
136
-
137
- | key | 类型 | 说明 |
138
- | --- | --- | --- |
139
- | `vital.metric` | string | `cls`/`fcp`/`inp`/`lcp`/`ttfb` |
140
- | `vital.value` | number | 指标值 |
141
- | `vital.rating` | string | `good`/`needs-improvement`/`poor` |
142
- | `vital.id` | string | 单条度量唯一 ID(仅 span) |
143
- | `rum.navigation.type` | string | 导航类型,含 `back-forward-cache` 等 |
144
- | `vital.lcp.*` / `vital.cls.*` / `vital.inp.*` / `vital.fcp.*` / `vital.ttfb.*` | mixed | attribution 归因明细(仅 span) |
145
-
146
- ### 错误 / 异常
147
-
148
- | key | 类型 | 说明 |
149
- | --- | --- | --- |
150
- | `exception.type` | string | 异常类型/名称 |
151
- | `exception.message` | string | 异常消息 |
152
- | `exception.message_short` | string | 消息前 80 字符 |
153
- | `exception.stacktrace` | string | 堆栈 |
154
- | `exception.stack_top_frame` | string | 栈顶帧 |
155
- | `exception.fingerprint` | string | 节流分组指纹(djb2 hash) |
156
- | `error.source` | string | `window.error`/`unhandledrejection`/`resource`/`csp` |
157
- | `error.handled` | boolean | 是否被业务捕获(自动采集恒为 `false`) |
158
- | `error.window_occurrence_index` | number | 当前节流窗口内该已上报 span 的触发序号;总量查询 `browser.error.count` |
159
- | `error.cross_origin` | boolean | 跨域脚本错误(`Script error.`) |
160
- | `code.filepath` / `code.lineno` / `code.column` | string/number | JS 错误位置 |
161
- | `html.tag` | string | 资源错误的元素标签 |
162
-
163
- ### 设备 / 浏览器 / 网络
164
-
165
- | key | 类型 | 说明 |
166
- | --- | --- | --- |
167
- | `device.id` | string | 匿名设备标识;默认仅当前 SDK 实例稳定,`tracking.device.persistentId=true` 时持久化 |
168
- | `device.memory_gib` | number | Resource 中的近似设备内存(GiB) |
169
- | `device.logical_processor_count` | number | Resource 中的逻辑处理器数量 |
170
- | `browser.viewport.width` / `browser.viewport.height` | number | 视口尺寸 |
171
- | `browser.screen.width` / `browser.screen.height` | number | 屏幕尺寸 |
172
- | `network.connection_type` / `network.downlink` / `network.rtt` / `network.save_data` | mixed | 网络信息 |
173
- | `browser.name` / `browser.version` / `os.name` | string | Resource 中的 UA 解析结果 |
174
- | `device.type` | string | Resource 中的 `mobile` / `desktop` |
175
-
176
- ### 用户动作 / 会话
177
-
178
- | key | 类型 | 说明 |
179
- | --- | --- | --- |
180
- | `action.type` | string | 动作类型 |
181
- | `action.id` | string / string[] | action 自身 ID;关联事件上为 action ID 数组 |
182
- | `action.name` | string | 可读动作名称 |
183
- | `action.target.name` | string | 自动 action 的目标元素名称 |
184
- | `action.target.tag` | string | 自动 action 的目标元素标签 |
185
- | `action.loading_time` | number | 点击后页面活动稳定耗时(ms) |
186
- | `action.resource.count` | number | action 关联资源数 |
187
- | `action.error.count` | number | action 关联错误数 |
188
- | `action.long_task.count` | number | action 关联长任务数 |
189
- | `action.frustration.type` | string[] | `rage_click` / `dead_click` / `error_click` |
190
- | `action.frustration.count` | number | 当前 action 的挫败信号数量 |
191
- | `session.start_time` | number | 会话开始时间戳 |
192
- | `session.previous_id` | string | 轮换前的 session.id |
193
- | `session.rotate.reason` | string | `init`/`inactivity`/`maxLifetime` |
194
-
195
- ### Long Task
196
-
197
- | key | 类型 | 说明 |
198
- | --- | --- | --- |
199
- | `long_task.id` | string | 长任务或长动画帧 ID |
200
- | `long_task.entry_type` | string | `long-animation-frame` / `long-task` |
201
- | `long_task.start_time` | number | LoAF 相对 `performance.timeOrigin` 的开始时间(ms) |
202
- | `long_task.duration` / `long_task.blocking_duration` | number | 总耗时 / 主线程阻塞耗时(ms) |
203
- | `long_task.is_frozen_frame` | boolean | 总耗时是否达到 700ms |
204
- | `long_task.culprit` | string | 最重脚本 URL、函数或 legacy attribution |
205
- | `long_task.script.count` | number | LoAF 脚本数 |
206
- | `long_task.render_start` / `long_task.style_and_layout_start` | number | LoAF 渲染与样式布局阶段起点 |
207
- | `long_task.script.*` | mixed | `long_task.script` Span Event 上的脚本耗时、URL、函数、invoker 和强制布局归因 |
208
-
209
- ### CSP
210
-
211
- | key | 类型 | 说明 |
212
- | --- | --- | --- |
213
- | `csp.blocked_uri` | string | 被拦截资源(URL 类值已脱敏) |
214
- | `csp.violated_directive` / `csp.effective_directive` | string | 违反的指令 |
215
- | `csp.disposition` | string | `enforce` / `report` |
216
- | `csp.source_file` | string | 触发脚本(已脱敏) |
217
- | `csp.line_number` / `csp.column_number` | number | 位置 |
218
- | `csp.status_code` | number | 状态码 |
219
- | `csp.fingerprint` / `csp.window_occurrence_index` | string/number | 节流指纹与该已上报 span 的窗口触发序号 |
220
- | `csp.original_policy` | string | 完整策略,仅窗口首条携带 |
221
-
222
- ### WebSocket
223
-
224
- | key | 类型 | 说明 |
225
- | --- | --- | --- |
226
- | `url.scheme` | string | `ws` / `wss` |
227
- | `server.address` | string | 目标 host |
228
- | `network.protocol.name` | string | 固定 `websocket` |
229
- | `websocket.direction` | string | `in` / `out`(仅 metric) |
230
- | `websocket.error.phase` | string | `connect` / `runtime` |
231
- | `websocket.error.window_occurrence_index` | number | 该已上报错误日志在节流窗口内的触发序号;总量查询 `browser.websocket.error.count` |
232
- | `websocket.close.code` / `websocket.close.reason` / `websocket.close.was_clean` | mixed | 关闭事件详情 |
233
-
234
- ### 白屏
235
-
236
- | key | 类型 | 说明 |
237
- | --- | --- | --- |
238
- | `blank_screen.empty_ratio` | number | 有效样本中的空白比例 |
239
- | `blank_screen.reason` | string | `empty_viewport` / `missing_root` |
240
- | `blank_screen.root_selector` / `blank_screen.root_found` | string/boolean | 根选择器与是否存在 |
241
- | `blank_screen.sample_count` / `blank_screen.valid_sample_count` | number | 总样本数 / 有效样本数 |
242
- | `blank_screen.empty_sample_count` / `blank_screen.ignored_sample_count` | number | 空白样本数 / loading 忽略样本数 |
243
- | `blank_screen.center_element` | string | 视口中心元素选择器 |
244
-
245
- ### 自定义事件
246
-
247
- | key | 类型 | 说明 |
248
- | --- | --- | --- |
249
- | `rum.custom.name` | string | `reportCustomEvent()` 的事件名 |
250
- | `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 原始耗时与脚本 span event |
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` 是可选根地址。未配置独立地址的已开启信号会基于它生成 `/v1/rum`、`/v1/metrics`、`/v1/logs`;单信号 `endpoint` 是完整 URL,不再拼接路径。
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
- signals: {
16
- traces: {
17
- endpoint: 'https://trace.example.com/v1/rum',
18
- processor: 'batch',
19
- batch: {
20
- maxQueueSize: 2048,
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
- - 决定由 `application.name + session.id` 的稳定 hash 得出。
76
- - 采样决定不写额外 storage;同一 Session 内 span/log/metric 决定一致。
77
- - Session 续期后使用新 ID 重新计算。
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
- signals: {
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`、`/v1/metrics`、`/v1/logs` 请求。
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 body 没有数据
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
- `capture` 默认就是 `errors`,成功请求不会产生 body Log;要采集成功请求需显式设为 `all`。如果仍然没有数据,依次检查 Content-Type 是否命中 `allowedContentTypes`、body 是否为支持的文本类型,以及 `redact` 是否返回了 `undefined`。FormData、ArrayBuffer 和二进制响应会跳过。
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
- 可以。将不需要的信号设为 `false`;根 endpoint 在所有已开启信号都配置独立地址时可以省略。
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
- 三类信号不能全部关闭。关闭 Trace 后也不会注入 `traceparent`。
222
+ Endpoint 会解析为 `https://trace-gateway.example.com/v1/rum`。
250
223
 
251
224
  ## 为什么不建议多个实例同时运行?
252
225
 
@@ -1,2 +0,0 @@
1
- export declare const CLS_HISTOGRAM_BOUNDARIES: number[];
2
- export declare const DURATION_HISTOGRAM_BOUNDARIES: number[];
@@ -1,3 +0,0 @@
1
- import type { BkOTRuntimeContext } from './plugin';
2
- export type BkOTSignal = 'logs' | 'metrics' | 'traces';
3
- export declare const shouldRecordSignal: (context: BkOTRuntimeContext, signal: BkOTSignal) => boolean;
@@ -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 {};