@blueking/open-telemetry 0.0.22-beta.1 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +258 -70
- package/dist/bk-rum.global.js +2 -2
- package/dist/bk-rum.global.js.map +1 -1
- package/dist/core/config.d.ts +10 -10
- package/dist/core/runtime-context.d.ts +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +608 -662
- package/dist/index.js.map +1 -1
- package/dist/plugins/blank-screen.d.ts +1 -1
- package/dist/plugins/common.d.ts +2 -2
- package/dist/plugins/device.d.ts +2 -2
- package/dist/plugins/resource.d.ts +1 -0
- package/dist/plugins/web-vitals.d.ts +1 -3
- package/dist/schema/attributes.d.ts +6 -7
- package/dist/schema/span.d.ts +24 -15
- package/package.json +1 -1
- package/skills/bk-rum-otele/SKILL.md +31 -30
- package/skills/bk-rum-otele/references/actions.md +166 -0
- package/skills/bk-rum-otele/references/api.md +248 -215
- package/skills/bk-rum-otele/references/architecture.md +139 -37
- package/skills/bk-rum-otele/references/blank-screen.md +190 -0
- package/skills/bk-rum-otele/references/capabilities.md +175 -83
- package/skills/bk-rum-otele/references/configuration.md +226 -151
- package/skills/bk-rum-otele/references/data-model.md +157 -24
- package/skills/bk-rum-otele/references/errors-security.md +168 -0
- package/skills/bk-rum-otele/references/extensions.md +237 -0
- package/skills/bk-rum-otele/references/framework-integration.md +318 -75
- package/skills/bk-rum-otele/references/getting-started.md +186 -70
- package/skills/bk-rum-otele/references/network.md +258 -0
- package/skills/bk-rum-otele/references/performance.md +198 -0
- package/skills/bk-rum-otele/references/privacy.md +236 -67
- package/skills/bk-rum-otele/references/production.md +266 -0
- package/skills/bk-rum-otele/references/session-context.md +185 -0
- package/skills/bk-rum-otele/references/telemetry-reference.md +500 -51
- package/skills/bk-rum-otele/references/transport-sampling.md +321 -32
- package/skills/bk-rum-otele/references/troubleshooting.md +341 -151
- package/skills/bk-rum-otele/references/views-routing.md +211 -0
- package/skills/bk-rum-otele/references/concepts.md +0 -60
- package/skills/bk-rum-otele/references/custom-plugin.md +0 -170
- package/skills/bk-rum-otele/references/plugins-basic.md +0 -135
- package/skills/bk-rum-otele/references/plugins-error-security.md +0 -86
- package/skills/bk-rum-otele/references/plugins-experience.md +0 -124
- package/skills/bk-rum-otele/references/plugins-network.md +0 -32
- package/skills/bk-rum-otele/references/plugins.md +0 -62
|
@@ -10,7 +10,7 @@ export interface BkOTBlankScreenPluginOptions {
|
|
|
10
10
|
confirmationDelay?: number;
|
|
11
11
|
/** loading、骨架屏等不参与空白比例计算的元素。 */
|
|
12
12
|
ignoreSelectors?: string[];
|
|
13
|
-
/** 应用挂载根节点,默认 body
|
|
13
|
+
/** 应用挂载根节点,默认 body。根节点不存在时回退到 body 检测。 */
|
|
14
14
|
rootSelector?: string;
|
|
15
15
|
/** 空白采样点比例阈值,默认 0.8。 */
|
|
16
16
|
threshold?: number;
|
package/dist/plugins/common.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { REQUEST_DISCARD_ATTRIBUTE } from '../core/processor';
|
|
2
|
-
import type { BkOTRequestConfig, BkOTRequestContext } from '../core/config';
|
|
2
|
+
import type { BkOTRequestConfig, BkOTRequestContext, BkOTRequestOutcome } from '../core/config';
|
|
3
3
|
import type { BkOTPlugin, BkOTRuntimeContext } from '../core/plugin';
|
|
4
4
|
import type { Span } from '@opentelemetry/api';
|
|
5
5
|
interface RequestDetails {
|
|
@@ -8,5 +8,5 @@ interface RequestDetails {
|
|
|
8
8
|
url?: string;
|
|
9
9
|
}
|
|
10
10
|
export { REQUEST_DISCARD_ATTRIBUTE };
|
|
11
|
-
export declare const decorateRequestSpan: (context: BkOTRuntimeContext, span: Span, subtype: "fetch" | "xhr", domainContext: BkOTRequestContext, details?: RequestDetails) => void;
|
|
11
|
+
export declare const decorateRequestSpan: (context: BkOTRuntimeContext, span: Span, subtype: "fetch" | "xhr", domainContext: BkOTRequestContext, outcome: BkOTRequestOutcome, details?: RequestDetails) => void;
|
|
12
12
|
export declare const createCommonInstrumentationsPlugin: (option: BkOTRequestConfig | boolean | undefined) => BkOTPlugin;
|
package/dist/plugins/device.d.ts
CHANGED
|
@@ -20,8 +20,8 @@ export declare const getDeviceResourceAttributes: () => Attributes;
|
|
|
20
20
|
* - viewport 监听 `resize` / `orientationchange`,并经 250ms debounce 合并,避免拖窗口时高频触发;
|
|
21
21
|
* 静默期结束后用最终值刷新 runtimeAttributes。
|
|
22
22
|
* - network 监听 `connection.change`(本身低频,不需要 throttle)。
|
|
23
|
-
* - 二者只更新 in-memory 的 runtimeAttributes,不会主动产生新的
|
|
24
|
-
*
|
|
23
|
+
* - 二者只更新 in-memory 的 runtimeAttributes,不会主动产生新的 Span;
|
|
24
|
+
* 更新后续生成的 Span 会带最新值。
|
|
25
25
|
*
|
|
26
26
|
* 与 session 插件的关系:device 跨会话持久(终身),session 有过期与续期(连续访问语义)。
|
|
27
27
|
*/
|
|
@@ -9,6 +9,7 @@ type ResourceTimingWithStatus = PerformanceResourceTiming & {
|
|
|
9
9
|
responseStatus?: number;
|
|
10
10
|
};
|
|
11
11
|
export declare const getResourceTimingAttributes: (entry: ResourceTimingWithStatus) => Record<string, number>;
|
|
12
|
+
export declare const getResourceDuration: (entry: ResourceTimingWithStatus) => number;
|
|
12
13
|
export declare const getResourcePerformanceAttributes: (entry: ResourceTimingWithStatus) => {
|
|
13
14
|
'resource.encoded_body_size': number;
|
|
14
15
|
'resource.decoded_body_size': number;
|
|
@@ -8,9 +8,7 @@
|
|
|
8
8
|
* (LCP 元素 url / CLS shift target / INP interaction target 等高基数字段),
|
|
9
9
|
* 方便按个例排查"哪个元素拖累了 LCP"
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
* - browser.web_vital.cls:单位 '1'(无量纲),CLS 是累积分数,不能与 ms 混用
|
|
13
|
-
* - browser.web_vital.duration:单位 'ms',FCP/INP/LCP/TTFB 共享,靠 vital.metric 维度区分
|
|
11
|
+
* 数值语义:CLS 是无量纲分数,FCP/INP/LCP/TTFB 的 vital.value 单位为 ms。
|
|
14
12
|
*
|
|
15
13
|
* Navigation Type:
|
|
16
14
|
* 优先使用 metric.navigationType(web-vitals 内部计算,含 'back-forward-cache' 等准确值),
|
|
@@ -18,11 +18,6 @@ export declare const RUM_ATTRIBUTES: {
|
|
|
18
18
|
readonly deviceLogicalProcessorCount: "device.logical_processor_count";
|
|
19
19
|
readonly deviceMemoryGib: "device.memory_gib";
|
|
20
20
|
readonly deviceType: "device.type";
|
|
21
|
-
readonly eventId: "event.id";
|
|
22
|
-
readonly eventPhase: "event.phase";
|
|
23
|
-
readonly eventTimestamp: "event.timestamp";
|
|
24
|
-
readonly eventType: "event.type";
|
|
25
|
-
readonly errorType: "error_type";
|
|
26
21
|
readonly longTaskBlockingDuration: "long_task.blocking_duration";
|
|
27
22
|
readonly longTaskDuration: "long_task.duration";
|
|
28
23
|
readonly longTaskEntryType: "long_task.entry_type";
|
|
@@ -30,7 +25,8 @@ export declare const RUM_ATTRIBUTES: {
|
|
|
30
25
|
readonly longTaskStartTime: "long_task.start_time";
|
|
31
26
|
readonly networkEffectiveType: "network.effective_type";
|
|
32
27
|
readonly nextHopProtocol: "resource.protocol";
|
|
33
|
-
readonly
|
|
28
|
+
readonly outcomeReason: "outcome.reason";
|
|
29
|
+
readonly outcomeType: "outcome.type";
|
|
34
30
|
readonly rumSchemaVersion: "rum.schema.version";
|
|
35
31
|
readonly serviceName: "service.name";
|
|
36
32
|
readonly serviceVersion: "service.version";
|
|
@@ -38,9 +34,9 @@ export declare const RUM_ATTRIBUTES: {
|
|
|
38
34
|
readonly sessionHasReplay: "session.has_replay";
|
|
39
35
|
readonly sessionId: "session.id";
|
|
40
36
|
readonly sessionSampleRate: "session.sample_rate";
|
|
37
|
+
readonly sessionPhase: "session.phase";
|
|
41
38
|
readonly sessionStartTime: "session.start_time";
|
|
42
39
|
readonly sessionType: "session.type";
|
|
43
|
-
readonly spanSubtype: "span_subtype";
|
|
44
40
|
readonly spanType: "span_type";
|
|
45
41
|
readonly userId: "user.id";
|
|
46
42
|
readonly vitalMetric: "vital.metric";
|
|
@@ -55,9 +51,12 @@ export declare const RUM_ATTRIBUTES: {
|
|
|
55
51
|
readonly viewLoadingTime: "view.loading_time";
|
|
56
52
|
readonly viewLoadingType: "view.loading_type";
|
|
57
53
|
readonly viewName: "view.name";
|
|
54
|
+
readonly viewPhase: "view.phase";
|
|
55
|
+
readonly viewSource: "view.source";
|
|
58
56
|
readonly viewStartedAt: "view.started_at";
|
|
59
57
|
readonly viewUrl: "view.url";
|
|
60
58
|
readonly viewUrlPathGroup: "view.url_path_group";
|
|
61
59
|
readonly viewVersion: "view.version";
|
|
60
|
+
readonly websocketPhase: "websocket.phase";
|
|
62
61
|
};
|
|
63
62
|
export type RumAttributeKey = (typeof RUM_ATTRIBUTES)[keyof typeof RUM_ATTRIBUTES];
|
package/dist/schema/span.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Attributes } from '@opentelemetry/api';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const RUM_SPAN_OUTCOME: {
|
|
3
3
|
readonly abort: "abort";
|
|
4
4
|
readonly error: "error";
|
|
5
5
|
readonly success: "success";
|
|
@@ -9,38 +9,47 @@ export declare const RUM_SPAN_RESULT: {
|
|
|
9
9
|
export declare const RUM_SPAN_TYPE: {
|
|
10
10
|
readonly action: "action";
|
|
11
11
|
readonly custom: "custom";
|
|
12
|
-
readonly document: "document";
|
|
13
12
|
readonly error: "error";
|
|
14
|
-
readonly
|
|
13
|
+
readonly longTask: "long_task";
|
|
15
14
|
readonly resource: "resource";
|
|
16
|
-
readonly route: "route";
|
|
17
15
|
readonly session: "session";
|
|
18
16
|
readonly vital: "vital";
|
|
17
|
+
readonly view: "view";
|
|
19
18
|
readonly websocket: "websocket";
|
|
20
19
|
};
|
|
20
|
+
export type RumRequestOutcome = {
|
|
21
|
+
error?: unknown;
|
|
22
|
+
type: 'network_error';
|
|
23
|
+
} | {
|
|
24
|
+
error?: unknown;
|
|
25
|
+
type: 'timeout';
|
|
26
|
+
} | {
|
|
27
|
+
statusCode?: number;
|
|
28
|
+
type: 'response';
|
|
29
|
+
} | {
|
|
30
|
+
type: 'abort';
|
|
31
|
+
};
|
|
21
32
|
export interface RumResourceSpanInput {
|
|
22
33
|
initiatorType?: string;
|
|
23
34
|
method?: string;
|
|
24
|
-
|
|
25
|
-
responseStatus?: number;
|
|
35
|
+
outcome?: RumRequestOutcome;
|
|
26
36
|
transferSize?: number;
|
|
27
37
|
url: string;
|
|
28
38
|
}
|
|
29
39
|
export interface RumSpanClassification {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
spanSubtype: string;
|
|
40
|
+
outcome?: RumSpanOutcome;
|
|
41
|
+
outcomeReason?: string;
|
|
33
42
|
spanType: RumSpanType;
|
|
34
43
|
}
|
|
35
|
-
export type
|
|
44
|
+
export type RumSpanOutcome = (typeof RUM_SPAN_OUTCOME)[keyof typeof RUM_SPAN_OUTCOME];
|
|
36
45
|
export type RumSpanType = (typeof RUM_SPAN_TYPE)[keyof typeof RUM_SPAN_TYPE];
|
|
37
46
|
export interface RumUrlTarget {
|
|
38
47
|
serverAddress?: string;
|
|
39
48
|
serverPort?: number;
|
|
40
49
|
}
|
|
41
|
-
export declare const
|
|
42
|
-
export declare const
|
|
43
|
-
export declare const
|
|
50
|
+
export declare const getHttpOutcome: (statusCode: number | undefined) => RumSpanOutcome;
|
|
51
|
+
export declare const getHttpOutcomeReason: (statusCode: number | undefined) => "network_timeout" | "http_5xx" | "http_4xx" | undefined;
|
|
52
|
+
export declare const getVitalOutcome: (rating: string | undefined) => RumSpanOutcome;
|
|
44
53
|
export declare const getUrlTarget: (url: string | undefined) => RumUrlTarget;
|
|
45
|
-
export declare const buildRumSpanAttributes: ({
|
|
46
|
-
export declare const buildRumResourceSpanAttributes: ({ initiatorType, method,
|
|
54
|
+
export declare const buildRumSpanAttributes: ({ outcome, outcomeReason, spanType, }: RumSpanClassification) => Attributes;
|
|
55
|
+
export declare const buildRumResourceSpanAttributes: ({ initiatorType, method, outcome, transferSize, url, }: RumResourceSpanInput) => Attributes;
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ description: 帮助业务方在前端应用里接入、使用和配置蓝鲸 RUM
|
|
|
5
5
|
|
|
6
6
|
# 蓝鲸 RUM OpenTelemetry SDK 接入助手
|
|
7
7
|
|
|
8
|
-
`@blueking/open-telemetry` 是蓝鲸 RUM 的浏览器上报 SDK,基于 OpenTelemetry Web SDK,把页面访问、接口请求、静态资源、JS 错误、Web Vitals、白屏、设备、会话、用户动作等浏览器事件统一转成
|
|
8
|
+
`@blueking/open-telemetry` 是蓝鲸 RUM 的浏览器上报 SDK,基于 OpenTelemetry Web SDK,把页面访问、接口请求、静态资源、JS 错误、Web Vitals、白屏、设备、会话、用户动作等浏览器事件统一转成 RUM Span,通过唯一的 OTLP HTTP Trace 通道上报到 collector。
|
|
9
9
|
|
|
10
10
|
本 skill 面向**集成使用方**:帮助把 SDK 接入到自己的前端应用,包括安装、配置、按需开关采集能力、框架集成、隐私脱敏、排障和手动上报。不覆盖 SDK 源码本身的开发维护。
|
|
11
11
|
|
|
@@ -21,34 +21,34 @@ description: 帮助业务方在前端应用里接入、使用和配置蓝鲸 RUM
|
|
|
21
21
|
|
|
22
22
|
| 用户想做的事 | 读取 |
|
|
23
23
|
| ------------------------------------------------------------------------------------------- | ------------------------------------- |
|
|
24
|
-
| 第一次接入、安装、最小示例、CDN
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
| 配置
|
|
32
|
-
|
|
|
33
|
-
| 配置
|
|
34
|
-
| 配置
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
24
|
+
| 第一次接入、安装、最小示例、CDN、第一次数据验证 | `references/getting-started.md` |
|
|
25
|
+
| 生产上线、采样容量、Collector/CORS、灰度与验收 | `references/production.md` |
|
|
26
|
+
| 评估 SDK 能力边界、默认开关、浏览器 API、信号产出和降级行为 | `references/capabilities.md` |
|
|
27
|
+
| 理解源码模块、初始化顺序、运行时上下文、过滤链路和 Hook 时机 | `references/architecture.md` |
|
|
28
|
+
| 理解 OTLP 层级、Session/View/Action 关联、字段归属和服务端派生 | `references/data-model.md` |
|
|
29
|
+
| 配置 Session、用户、Device、持久化和跨 Tab | `references/session-context.md` |
|
|
30
|
+
| 配置自动/手动 View、Router、BFCache 和 View Loading Time | `references/views-routing.md` |
|
|
31
|
+
| 配置 Fetch/XHR、Resource Timing、Trace Header 和 WebSocket | `references/network.md` |
|
|
32
|
+
| 配置自动 Action、手动 Action、命名和 Rage/Dead/Error Click | `references/actions.md` |
|
|
33
|
+
| 配置 Web Vitals、Long Task 及其浏览器降级 | `references/performance.md` |
|
|
34
|
+
| 配置 JS/Promise/资源错误、exception 和 CSP Violation | `references/errors-security.md` |
|
|
35
|
+
| 配置白屏根节点、阈值、忽略元素和处理误报 | `references/blank-screen.md` |
|
|
36
|
+
| 写自定义 BkOTPlugin、接入第三方 OpenTelemetry Instrumentation | `references/extensions.md` |
|
|
37
|
+
| 查全部配置项、默认值、Endpoint、插件参数和 Hook | `references/configuration.md` |
|
|
38
|
+
| 查公开 API(start/flush/shutdown/setUser/startView/reportAction/reportCustomEvent 等) | `references/api.md` |
|
|
39
|
+
| Vue / React / Router / SSR / 微前端集成 | `references/framework-integration.md` |
|
|
40
|
+
| URL/属性脱敏、Consent、低基数路由、user.id 和服务端隐私责任 | `references/privacy.md` |
|
|
41
|
+
| 查 Transport、OTLP JSON、批量队列、重试、keepalive、Session 采样和 CORS | `references/transport-sampling.md` |
|
|
42
|
+
| 查具体 Span 名、OTLP Envelope、Resource/Span/Event 完整字段字典 | `references/telemetry-reference.md` |
|
|
43
|
+
| 没有数据、手动事件没上报、白屏误报、接口 Span 太多、字段缺失等排障 | `references/troubleshooting.md` |
|
|
42
44
|
|
|
43
45
|
> `references/` 由 `packages/open-telemetry/scripts/gen-skill-references.mjs` 从 SDK 的 `wikis/` 自动生成,请勿手改。如内容过期,让维护者重新执行 `pnpm --filter @blueking/open-telemetry skill:refs`。
|
|
44
46
|
|
|
45
47
|
## 核心心智模型
|
|
46
48
|
|
|
47
|
-
###
|
|
49
|
+
### 单一 Trace 信号
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
- **Metric**:可聚合的数值——Web Vitals、长任务数、WebSocket 消息大小、白屏结果。
|
|
51
|
-
- **Log**:离散事件——错误、CSP 违规、会话生命周期、HTTP body 错误路径。
|
|
51
|
+
SDK 只创建 Trace Provider。页面、请求、资源、错误、Vital、白屏和生命周期事件都编码为 RUM Span;计数、直方图、分位数、错误分组和跨事件聚合由服务端完成。
|
|
52
52
|
|
|
53
53
|
### 内置采集与扩展
|
|
54
54
|
|
|
@@ -59,15 +59,15 @@ SDK 把能力拆成两类:
|
|
|
59
59
|
|
|
60
60
|
### 会话级确定性采样
|
|
61
61
|
|
|
62
|
-
`session.sampleRate`(0–1,默认 1
|
|
62
|
+
`session.sampleRate`(0–1,默认 1)是**会话级确定性采样**,不是单条 Span 级。决定由 `application.name + session.id` 的稳定 hash 得出,同一 Session 的所有 Span 决定一致。插件仍维护必要的浏览器生命周期,但未命中时数据不会导出,`reportAction()`、`reportCustomEvent()` 会被静默丢弃。调试时临时设 `sampleRate: 1` 和 `debug: true`。
|
|
63
63
|
|
|
64
64
|
### 运行时上下文
|
|
65
65
|
|
|
66
|
-
SDK 维护公共上下文并自动挂到后续
|
|
66
|
+
SDK 维护公共上下文并自动挂到后续 Span 上:`user.id`(业务方提供,SDK 原样透传、不 hash 不脱敏)、`session.id`(Session 生成/轮换)、`view.*`(View 管理器维护)和活动窗口内的 `action.id`。运行中可用 `setUser()` 更新用户;手动 View 使用 `startView()` 划界、`setViewName()` 改名。
|
|
67
67
|
|
|
68
68
|
### 数据归一
|
|
69
69
|
|
|
70
|
-
SDK 为
|
|
70
|
+
SDK 为 Span 补充归一字段便于统一检索:`span_type`(session/view/resource/vital/error/long_task/action/websocket/custom)、`outcome.type`(success/warning/error/timeout/abort)和可选 `outcome.reason`。具体子类由 `resource.type`、`vital.metric`、`error.source` 等领域字段表达;Fetch/XHR 与静态资源统一为 resource,通过 `resource.type` 区分。
|
|
71
71
|
|
|
72
72
|
## 最小接入速查
|
|
73
73
|
|
|
@@ -95,7 +95,7 @@ CDN:
|
|
|
95
95
|
</script>
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
`transport.endpoint`
|
|
98
|
+
`transport.endpoint` 是必填上报根地址,可以包含网关前缀,但不要包含最终 `/v1/rum`;SDK 去除末尾斜杠后自动追加 `/v1/rum`。SDK 不创建 Metric/Log Provider,所有原始 RUM 事件统一走 Trace Span。`token` 作为 `Authorization: Bearer <token>` 默认头。构造后默认 `autoStart: true` 异步启动;如果要确保首个手动事件不丢,应改用 `autoStart: false` 并显式 `await start()`。
|
|
99
99
|
|
|
100
100
|
## 默认采集能力清单
|
|
101
101
|
|
|
@@ -103,15 +103,16 @@ CDN:
|
|
|
103
103
|
|
|
104
104
|
- 基础能力:Session、View;内置采集:`request`、`action`、`resource`、`error`、`webVitals`、`blankScreen`、`device`
|
|
105
105
|
|
|
106
|
-
View Loading Time 默认开启;默认关闭、按需打开:`longTask`、`cspViolation`、`websocket`。关闭默认能力时显式设为 `false
|
|
106
|
+
View Loading Time 默认开启;默认关闭、按需打开:`longTask`、`cspViolation`、`websocket`。关闭默认能力时显式设为 `false`。各能力参数按「任务路由」读取对应主题 reference。
|
|
107
107
|
|
|
108
108
|
## 关键易错点
|
|
109
109
|
|
|
110
110
|
- **单实例**:`fetch`/`xhr`/`action`/`websocket` 会 patch 或监听全局 API,同页面只应初始化一个 SDK 实例,微前端只在主应用初始化一次。
|
|
111
111
|
- **`use()` / `useInstrumentation()` 必须在 `start()` 之前**:要注册自定义插件或 instrumentation,请设 `autoStart: false` 再手动 `start()`。
|
|
112
112
|
- **采样影响手动上报**:未命中采样时 `reportAction()` / `reportCustomEvent()` 静默丢弃,排查时先确认采样。
|
|
113
|
-
-
|
|
114
|
-
-
|
|
113
|
+
- **手动事件不排队**:异步 autoStart 尚未建立 View 时立即调用的手动事件可能被过滤;确定性时序使用 `autoStart: false`、`await start()`,manual View 再先调用 `startView()`。
|
|
114
|
+
- **隐私要业务显式配置**:SDK 不猜哪些字段敏感,URL、属性需通过 `privacy` / `request.beforeSend` 显式处理;SDK 不采集 HTTP Body;`user.id` 需 hash 的话要在传入前处理。`tracking.beforeSend` 新写入的字段不会再次自动经过 `redactAttributes`。
|
|
115
|
+
- **Consent**:未授权初始化时配置 `privacy.trackingConsent: 'not-granted'`,用户授权后调用 `setTrackingConsent('granted')`;撤销授权会停止采集并解除 patch。该配置不会阻止构造阶段读取 Device Resource 快照;要求授权前零读取时必须延迟构造 SDK。
|
|
115
116
|
- **单一信号**:只有 `/v1/rum` Trace 通道;计数、直方图、分位数、错误指纹和跨事件聚合由服务端完成。
|
|
116
117
|
- **低基数路由**:用 `tracking.view.getPathGroup` 把 `/user/123` 归类成 `/user/:id`,避免高基数 URL 污染指标维度。
|
|
117
118
|
- **手动 View 的时机**:使用 `autoStart: false`,先 `await start()` 建立 Session,再调用 `startView()`;启动前调用会因没有有效采样 Session 而被忽略。
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<!-- 本文件由 packages/open-telemetry/scripts/gen-skill-references.mjs 从 wikis 自动生成,请勿手改。 -->
|
|
2
|
+
|
|
3
|
+
# 用户 Action 与挫败信号
|
|
4
|
+
|
|
5
|
+
Action 表示一次用户操作以及操作后引发的页面活动。SDK 默认自动监听 click,也提供 `reportAction()` 上报业务命名动作。自动 Action 才计算 Loading Time、页面活动和挫败信号。
|
|
6
|
+
|
|
7
|
+
## 自动 Action 生命周期
|
|
8
|
+
|
|
9
|
+
一次 click 的处理过程:
|
|
10
|
+
|
|
11
|
+
1. 从 Event 取得真实发生时间和 composed target。
|
|
12
|
+
2. 生成 `action.id`,保存当时的 Session/View 上下文。
|
|
13
|
+
3. 把活动中的 Action ID 写入运行时上下文,后续请求、资源、错误和 Long Task 自动关联。
|
|
14
|
+
4. 观察请求、DOM Mutation、Resource、Long Task、Error 和部分用户行为。
|
|
15
|
+
5. 发生过页面活动后,等待所有请求完成并连续 100ms 无活动。
|
|
16
|
+
6. 最长等待 `maxDuration`,默认 10 秒。
|
|
17
|
+
7. 从运行时上下文移除 Action ID。
|
|
18
|
+
8. 最多再等待到 click 后 1 秒完成 Rage Click 判断。
|
|
19
|
+
9. 创建并结束 `action.click` Span。
|
|
20
|
+
|
|
21
|
+
上报等待期不会延长 Action 关联窗口;后续无关事件不会因为等待 Rage Click 判断而关联旧 Action。
|
|
22
|
+
|
|
23
|
+
## Action 活动
|
|
24
|
+
|
|
25
|
+
会影响 Loading Time 的活动:
|
|
26
|
+
|
|
27
|
+
- Fetch/XHR 开始和结束;
|
|
28
|
+
- 静态资源完成;
|
|
29
|
+
- DOM Mutation;
|
|
30
|
+
- Long Task;
|
|
31
|
+
- Error;
|
|
32
|
+
- `window.open`。
|
|
33
|
+
|
|
34
|
+
Error 会把 Action 标记为发生过活动、更新结束时间并标记 `error_click`;Long Task 也只影响 Action Activity。View Loading Time 的稳定判断会忽略 Error 和 Long Task。`view.excludedActivityUrls` 命中的请求/资源不参与 Action 活动。
|
|
35
|
+
|
|
36
|
+
点击后 100ms 内没有任何页面活动时,Action 以零持续时间结束且没有 `action.loading_time`;它仍可能被识别为 Dead Click。
|
|
37
|
+
|
|
38
|
+
## 自动命名
|
|
39
|
+
|
|
40
|
+
默认配置:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
tracking: {
|
|
44
|
+
action: {
|
|
45
|
+
actionNameAttribute: 'data-bk-action-name',
|
|
46
|
+
maxDuration: 10_000,
|
|
47
|
+
nameCollection: 'explicit',
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`explicit` 模式从目标元素向上查找指定属性;找不到时只使用目标标签名。推荐:
|
|
53
|
+
|
|
54
|
+
```html
|
|
55
|
+
<button data-bk-action-name="提交订单">提交</button>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
遥测中的名称为 `Click on 提交订单`,同时写入:
|
|
59
|
+
|
|
60
|
+
- `action.target.name=提交订单`
|
|
61
|
+
- `action.target.tag=button`
|
|
62
|
+
|
|
63
|
+
名称会合并连续空白、截断到 100 字符。
|
|
64
|
+
|
|
65
|
+
## 文本命名模式
|
|
66
|
+
|
|
67
|
+
`nameCollection='text'` 才会继续读取:
|
|
68
|
+
|
|
69
|
+
1. 关联 label;
|
|
70
|
+
2. button/reset/submit input value;
|
|
71
|
+
3. button、label、`role=button` 文本;
|
|
72
|
+
4. `aria-label`、`alt`、`name`、`title`、`placeholder`;
|
|
73
|
+
5. DOM textContent;
|
|
74
|
+
6. 从目标开始,最多继续检查 10 层父级;遇到 form/body/html/head 停止。
|
|
75
|
+
|
|
76
|
+
该模式可能采集用户输入、订单内容或个人信息。生产环境优先使用 `explicit`,只有完成隐私评估后才启用文本模式。
|
|
77
|
+
|
|
78
|
+
## Rage Click
|
|
79
|
+
|
|
80
|
+
满足以下条件时标记 `rage_click`:
|
|
81
|
+
|
|
82
|
+
- 1 秒内至少三次 click;
|
|
83
|
+
- 点击目标是同一个 DOM Element;
|
|
84
|
+
- 相邻点击坐标距离不超过 100px;
|
|
85
|
+
- 期间没有 scroll 或 selectionchange 中断点击链。
|
|
86
|
+
|
|
87
|
+
前三次点击仍各自保留独立 Action Span,并带 Rage Click 语义,不合并成一条事件。
|
|
88
|
+
|
|
89
|
+
## Dead Click
|
|
90
|
+
|
|
91
|
+
点击后没有页面活动,且没有 input、scroll 或文本选择时,候选为 `dead_click`。以下目标因行为难以可靠判断而排除:
|
|
92
|
+
|
|
93
|
+
- 带 href 的链接;
|
|
94
|
+
- `select`、`textarea`、`canvas`;
|
|
95
|
+
- `contenteditable`;
|
|
96
|
+
- 文本类 input;
|
|
97
|
+
- 指向以上控件的 label。
|
|
98
|
+
|
|
99
|
+
button、checkbox、radio、range、reset、submit input 仍可判断。
|
|
100
|
+
|
|
101
|
+
## Error Click
|
|
102
|
+
|
|
103
|
+
Action 活动窗口内发生由 Activity Bus 通知的前端错误时,标记 `error_click`。Error 不要求是 Action Span 的子 Span,只要事件时间落在活动窗口并带同一 `action.id` 即可在服务端关联。
|
|
104
|
+
|
|
105
|
+
## Outcome 与字段
|
|
106
|
+
|
|
107
|
+
自动 Action Span:
|
|
108
|
+
|
|
109
|
+
| 条件 | `outcome.type` | 具体语义 |
|
|
110
|
+
| --- | --- | --- |
|
|
111
|
+
| 无错误、无挫败 | `success` | 无 |
|
|
112
|
+
| 有前端错误 | `warning` | `action.frustration.type=error_click` |
|
|
113
|
+
| 只有 Rage/Dead Click | `warning` | `action.frustration.type` 对应值 |
|
|
114
|
+
|
|
115
|
+
关键字段:
|
|
116
|
+
|
|
117
|
+
- `action.id`
|
|
118
|
+
- `action.type=click`
|
|
119
|
+
- `action.name`
|
|
120
|
+
- `action.target.name`
|
|
121
|
+
- `action.target.tag`
|
|
122
|
+
- `action.loading_time`,只有观察到页面活动时存在,单位 ms
|
|
123
|
+
- `action.frustration.type`,按 `rage_click`、`dead_click`、`error_click` 固定顺序的数组
|
|
124
|
+
|
|
125
|
+
SDK 不在 Action Span 中写请求数、资源数、错误数或 Long Task 数;服务端通过 `action.id` 关联原始事件后派生。
|
|
126
|
+
|
|
127
|
+
## 手动 Action
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
bkOT.reportAction({
|
|
131
|
+
name: '立即支付',
|
|
132
|
+
attributes: {
|
|
133
|
+
'biz.order_type': 'normal',
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
它立即创建并结束 `action.custom`:
|
|
139
|
+
|
|
140
|
+
- 新生成独立 `action.id`;
|
|
141
|
+
- `action.type=custom`;
|
|
142
|
+
- `action.name` 使用传入名称;
|
|
143
|
+
- `span_type=action`、`outcome.type=success`;
|
|
144
|
+
- 不建立活动窗口;
|
|
145
|
+
- 不计算 Loading Time 或挫败信号;
|
|
146
|
+
- 不把该 ID挂到后续请求/错误。
|
|
147
|
+
|
|
148
|
+
未采样、未授权或没有有效 View 时不会导出。`reportAction()` 未采样时静默返回。
|
|
149
|
+
|
|
150
|
+
## Flush 与页面退出
|
|
151
|
+
|
|
152
|
+
页面隐藏、pagehide、Session 过期、插件 flush 或 shutdown 时,SDK会结束仍活动的 Action,并立即落数等待中的 Rage Click Action,避免正常生命周期中积压。
|
|
153
|
+
|
|
154
|
+
## 常见问题
|
|
155
|
+
|
|
156
|
+
### Action 名称只有标签名
|
|
157
|
+
|
|
158
|
+
这是默认隐私行为。为元素或祖先添加 `data-bk-action-name`,或显式配置其他 `actionNameAttribute`。
|
|
159
|
+
|
|
160
|
+
### 点击有请求但没有 Loading Time
|
|
161
|
+
|
|
162
|
+
检查请求是否命中 `view.excludedActivityUrls`,click 是否在请求开始前被其他监听逻辑延迟,以及 Action 是否在未采样/无 View 状态发生。
|
|
163
|
+
|
|
164
|
+
### Dead Click 过多
|
|
165
|
+
|
|
166
|
+
确认自定义控件是否由普通 `div` 实现但实际承担输入/跳转行为;可让点击产生可观察活动、改用语义化元素,或关闭自动 Action 并使用手动上报。当前配置没有单独关闭某一种挫败信号的选项。
|