@blueking/open-telemetry 0.0.4 → 0.0.6

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.
@@ -0,0 +1,2 @@
1
+ import { BkOpenTelemetry } from './core/sdk';
2
+ export default BkOpenTelemetry;
@@ -0,0 +1,138 @@
1
+ import type { BkOTPlugin } from './plugin';
2
+ import type { Attributes } from '@opentelemetry/api';
3
+ import type { Instrumentation } from '@opentelemetry/instrumentation';
4
+ export interface BkOTAttributesConfig {
5
+ custom?: () => Attributes;
6
+ error?: () => Attributes;
7
+ metric?: () => Attributes;
8
+ page?: () => Attributes;
9
+ }
10
+ export type BkOTAttributeValue = boolean | number | string;
11
+ export interface BkOTBatchConfig {
12
+ exportTimeoutMillis?: number;
13
+ maxExportBatchSize?: number;
14
+ maxQueueSize?: number;
15
+ scheduledDelayMillis?: number;
16
+ }
17
+ export interface BkOTConfig {
18
+ attributes?: BkOTAttributesConfig;
19
+ autoStart?: boolean;
20
+ debug?: boolean;
21
+ enabled?: boolean;
22
+ endpoint?: string;
23
+ environment?: string;
24
+ headers?: Record<string, string>;
25
+ instrumentations?: Instrumentation[];
26
+ logs?: SignalExporterInputConfig;
27
+ metrics?: SignalExporterInputConfig;
28
+ plugins?: BkOTPlugin[];
29
+ redact?: BkOTRedactConfig;
30
+ rum?: BkOTRumConfig;
31
+ sampleRate?: number;
32
+ signalEndpoints?: SignalEndpointsConfig;
33
+ spanBatch?: BkOTBatchConfig;
34
+ spanProcessor?: BkOTSpanProcessorMode;
35
+ token?: string;
36
+ traces?: SignalExporterInputConfig;
37
+ }
38
+ export interface BkOTCustomEventPayload {
39
+ attributes?: Attributes;
40
+ error?: Error;
41
+ name: string;
42
+ }
43
+ export interface BkOTHttpBodyConfig {
44
+ maxBodySize?: number;
45
+ redact?: (payload: BkOTHttpBodyRedactPayload) => string;
46
+ }
47
+ export interface BkOTHttpBodyRedactPayload {
48
+ body: string;
49
+ contentType?: string;
50
+ method: string;
51
+ status?: number;
52
+ truncated: boolean;
53
+ type: 'request' | 'response';
54
+ url: string;
55
+ }
56
+ export interface BkOTInstrumentationsConfig {
57
+ documentLoad?: boolean;
58
+ fetch?: boolean;
59
+ userInteraction?: boolean | {
60
+ eventNames?: string[];
61
+ };
62
+ xhr?: boolean;
63
+ }
64
+ export interface BkOTRedactConfig {
65
+ attributes?: (attributes: Attributes) => Attributes;
66
+ url?: (url: string) => string;
67
+ }
68
+ export interface BkOTRumConfig extends BkOTInstrumentationsConfig {
69
+ cspViolation?: boolean;
70
+ device?: boolean | {
71
+ storageKey?: string;
72
+ };
73
+ httpBody?: BkOTHttpBodyConfig | boolean;
74
+ pageView?: boolean;
75
+ routeTiming?: boolean;
76
+ websocket?: boolean;
77
+ webVitals?: boolean;
78
+ blankScreen?: {
79
+ checkDelay?: number;
80
+ ignoreSelectors?: string[];
81
+ rootSelector?: string;
82
+ threshold?: number;
83
+ } | boolean;
84
+ error?: {
85
+ maxPerWindow?: number;
86
+ windowMs?: number;
87
+ } | boolean;
88
+ longTask?: {
89
+ threshold?: number;
90
+ } | boolean;
91
+ session?: {
92
+ inactivityMs?: number;
93
+ maxLifetimeMs?: number;
94
+ storageKey?: string;
95
+ } | boolean;
96
+ }
97
+ export type BkOTSpanProcessorMode = 'batch' | 'simple';
98
+ export interface NormalizedBkOTConfig extends Omit<BkOTConfig, 'attributes' | 'autoStart' | 'debug' | 'enabled' | 'endpoint' | 'environment' | 'instrumentations' | 'logs' | 'metrics' | 'plugins' | 'redact' | 'signalEndpoints' | 'spanProcessor' | 'token' | 'traces'> {
99
+ autoStart: boolean;
100
+ debug: boolean;
101
+ enabled: boolean;
102
+ endpoint: string;
103
+ environment: string;
104
+ instrumentations: Instrumentation[];
105
+ logs: SignalExporterConfig;
106
+ metricIntervalMillis: number;
107
+ metrics: SignalExporterConfig;
108
+ plugins: BkOTPlugin[];
109
+ resourceAttributes: Attributes;
110
+ sampleRate: number;
111
+ spanProcessor: BkOTSpanProcessorMode;
112
+ traces: SignalExporterConfig;
113
+ getCustomAttributes: () => Attributes;
114
+ getErrorAttributes: () => Attributes;
115
+ getMetricAttributes: () => Attributes;
116
+ getPageAttributes: () => Attributes;
117
+ redactAttributes: (attributes: Attributes) => Attributes;
118
+ redactUrl: (url: string) => string;
119
+ commonInstrumentations: Required<Pick<BkOTInstrumentationsConfig, 'documentLoad' | 'fetch' | 'xhr'>> & {
120
+ userInteraction: BkOTInstrumentationsConfig['userInteraction'];
121
+ };
122
+ rum: Omit<Required<BkOTRumConfig>, 'documentLoad' | 'fetch' | 'httpBody' | 'userInteraction' | 'xhr'> & {
123
+ httpBody: false | Required<BkOTHttpBodyConfig>;
124
+ };
125
+ }
126
+ export interface SignalEndpointsConfig {
127
+ logs?: string;
128
+ metrics?: string;
129
+ traces?: string;
130
+ }
131
+ export interface SignalExporterConfig {
132
+ concurrencyLimit?: number;
133
+ endpoint: string;
134
+ headers?: Record<string, string>;
135
+ timeoutMillis?: number;
136
+ }
137
+ export type SignalExporterInputConfig = Partial<SignalExporterConfig>;
138
+ export declare const normalizeConfig: (config: BkOTConfig) => NormalizedBkOTConfig;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 生成随机 ID。优先用 `crypto.randomUUID`(standards-compliant UUID v4),不可用时回退到
3
+ * `${prefix}-${timestamp}-${rand}` 形式。
4
+ *
5
+ * 注意:fallback 实现使用 Math.random,**不是密码学安全**,仅适用于设备/会话/事件标识等场景,
6
+ * 不要复用此函数生成 token、CSRF 防护等安全相关的值。
7
+ */
8
+ export declare const createRandomId: (prefix: string) => string;
@@ -0,0 +1,46 @@
1
+ import type { NormalizedBkOTConfig } from './config';
2
+ import type { Attributes, Meter, Span, TimeInput, Tracer } from '@opentelemetry/api';
3
+ import type { Logger, LogRecord } from '@opentelemetry/api-logs';
4
+ export interface BkOTPlugin {
5
+ enabled?: ((config: NormalizedBkOTConfig) => boolean) | boolean;
6
+ name: string;
7
+ flush?: () => Promise<void> | void;
8
+ init: (context: BkOTRuntimeContext) => Promise<void> | void;
9
+ shutdown?: () => Promise<void> | void;
10
+ }
11
+ export interface BkOTRuntimeContext {
12
+ config: NormalizedBkOTConfig;
13
+ logger: Logger;
14
+ meter: Meter;
15
+ tracer: Tracer;
16
+ /** 对外提供的属性脱敏入口,所有插件在 emit 前都应过一次 */
17
+ applyRedact: (attributes: Attributes) => Attributes;
18
+ /** 包装 logger.emit,自动应用 redact 与 runtime attributes */
19
+ emitLog: (record: LogRecord) => void;
20
+ getRuntimeAttributes: () => Attributes;
21
+ setRuntimeAttributes: (attributes: Attributes) => void;
22
+ startSpan: (name: string, attributes?: Attributes, options?: BkOTStartSpanOptions) => Span;
23
+ }
24
+ /**
25
+ * startSpan 的扩展选项。
26
+ *
27
+ * 用于"事件实际发生在过去某个时刻,但 span 现在才创建"的场景:
28
+ * 例如 route-timing 在 raf+setTimeout 链路结束后才上报,但希望 span 的时间窗
29
+ * 反映真实的"路由切换瞬间到渲染完成"区间,方便 trace 视图与并发请求对齐。
30
+ *
31
+ * startTime 接受 OT TimeInput;常用 epoch 毫秒(performance.timeOrigin + performance.now())。
32
+ * 配合 span.end(endTime?) 可控制结束时间。
33
+ */
34
+ export interface BkOTStartSpanOptions {
35
+ startTime?: TimeInput;
36
+ }
37
+ export declare const isPluginEnabled: (plugin: BkOTPlugin, config: NormalizedBkOTConfig) => boolean;
38
+ export declare const createPlugin: (plugin: BkOTPlugin) => BkOTPlugin;
39
+ export declare class PluginManager {
40
+ private readonly plugins;
41
+ private startedPlugins;
42
+ constructor(plugins: BkOTPlugin[]);
43
+ flush(): Promise<void>;
44
+ shutdown(): Promise<void>;
45
+ start(context: BkOTRuntimeContext): Promise<void>;
46
+ }
@@ -0,0 +1,16 @@
1
+ import type { NormalizedBkOTConfig } from './config';
2
+ import type { Context } from '@opentelemetry/api';
3
+ import type { ReadableSpan, Span, SpanProcessor } from '@opentelemetry/sdk-trace-base';
4
+ /**
5
+ * 包装 SpanProcessor,在 onEnd 阶段过滤指向自身上报 endpoint 的 span,
6
+ * 兜底防止 official fetch/xhr 拦截器对 OTel 自身请求产生回环 span。
7
+ */
8
+ export declare class FilteringSpanProcessor implements SpanProcessor {
9
+ private readonly inner;
10
+ private readonly config;
11
+ constructor(inner: SpanProcessor, config: NormalizedBkOTConfig);
12
+ forceFlush(): Promise<void>;
13
+ onEnd(span: ReadableSpan): void;
14
+ onStart(span: Span, parentContext: Context): void;
15
+ shutdown(): Promise<void>;
16
+ }
@@ -0,0 +1,9 @@
1
+ export interface RouteChangeEvent {
2
+ fromUrl: string;
3
+ source: RouteChangeSource;
4
+ toUrl: string;
5
+ }
6
+ export type RouteChangeSource = 'hashchange' | 'popstate' | 'pushState' | 'replaceState';
7
+ type RouteChangeHandler = (event: RouteChangeEvent) => void;
8
+ export declare const subscribeRouteChange: (handler: RouteChangeHandler) => () => void;
9
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { NormalizedBkOTConfig } from './config';
2
+ export declare const isBkOTSampled: ({ sampleRate }: Pick<NormalizedBkOTConfig, "sampleRate">) => boolean;
@@ -0,0 +1,44 @@
1
+ import { type Attributes, type Span } from '@opentelemetry/api';
2
+ import { type Instrumentation } from '@opentelemetry/instrumentation';
3
+ import { type BkOTConfig, type BkOTCustomEventPayload, type NormalizedBkOTConfig } from './config';
4
+ import { type BkOTPlugin, type BkOTRuntimeContext, type BkOTStartSpanOptions } from './plugin';
5
+ import type { LogRecord } from '@opentelemetry/api-logs';
6
+ export interface BkOTInstance extends BkOTRuntimeContext {
7
+ flush: () => Promise<void>;
8
+ reportCustomEvent: (payload: BkOTCustomEventPayload) => void;
9
+ shutdown: () => Promise<void>;
10
+ start: () => Promise<void>;
11
+ use: (plugin: BkOTPlugin) => BkOTInstance;
12
+ useInstrumentation: (instrumentation: Instrumentation) => BkOTInstance;
13
+ }
14
+ export declare class BkOpenTelemetry implements BkOTInstance {
15
+ private readonly loggerProvider;
16
+ private readonly meterProvider;
17
+ private phase;
18
+ private readonly pluginManager;
19
+ private readonly plugins;
20
+ private readonly registeredInstrumentations;
21
+ private readonly runtimeAttributes;
22
+ private readonly sampled;
23
+ private readonly teardownCallbacks;
24
+ private readonly tracerProvider;
25
+ private assertBeforeStart;
26
+ readonly applyRedact: (attributes: Attributes) => Attributes;
27
+ readonly config: NormalizedBkOTConfig;
28
+ readonly emitLog: (record: LogRecord) => void;
29
+ readonly flush: () => Promise<void>;
30
+ readonly getRuntimeAttributes: () => {
31
+ [attributeKey: string]: import("@opentelemetry/api").AttributeValue | undefined;
32
+ };
33
+ readonly logger: BkOTRuntimeContext['logger'];
34
+ readonly meter: BkOTRuntimeContext['meter'];
35
+ readonly reportCustomEvent: ({ attributes, error, name }: BkOTCustomEventPayload) => void;
36
+ readonly setRuntimeAttributes: (attributes: Attributes) => void;
37
+ readonly shutdown: () => Promise<void>;
38
+ readonly start: () => Promise<void>;
39
+ readonly startSpan: (name: string, attributes?: Attributes, options?: BkOTStartSpanOptions) => Span;
40
+ readonly tracer: BkOTRuntimeContext['tracer'];
41
+ readonly use: (plugin: BkOTPlugin) => this;
42
+ readonly useInstrumentation: (instrumentation: Instrumentation) => this;
43
+ constructor(inputConfig: BkOTConfig);
44
+ }
@@ -0,0 +1,20 @@
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
+ };
@@ -0,0 +1,4 @@
1
+ import type { NormalizedBkOTConfig } from './config';
2
+ export declare const isBkOTEndpoint: (config: NormalizedBkOTConfig, url: string) => boolean;
3
+ export declare const shouldIgnoreUrl: (config: NormalizedBkOTConfig, url: string) => boolean;
4
+ export declare const shouldPropagateTraceHeader: (_config: NormalizedBkOTConfig, url: string) => boolean;
@@ -0,0 +1,16 @@
1
+ export { type BkOTAttributesConfig, type BkOTAttributeValue, type BkOTBatchConfig, type BkOTConfig, type BkOTCustomEventPayload, type BkOTHttpBodyConfig, type BkOTHttpBodyRedactPayload, type BkOTRedactConfig, type BkOTRumConfig, normalizeConfig, type NormalizedBkOTConfig, type SignalExporterConfig, } from './core/config';
2
+ export { type BkOTPlugin, type BkOTRuntimeContext, createPlugin, type PluginManager } from './core/plugin';
3
+ export { FilteringSpanProcessor } from './core/processor';
4
+ export { BkOpenTelemetry, type BkOTInstance } from './core/sdk';
5
+ export { createBlankScreenPlugin } from './plugins/blank-screen';
6
+ export { createCommonInstrumentationsPlugin } from './plugins/common';
7
+ export { createCspViolationPlugin } from './plugins/csp-violation';
8
+ export { createDevicePlugin } from './plugins/device';
9
+ export { createErrorPlugin } from './plugins/error';
10
+ export { createHttpBodyPlugin } from './plugins/http-body';
11
+ export { createLongTaskPlugin } from './plugins/long-task';
12
+ export { createPageViewPlugin } from './plugins/page-view';
13
+ export { createRouteTimingPlugin } from './plugins/route-timing';
14
+ export { createSessionPlugin } from './plugins/session';
15
+ export { createWebVitalsPlugin } from './plugins/web-vitals';
16
+ export { createWebSocketPlugin } from './plugins/websocket';