@blueking/open-telemetry 0.0.31 → 0.0.33
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 +71 -33
- package/dist/bk-rum.global.js +2 -2
- package/dist/bk-rum.global.js.map +1 -1
- package/dist/core/plugin.d.ts +3 -0
- package/dist/index.js +461 -354
- package/dist/index.js.map +1 -1
- package/dist/plugins/web-vitals.d.ts +1 -1
- package/dist/schema/attributes.d.ts +1 -0
- package/dist/schema/span.d.ts +10 -0
- package/package.json +1 -1
- package/skills/bk-rum-otele/SKILL.md +1 -1
- package/skills/bk-rum-otele/evals/evals.json +1 -1
- package/skills/bk-rum-otele/references/actions.md +16 -10
- package/skills/bk-rum-otele/references/api.md +6 -3
- package/skills/bk-rum-otele/references/architecture.md +4 -4
- package/skills/bk-rum-otele/references/blank-screen.md +10 -19
- package/skills/bk-rum-otele/references/capabilities.md +18 -18
- package/skills/bk-rum-otele/references/configuration.md +5 -5
- package/skills/bk-rum-otele/references/data-model.md +14 -16
- package/skills/bk-rum-otele/references/errors-security.md +9 -8
- package/skills/bk-rum-otele/references/extensions.md +8 -0
- package/skills/bk-rum-otele/references/framework-integration.md +1 -1
- package/skills/bk-rum-otele/references/getting-started.md +21 -2
- package/skills/bk-rum-otele/references/network.md +21 -22
- package/skills/bk-rum-otele/references/performance.md +14 -25
- package/skills/bk-rum-otele/references/privacy.md +1 -1
- package/skills/bk-rum-otele/references/session-context.md +16 -12
- package/skills/bk-rum-otele/references/span-protocol.md +192 -282
- package/skills/bk-rum-otele/references/telemetry-reference.md +97 -99
- package/skills/bk-rum-otele/references/transport-sampling.md +19 -14
- package/skills/bk-rum-otele/references/troubleshooting.md +4 -4
- package/skills/bk-rum-otele/references/views-routing.md +5 -4
|
@@ -21,7 +21,7 @@ SDK 不采集任何请求 Body、响应 Body、WebSocket 消息内容、消息
|
|
|
21
21
|
1. 把 URL 转成绝对 URL。
|
|
22
22
|
2. 排除 SDK 自身上报和 `excludedUrls`。
|
|
23
23
|
3. 按白名单探测既有 Trace Header,规划本次请求的 trace context。
|
|
24
|
-
4. 创建 `
|
|
24
|
+
4. 创建 `span_type=resource` 的 CLIENT Span,并把关联后端 Trace 的 Span Link 一并写入。
|
|
25
25
|
5. 需要时注入 `traceparent`。
|
|
26
26
|
6. 把请求开始/结束通知给 View/Action 页面活动。
|
|
27
27
|
7. 根据 Response 或终止原因生成结构化 outcome,并补充结果、异常和 Resource Timing。
|
|
@@ -32,7 +32,7 @@ Patch 在插件 shutdown 时仅在全局方法仍是 SDK 安装版本的情况
|
|
|
32
32
|
|
|
33
33
|
## 请求 Span
|
|
34
34
|
|
|
35
|
-
Fetch 和 XHR
|
|
35
|
+
Fetch 和 XHR 都生成名称为 `<http.request.method> <url.template>` 的 Resource Span:
|
|
36
36
|
|
|
37
37
|
| 字段 | Fetch | XHR |
|
|
38
38
|
| --------------------------- | ---------------------------------------------- | --------------------------- |
|
|
@@ -53,18 +53,17 @@ Span 开始时间使用请求开始时间,结束时间优先使用匹配到的
|
|
|
53
53
|
|
|
54
54
|
## Outcome 与 Status
|
|
55
55
|
|
|
56
|
-
| 条件 | `outcome.type` |
|
|
57
|
-
| ---------------------------------- | -------------- |
|
|
58
|
-
| `408` / `504` | `timeout` |
|
|
59
|
-
| 其他 `4xx`
|
|
60
|
-
|
|
|
61
|
-
| Fetch
|
|
62
|
-
| Fetch
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
| 其余 | `success` | 不写 | UNSET |
|
|
56
|
+
| 条件 | `outcome.type` | OTel Status |
|
|
57
|
+
| ---------------------------------- | -------------- | --------------------------- |
|
|
58
|
+
| `408` / `504` | `timeout` | ERROR |
|
|
59
|
+
| 其他 `4xx` / `5xx` | `error` | ERROR |
|
|
60
|
+
| Fetch AbortError / XHR `abort` | `abort` | UNSET,不记录 exception |
|
|
61
|
+
| Fetch TimeoutError / XHR `timeout` | `timeout` | ERROR,Fetch 记录 exception |
|
|
62
|
+
| Fetch 其他 reject / XHR `error` | `error` | ERROR,Fetch 记录 exception |
|
|
63
|
+
| XHR `load` 但无法取得有效状态 | `error` | ERROR |
|
|
64
|
+
| 其余 | `success` | UNSET |
|
|
66
65
|
|
|
67
|
-
SDK 不根据业务响应 JSON 中的 code 判断成功或失败;需要业务口径时使用 `request.beforeSend` 增加属性,或上报自定义事件。
|
|
66
|
+
当前 SDK **不写** `outcome.reason`。HTTP 失败请用 `http.response.status_code` 细分。SDK 不根据业务响应 JSON 中的 code 判断成功或失败;需要业务口径时使用 `request.beforeSend` 增加属性,或上报自定义事件。
|
|
68
67
|
|
|
69
68
|
## URL 排除
|
|
70
69
|
|
|
@@ -114,7 +113,7 @@ traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
|
|
|
114
113
|
└ version=00 parent-id:16 位 ─────┘ sampled=01
|
|
115
114
|
```
|
|
116
115
|
|
|
117
|
-
这样后端按 trace-id 检索时,一条 Trace 只对应一个 API
|
|
116
|
+
这样后端按 trace-id 检索时,一条 Trace 只对应一个 API 请求,也不会把前端 Resource Span 混进后端链路。前后端的关联由 **Span Link** 承担,后端可按 `link.trace_id` 反查对应的 RUM Span。
|
|
118
117
|
|
|
119
118
|
每个命中白名单的请求恒定产出**一条** Link,结构固定为 trace context 加上记录来源的 `attributes`:
|
|
120
119
|
|
|
@@ -222,7 +221,7 @@ Fetch resolve/reject 和 XHR 终止事件往往早于 Resource Timing Observer
|
|
|
222
221
|
|
|
223
222
|
## 静态资源
|
|
224
223
|
|
|
225
|
-
`tracking.resource=true` 时,Resource PerformanceObserver 为非 Fetch/XHR Entry 创建独立
|
|
224
|
+
`tracking.resource=true` 时,Resource PerformanceObserver 为非 Fetch/XHR Entry 创建独立 Resource CLIENT Span。Span 名使用 `GET <url.template>`。Fetch 和 `xmlhttprequest` Entry 只回填已有请求 Span,不重复上报。
|
|
226
225
|
|
|
227
226
|
常见资源类型来自 `initiatorType`,例如 `script`、`link`、`img`、`css`、`beacon`、`other`。
|
|
228
227
|
|
|
@@ -275,14 +274,14 @@ Timing-Allow-Origin: https://your-web.example.com
|
|
|
275
274
|
|
|
276
275
|
`tracking.websocket=true` 时,SDK 使用 Proxy 包装全局 `WebSocket` 构造器,并保持静态常量、`instanceof` 和子类构造行为。每条连接生成 `websocket.connection.id`,随后发送四类瞬时 CLIENT Span:
|
|
277
276
|
|
|
278
|
-
| phase | 时机 | 额外字段
|
|
279
|
-
| --------- | --------------------- |
|
|
280
|
-
| `connect` | 构造 WebSocket 后立即 | 基础目标字段
|
|
281
|
-
| `open` | `open` Event | 无
|
|
282
|
-
| `error` | `error` Event | `websocket.error.phase
|
|
283
|
-
| `close` | `close` Event | code、reason、was_clean
|
|
277
|
+
| phase | 时机 | 额外字段 |
|
|
278
|
+
| --------- | --------------------- | --------------------------------------------- |
|
|
279
|
+
| `connect` | 构造 WebSocket 后立即 | 基础目标字段 |
|
|
280
|
+
| `open` | `open` Event | 无 |
|
|
281
|
+
| `error` | `error` Event | `websocket.error.phase`:`connect` 或 `runtime` |
|
|
282
|
+
| `close` | `close` Event | code、reason、was_clean |
|
|
284
283
|
|
|
285
|
-
Span
|
|
284
|
+
Span 名按 `websocket.<websocket.phase>` 生成,不使用长连接 Span。基础字段包括:
|
|
286
285
|
|
|
287
286
|
- `network.protocol.name=websocket`
|
|
288
287
|
- `url.full`,经脱敏
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Web Vitals 总览
|
|
8
8
|
|
|
9
|
-
`
|
|
9
|
+
`span_type=vital` 覆盖以下指标,Span 名使用大写指标名:
|
|
10
10
|
|
|
11
11
|
| 指标 | `vital.metric` | 单位 | 当前采集方式 |
|
|
12
12
|
| --- | --- | --- | --- |
|
|
@@ -24,25 +24,16 @@
|
|
|
24
24
|
|
|
25
25
|
- `vital.metric`
|
|
26
26
|
- `vital.value`
|
|
27
|
-
- `vital.rating=good|needs-improvement|poor`
|
|
28
27
|
- `vital.id`
|
|
29
28
|
- `span_type=vital`
|
|
30
|
-
- `outcome.type=success
|
|
29
|
+
- `outcome.type=success`,仅内部 rating=good
|
|
31
30
|
- `outcome.type=warning`,其他 rating
|
|
32
31
|
|
|
33
|
-
Vital Span 是瞬时 INTERNAL Span。非法 `NaN`、`Infinity`
|
|
32
|
+
Vital Span 是瞬时 INTERNAL Span。非法 `NaN`、`Infinity` 不上报。当前 **不写** `vital.rating` 或 `navigationType` Attribute;good/poor 只通过 `outcome.type` 体现。
|
|
34
33
|
|
|
35
34
|
## Navigation Type
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- `navigate`
|
|
40
|
-
- `reload`
|
|
41
|
-
- `back-forward`
|
|
42
|
-
- `back-forward-cache`
|
|
43
|
-
- `prerender`
|
|
44
|
-
- `restore`
|
|
45
|
-
- `unknown`
|
|
36
|
+
web-vitals 指标对象可能带 `navigationType`,但当前插件 **不会** 把它写入 Span。不要按该字段查询 Collector 数据。
|
|
46
37
|
|
|
47
38
|
## FCP、LCP 与 TTFB 的 View 归属
|
|
48
39
|
|
|
@@ -52,8 +43,8 @@ Attribution 字段:
|
|
|
52
43
|
|
|
53
44
|
| 指标 | 字段 |
|
|
54
45
|
| --- | --- |
|
|
55
|
-
| LCP | `vital.lcp.url`、`target`、`element_render_delay`、`resource_load_duration
|
|
56
|
-
| FCP |
|
|
46
|
+
| LCP | `vital.lcp.url`、`target`、`element_render_delay`、`resource_load_duration` |
|
|
47
|
+
| FCP | 当前无独立归因字段 |
|
|
57
48
|
| TTFB | `vital.ttfb.waiting_duration`、`dns_duration`、`connection_duration`、`request_duration` |
|
|
58
49
|
|
|
59
50
|
LCP URL 经过 `redactUrl`;DOM target 等字段可能包含高基数或业务语义,应纳入隐私审查。
|
|
@@ -66,16 +57,16 @@ SDK 不直接使用整页生命周期累计的 web-vitals CLS,而是按 SDK Vi
|
|
|
66
57
|
- 相邻 Shift 间隔小于 1 秒且窗口总长小于 5 秒时进入同一 session window;
|
|
67
58
|
- 取所有 session window 中累计值最大的一个;
|
|
68
59
|
- 数值保留四位小数;
|
|
69
|
-
- 记录该窗口中最大的单次 Shift
|
|
60
|
+
- 记录该窗口中最大的单次 Shift 及目标元素(仅用于内部累计 `vital.value`,**不上报** `vital.cls.largest_shift_*`);
|
|
70
61
|
- View 结束时发送一条 CLS Span,即使值为 0。
|
|
71
62
|
|
|
72
|
-
Rating
|
|
63
|
+
Rating 阈值(只影响 `outcome.type`,不写 `vital.rating`):
|
|
73
64
|
|
|
74
|
-
- `<= 0.1`:good
|
|
75
|
-
- `<= 0.25`:needs-improvement
|
|
76
|
-
- `> 0.25`:poor
|
|
65
|
+
- `<= 0.1`:good → `success`
|
|
66
|
+
- `<= 0.25`:needs-improvement → `warning`
|
|
67
|
+
- `> 0.25`:poor → `warning`
|
|
77
68
|
|
|
78
|
-
|
|
69
|
+
当前 **不上报** `vital.cls.load_state`。按 View 汇总的 CLS 传入空 attribution。
|
|
79
70
|
|
|
80
71
|
## 每个 View 的 INP
|
|
81
72
|
|
|
@@ -133,19 +124,17 @@ tracking: {
|
|
|
133
124
|
|
|
134
125
|
## Long Task Span
|
|
135
126
|
|
|
136
|
-
每条合格 Entry 生成 `
|
|
127
|
+
每条合格 Entry 生成 `span_type=long_task` 的 INTERNAL Span。Span 名使用 `long_task.entry_type`,持续时间等于浏览器 Entry duration:
|
|
137
128
|
|
|
138
129
|
- `long_task.id`
|
|
139
130
|
- `long_task.entry_type=long-animation-frame|long-task`
|
|
140
|
-
- `long_task.duration`
|
|
141
131
|
- `long_task.name`
|
|
142
|
-
- LoAF 的 `long_task.start_time`
|
|
143
132
|
- LoAF 原生 `long_task.blocking_duration`
|
|
144
133
|
- LoAF 的 `long_task.first_ui_event_timestamp`
|
|
145
134
|
- LoAF 的 `long_task.render_start`
|
|
146
135
|
- LoAF 的 `long_task.style_and_layout_start`
|
|
147
136
|
|
|
148
|
-
Span 开始时间是 `performance.timeOrigin + entry.startTime
|
|
137
|
+
Span 开始时间是 `performance.timeOrigin + entry.startTime`,结束时间加上 `entry.duration`;持续时间只体现在 Span 起止时间上,没有独立的 `long_task.duration` 或 `long_task.start_time` Attribute。该 Span 也会通知 Action Activity,使活动中的 Action 能关联此 Long Task。
|
|
149
138
|
|
|
150
139
|
## LoAF 脚本 Event
|
|
151
140
|
|
|
@@ -52,7 +52,7 @@ await rum.setTrackingConsent('not-granted');
|
|
|
52
52
|
- SDK 不提供 Consent UI、Cookie 分类或法律依据记录;
|
|
53
53
|
- 页面中有多个 SDK 实例时,全局 OTel 对象按引用计数释放,但全局监听仍可能重复,因此仍应使用单实例。
|
|
54
54
|
|
|
55
|
-
构造阶段有一个重要边界:`new BkOpenTelemetry()` 会先解析配置并创建 OpenTelemetry Resource。只要 `tracking.device !== false`,这个过程会同步读取 UA
|
|
55
|
+
构造阶段有一个重要边界:`new BkOpenTelemetry()` 会先解析配置并创建 OpenTelemetry Resource。只要 `tracking.device !== false`,这个过程会同步读取 `navigator.userAgent` 与 UA-CH(`userAgentData.platform` / `mobile`),生成 `user_agent.*` 和 `device.type` 四个 Resource 字段,即使初始 Consent 是 `not-granted` 或 `enabled: false`;这些值此时不会发送,Device 插件的 ID/视口/网络监听也不会启动。如果你的合规定义连“读取 User-Agent”都必须晚于授权,应在获得授权后再构造 SDK,而不是只依赖 `trackingConsent`。
|
|
56
56
|
|
|
57
57
|
## URL 脱敏
|
|
58
58
|
|
|
@@ -20,7 +20,7 @@ SDK 使用以下固定规则:
|
|
|
20
20
|
初始化时,SDK 尝试从 localStorage 读取同一应用和 Collector 隔离的 Session Record:
|
|
21
21
|
|
|
22
22
|
- Record 有效:复用 ID,并延长无活动过期时间。
|
|
23
|
-
- Record 不存在:创建新 Session,发送 `
|
|
23
|
+
- Record 不存在:创建新 Session,发送 `session.start` Span。
|
|
24
24
|
- Record 已过期:创建新 ID,发送 rotate;旧 Session 的 end 由持有旧上下文的 Tab 发送。
|
|
25
25
|
- localStorage 不可访问:退回当前 JavaScript 进程内存,不影响页面采集,但不能跨页面或跨 Tab 共享。
|
|
26
26
|
|
|
@@ -29,7 +29,7 @@ SDK 使用以下固定规则:
|
|
|
29
29
|
用户活动会延长有效 Session。达到 15 分钟无活动或 4 小时最长生命周期时,SDK:
|
|
30
30
|
|
|
31
31
|
1. 通知 View、Action 等插件 Session 已过期。
|
|
32
|
-
2. 发送 `
|
|
32
|
+
2. 发送 `session.end` Span。
|
|
33
33
|
3. 清除运行时 `session.*`。
|
|
34
34
|
4. 结束当前 View。
|
|
35
35
|
5. 触发一次 flush。
|
|
@@ -39,7 +39,13 @@ SDK 使用以下固定规则:
|
|
|
39
39
|
|
|
40
40
|
## 跨 Tab 行为
|
|
41
41
|
|
|
42
|
-
默认 storage key
|
|
42
|
+
默认 storage key 按 `application.name` 与 **解析后 Endpoint 的 host** 计算:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
bk_ot_session__${hash36(application.name + "\0" + endpointHost)}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`hash36` 是 djb2 风格非密码学 hash,转成 36 进制。同一浏览器 origin 下,不同 `application.name` 或不同 Collector host 不会共用 Session。多个同源 Tab 默认共享同一 key 下的 Session Record。
|
|
43
49
|
|
|
44
50
|
- 其他 Tab 只延长当前相同 Session 时,本 Tab 会更新自己的过期 Timer。
|
|
45
51
|
- 其他 Tab 使 Session 过期或替换 ID 时,本 Tab 会停用自己的 Session。
|
|
@@ -73,24 +79,23 @@ new BkOpenTelemetry({
|
|
|
73
79
|
|
|
74
80
|
## Session 遥测
|
|
75
81
|
|
|
76
|
-
Span
|
|
82
|
+
Span 名按 `session.<session.phase>` 生成:
|
|
77
83
|
|
|
78
|
-
| `session.phase` | 使用时机 |
|
|
84
|
+
| `session.phase` | 使用时机 | 内部 lifecycle reason(不上报为 Attribute) |
|
|
79
85
|
| --- | --- | --- |
|
|
80
86
|
| `start` | 首次创建 | `init` |
|
|
81
87
|
| `rotate` | 旧 Session 过期后新建 | `inactivity`、`maxLifetime` |
|
|
82
88
|
| `end` | 当前 Session 失效 | `inactivity`、`maxLifetime`、`external` |
|
|
83
89
|
|
|
84
|
-
|
|
90
|
+
实际上报字段只有:
|
|
85
91
|
|
|
86
92
|
- `session.id`
|
|
87
|
-
- `session.start_time`
|
|
88
93
|
- `session.type=user`
|
|
89
94
|
- `session.has_replay=false`
|
|
90
|
-
- `session.lifecycle.reason`
|
|
91
|
-
- `session.previous_id`,仅存在前一个 ID 时出现
|
|
92
95
|
- `session.phase`
|
|
93
96
|
|
|
97
|
+
过期原因通过 `onSessionLifecycle` 通知插件,**不会**写成 `session.lifecycle.reason` 或 `session.start_time`。完整字段见[遥测字段字典](./telemetry-reference.md#session-字段)。
|
|
98
|
+
|
|
94
99
|
生命周期 Span 是瞬时事件,持续时间由服务端根据时间戳推导。
|
|
95
100
|
|
|
96
101
|
## User 上下文
|
|
@@ -121,10 +126,9 @@ SDK 只维护 `user.id`,并原样透传:不 hash、不截断、不验证、
|
|
|
121
126
|
| `user_agent.name` | UA 简单识别:Edge/Chrome/Firefox/Safari/Other | 否 |
|
|
122
127
|
| `user_agent.version` | UA 主版本 | 未识别版本时 |
|
|
123
128
|
| `user_agent.os.name` | UA / UA-CH platform | 否,无法识别为 `Other` |
|
|
124
|
-
| `device.type` | UA-CH mobile 或移动 UA |
|
|
125
|
-
| `device.memory_gib` | `navigator.deviceMemory` | 浏览器未实现时 |
|
|
129
|
+
| `device.type` | UA-CH mobile 或移动 UA 特征 | 否,仅为 `mobile` 或 `desktop` |
|
|
126
130
|
|
|
127
|
-
关闭 `tracking.device` 时,这些 Device Resource
|
|
131
|
+
关闭 `tracking.device` 时,这些 Device Resource 字段不写入。当前不读取 `navigator.deviceMemory`,因此没有 `device.memory_gib`。
|
|
128
132
|
|
|
129
133
|
## Device 运行时属性
|
|
130
134
|
|