chinalife-otel-web-sdk 1.0.0

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 ADDED
@@ -0,0 +1,347 @@
1
+ # @chinalife/otel-web-sdk
2
+
3
+ OpenTelemetry Web SDK - 简化的前端追踪 SDK,封装 OpenTelemetry JS API,提供简单易用的接口。
4
+
5
+ ## 特性
6
+
7
+ - ✅ **简单易用** - 一行代码完成初始化
8
+ - ✅ **自动追踪** - 自动 instrument HTTP 请求、路由跳转等
9
+ - ✅ **多框架支持** - 支持 Vue、React、H5 应用
10
+ - ✅ **环境变量配置** - 支持通过环境变量配置,无需修改代码
11
+ - ✅ **TypeScript 支持** - 完整的 TypeScript 类型定义
12
+ - ✅ **CDN 支持** - 支持通过 CDN 方式引入
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ npm install @chinalife/otel-web-sdk
18
+ # 或
19
+ yarn add @chinalife/otel-web-sdk
20
+ ```
21
+
22
+ ## 快速开始
23
+
24
+ ### 最简配置
25
+
26
+ ```typescript
27
+ import { initOTel } from '@chinalife/otel-web-sdk';
28
+
29
+ // 一键初始化,使用环境变量或默认配置
30
+ initOTel();
31
+ ```
32
+
33
+ ### 完整配置
34
+
35
+ ```typescript
36
+ import { initOTel } from '@chinalife/otel-web-sdk';
37
+
38
+ initOTel({
39
+ serviceName: 'frontend-vue-app',
40
+ serviceVersion: '1.0.0',
41
+ environment: 'production',
42
+ datacenter: 'dc1',
43
+ collectorEndpoint: 'http://collector-dc1.otel.svc.cluster.local:4318/v1/traces',
44
+ samplingRatio: 1.0, // 100%采样(默认)
45
+ enableAutoInstrumentation: true,
46
+ enableRouterTracing: true,
47
+ enableHttpTracing: true,
48
+ propagationFormat: 'w3c', // 传播协议格式:'w3c' | 'b3multi' | 'pinpoint' | ['w3c', 'b3multi']
49
+ });
50
+ ```
51
+
52
+ ## Vue 应用集成
53
+
54
+ ```typescript
55
+ // main.ts
56
+ import { createApp } from 'vue';
57
+ import App from './App.vue';
58
+ import router from './router';
59
+ import { initOTel } from '@chinalife/otel-web-sdk';
60
+
61
+ // 在应用启动前初始化 SDK
62
+ initOTel({
63
+ serviceName: 'frontend-vue-app',
64
+ framework: 'vue',
65
+ router: router, // 自动 instrument 路由
66
+ collectorEndpoint: process.env.VITE_OTEL_COLLECTOR_ENDPOINT ||
67
+ 'http://collector-dc1.otel.svc.cluster.local:4318/v1/traces',
68
+ });
69
+
70
+ const app = createApp(App);
71
+ app.use(router);
72
+ app.mount('#app');
73
+ ```
74
+
75
+ ## React 应用集成
76
+
77
+ ```typescript
78
+ // index.tsx
79
+ import React from 'react';
80
+ import ReactDOM from 'react-dom/client';
81
+ import App from './App';
82
+ import { initOTel } from '@chinalife/otel-web-sdk';
83
+
84
+ // 初始化 SDK
85
+ initOTel({
86
+ serviceName: 'frontend-react-app',
87
+ framework: 'react',
88
+ collectorEndpoint: process.env.REACT_APP_OTEL_COLLECTOR_ENDPOINT ||
89
+ 'http://collector-dc1.otel.svc.cluster.local:4318/v1/traces',
90
+ });
91
+
92
+ const root = ReactDOM.createRoot(
93
+ document.getElementById('root') as HTMLElement
94
+ );
95
+ root.render(
96
+ <React.StrictMode>
97
+ <App />
98
+ </React.StrictMode>
99
+ );
100
+ ```
101
+
102
+ ## H5 应用集成
103
+
104
+ ### CDN 方式
105
+
106
+ ```html
107
+ <!DOCTYPE html>
108
+ <html>
109
+ <head>
110
+ <script src="https://cdn.jsdelivr.net/npm/@chinalife/otel-web-sdk@latest/dist/index.umd.js"></script>
111
+ </head>
112
+ <body>
113
+ <script>
114
+ // 初始化 SDK
115
+ window.OTelSDK.init({
116
+ serviceName: 'h5-app',
117
+ collectorEndpoint: 'http://collector-dc1.otel.svc.cluster.local:4318/v1/traces',
118
+ samplingRatio: 1.0,
119
+ });
120
+ </script>
121
+ </body>
122
+ </html>
123
+ ```
124
+
125
+ ## 手动创建 Span
126
+
127
+ ```typescript
128
+ import { trace } from '@chinalife/otel-web-sdk';
129
+
130
+ // 方式1: 手动管理 span
131
+ function handleUserAction() {
132
+ const span = trace.startSpan('user_action', {
133
+ attributes: {
134
+ 'action.type': 'button_click',
135
+ 'action.name': 'submit_form',
136
+ },
137
+ });
138
+
139
+ try {
140
+ await submitForm();
141
+ span.setStatus({ code: 1 }); // 1 = OK
142
+ } catch (error: any) {
143
+ span.setStatus({ code: 2, message: error.message }); // 2 = ERROR
144
+ span.recordException(error);
145
+ throw error;
146
+ } finally {
147
+ span.end();
148
+ }
149
+ }
150
+
151
+ // 方式2: 使用 withSpan(自动管理)
152
+ async function handleUserAction() {
153
+ await trace.withSpanAsync('user_action', async (span) => {
154
+ span.setAttributes({
155
+ 'action.type': 'button_click',
156
+ 'action.name': 'submit_form',
157
+ });
158
+ await submitForm();
159
+ });
160
+ }
161
+
162
+ // 方式3: 同步函数
163
+ function processData() {
164
+ return trace.withSpan('process_data', (span) => {
165
+ span.setAttributes({ 'data.size': data.length });
166
+ return process(data);
167
+ });
168
+ }
169
+ ```
170
+
171
+ ## 获取 Trace 信息
172
+
173
+ ```typescript
174
+ import { trace } from '@chinalife/otel-web-sdk';
175
+
176
+ // 获取当前 Trace ID
177
+ const traceId = trace.getCurrentTraceId();
178
+ console.log('Current Trace ID:', traceId);
179
+
180
+ // 获取当前 Span ID
181
+ const spanId = trace.getCurrentSpanId();
182
+ console.log('Current Span ID:', spanId);
183
+
184
+ // 获取当前活动的 Span
185
+ const activeSpan = trace.getActiveSpan();
186
+ if (activeSpan) {
187
+ activeSpan.setAttribute('custom.key', 'value');
188
+ }
189
+ ```
190
+
191
+ ## 传播协议配置
192
+
193
+ SDK 支持多种 Trace 传播协议格式,用于在不同系统间传递 Trace 上下文信息。
194
+
195
+ ### 支持的传播协议
196
+
197
+ - **W3C Trace Context** (`w3c`) - W3C 标准,使用 `traceparent` 和 `tracestate` 头部(默认)
198
+ - **B3 Multi** (`b3multi`) - Zipkin B3 多头部格式,使用 `X-B3-TraceId`、`X-B3-SpanId` 等
199
+ - **B3 Single** (`b3`) - Zipkin B3 单头部格式
200
+ - **Pinpoint** (`pinpoint`) - Naver Pinpoint 格式,使用 `Pinpoint-TraceId`、`Pinpoint-SpanId` 等
201
+
202
+ ### 使用单个传播协议
203
+
204
+ ```typescript
205
+ import { initOTel } from '@chinalife/otel-web-sdk';
206
+
207
+ // 使用 W3C Trace Context(默认)
208
+ initOTel({
209
+ serviceName: 'my-app',
210
+ propagationFormat: 'w3c',
211
+ });
212
+
213
+ // 使用 B3 Multi
214
+ initOTel({
215
+ serviceName: 'my-app',
216
+ propagationFormat: 'b3multi',
217
+ });
218
+
219
+ // 使用 Pinpoint
220
+ initOTel({
221
+ serviceName: 'my-app',
222
+ propagationFormat: 'pinpoint',
223
+ });
224
+ ```
225
+
226
+ ### 同时使用多个传播协议
227
+
228
+ 当需要同时支持多种后端系统时,可以配置多个传播协议:
229
+
230
+ ```typescript
231
+ initOTel({
232
+ serviceName: 'my-app',
233
+ // 同时使用 W3C 和 B3,HTTP 请求会同时携带两种格式的头部
234
+ propagationFormat: ['w3c', 'b3multi'],
235
+ });
236
+ ```
237
+
238
+ ### 通过环境变量配置
239
+
240
+ ```bash
241
+ # .env 文件
242
+ # 单个协议
243
+ OTEL_PROPAGATION_FORMAT=w3c
244
+
245
+ # 或多个协议(逗号分隔)
246
+ OTEL_PROPAGATION_FORMAT=w3c,b3multi
247
+
248
+ # 或使用 Vite 环境变量
249
+ VITE_OTEL_PROPAGATION_FORMAT=pinpoint
250
+ ```
251
+
252
+ ### 传播协议头部说明
253
+
254
+ **W3C Trace Context:**
255
+ - `traceparent`: `00-<trace-id>-<parent-id>-<flags>`
256
+ - `tracestate`: 可选的键值对列表
257
+
258
+ **B3 Multi:**
259
+ - `X-B3-TraceId`: 128 位或 64 位 trace ID
260
+ - `X-B3-SpanId`: 64 位 span ID
261
+ - `X-B3-ParentSpanId`: 64 位父 span ID(可选)
262
+ - `X-B3-Sampled`: `1` 或 `0`
263
+ - `X-B3-Flags`: 调试标志(可选)
264
+
265
+ **Pinpoint:**
266
+ - `Pinpoint-TraceId`: 16 字节十六进制 trace ID
267
+ - `Pinpoint-SpanId`: 8 字节十六进制 span ID
268
+ - `Pinpoint-ParentSpanId`: 8 字节十六进制父 span ID(可选)
269
+ - `Pinpoint-Sampled`: `1` 或 `0`
270
+ - `Pinpoint-Flags`: 标志位(通常为 `0`)
271
+
272
+ ## 环境变量配置
273
+
274
+ 支持通过环境变量配置,无需修改代码:
275
+
276
+ ```bash
277
+ # .env 文件
278
+ OTEL_EXPORTER_OTLP_ENDPOINT=http://collector-dc1.otel.svc.cluster.local:4318/v1/traces
279
+ OTEL_SERVICE_NAME=frontend-vue-app
280
+ OTEL_SERVICE_VERSION=1.0.0
281
+ OTEL_SAMPLING_RATIO=1.0
282
+ OTEL_DEPLOYMENT_ENVIRONMENT=production
283
+ OTEL_DATACENTER=dc1
284
+ OTEL_LOG_LEVEL=info
285
+ ```
286
+
287
+ ## API 参考
288
+
289
+ ### initOTel(options?: SDKOptions)
290
+
291
+ 初始化 SDK。
292
+
293
+ **参数:**
294
+ - `options.serviceName` - 服务名称
295
+ - `options.serviceVersion` - 服务版本
296
+ - `options.environment` - 环境(development/production)
297
+ - `options.datacenter` - 数据中心(dc1/dc2/dc3)
298
+ - `options.collectorEndpoint` - Collector 端点
299
+ - `options.samplingRatio` - 采样率(0-1,默认1.0)
300
+ - `options.enableAutoInstrumentation` - 启用自动 instrumentation
301
+ - `options.enableRouterTracing` - 启用路由追踪
302
+ - `options.enableHttpTracing` - 启用 HTTP 追踪
303
+ - `options.framework` - 框架类型(vue/react/h5)
304
+ - `options.router` - Vue Router 实例(Vue 专用)
305
+ - `options.propagationFormat` - 传播协议格式('w3c' | 'b3multi' | 'b3' | 'pinpoint' | string[]),默认 'w3c'
306
+
307
+ ### trace.startSpan(name, options?)
308
+
309
+ 创建并启动一个 span。
310
+
311
+ ### trace.withSpan(name, fn, options?)
312
+
313
+ 在上下文中执行函数并创建 span(同步)。
314
+
315
+ ### trace.withSpanAsync(name, fn, options?)
316
+
317
+ 在上下文中执行函数并创建 span(异步)。
318
+
319
+ ### trace.getCurrentTraceId()
320
+
321
+ 获取当前 Trace ID。
322
+
323
+ ### trace.getCurrentSpanId()
324
+
325
+ 获取当前 Span ID。
326
+
327
+ ### trace.getActiveSpan()
328
+
329
+ 获取当前活动的 Span。
330
+
331
+ ## 开发
332
+
333
+ ```bash
334
+ # 安装依赖
335
+ npm install
336
+
337
+ # 构建
338
+ npm run build
339
+
340
+ # 开发模式(监听文件变化)
341
+ npm run dev
342
+ ```
343
+
344
+ ## 许可证
345
+
346
+ MIT
347
+
@@ -0,0 +1,19 @@
1
+ import { SDKOptions } from './types';
2
+ /**
3
+ * 合并配置
4
+ */
5
+ export declare function mergeConfig(options?: SDKOptions): SDKOptions;
6
+ /**
7
+ * 日志工具
8
+ */
9
+ export declare class Logger {
10
+ private level;
11
+ constructor(level?: 'debug' | 'info' | 'warn' | 'error');
12
+ setLevel(level: 'debug' | 'info' | 'warn' | 'error'): void;
13
+ private shouldLog;
14
+ debug(...args: any[]): void;
15
+ info(...args: any[]): void;
16
+ warn(...args: any[]): void;
17
+ error(...args: any[]): void;
18
+ }
19
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAe,MAAM,SAAS,CAAC;AAyHlD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,UAAU,CAqC5D;AAED;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,KAAK,CAAsC;gBAEvC,KAAK,GAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAgB;IAI/D,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO;IAInD,OAAO,CAAC,SAAS;IAKjB,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE;IAMpB,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE;IAMnB,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE;IAMnB,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE;CAKrB"}
@@ -0,0 +1,76 @@
1
+ import { Span, Tracer } from '@opentelemetry/api';
2
+ import { initOTel, getTracer, forceFlush } from './sdk';
3
+ import { SDKOptions, SpanOptions, SpanStatus } from './types';
4
+ export { initOTel, getTracer, forceFlush };
5
+ export type { SDKOptions, SpanOptions, SpanStatus };
6
+ /**
7
+ * Trace API - 简化的追踪接口
8
+ */
9
+ export declare const traceAPI: {
10
+ /**
11
+ * 获取 tracer
12
+ */
13
+ getTracer(name?: string, version?: string): Tracer;
14
+ /**
15
+ * 创建并启动一个 span
16
+ */
17
+ startSpan(name: string, options?: SpanOptions): Span;
18
+ /**
19
+ * 在上下文中执行函数并创建 span
20
+ */
21
+ withSpan<T>(name: string, fn: (span: Span) => T, options?: SpanOptions): T;
22
+ /**
23
+ * 异步执行函数并创建 span
24
+ */
25
+ withSpanAsync<T>(name: string, fn: (span: Span) => Promise<T>, options?: SpanOptions): Promise<T>;
26
+ /**
27
+ * 获取当前活动的 span
28
+ */
29
+ getActiveSpan(): Span | undefined;
30
+ /**
31
+ * 获取当前 trace ID
32
+ */
33
+ getCurrentTraceId(): string | undefined;
34
+ /**
35
+ * 获取当前 span ID
36
+ */
37
+ getCurrentSpanId(): string | undefined;
38
+ };
39
+ export { traceAPI as trace };
40
+ declare const _default: {
41
+ init: typeof initOTel;
42
+ trace: {
43
+ /**
44
+ * 获取 tracer
45
+ */
46
+ getTracer(name?: string, version?: string): Tracer;
47
+ /**
48
+ * 创建并启动一个 span
49
+ */
50
+ startSpan(name: string, options?: SpanOptions): Span;
51
+ /**
52
+ * 在上下文中执行函数并创建 span
53
+ */
54
+ withSpan<T>(name: string, fn: (span: Span) => T, options?: SpanOptions): T;
55
+ /**
56
+ * 异步执行函数并创建 span
57
+ */
58
+ withSpanAsync<T>(name: string, fn: (span: Span) => Promise<T>, options?: SpanOptions): Promise<T>;
59
+ /**
60
+ * 获取当前活动的 span
61
+ */
62
+ getActiveSpan(): Span | undefined;
63
+ /**
64
+ * 获取当前 trace ID
65
+ */
66
+ getCurrentTraceId(): string | undefined;
67
+ /**
68
+ * 获取当前 span ID
69
+ */
70
+ getCurrentSpanId(): string | undefined;
71
+ };
72
+ getTracer: typeof getTracer;
73
+ forceFlush: typeof forceFlush;
74
+ };
75
+ export default _default;
76
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,IAAI,EAAE,MAAM,EAAW,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG9D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AAG3C,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AAEpD;;GAEG;AACH,eAAO,MAAM,QAAQ;IACnB;;OAEG;qBACc,MAAM,YAAY,MAAM,GAAG,MAAM;IAIlD;;OAEG;oBACa,MAAM,YAAY,WAAW,GAAG,IAAI;IAcpD;;OAEG;aACM,CAAC,QAAQ,MAAM,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,YAAY,WAAW,GAAG,CAAC;IAgC1E;;OAEG;kBACiB,CAAC,QACb,MAAM,MACR,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,YACpB,WAAW,GACpB,OAAO,CAAC,CAAC,CAAC;IAiBb;;OAEG;qBACc,IAAI,GAAG,SAAS;IAIjC;;OAEG;yBACkB,MAAM,GAAG,SAAS;IASvC;;OAEG;wBACiB,MAAM,GAAG,SAAS;CAQvC,CAAC;AAGF,OAAO,EAAE,QAAQ,IAAI,KAAK,EAAE,CAAC;;;;QApH3B;;WAEG;yBACc,MAAM,YAAY,MAAM,GAAG,MAAM;QAIlD;;WAEG;wBACa,MAAM,YAAY,WAAW,GAAG,IAAI;QAcpD;;WAEG;iBACM,CAAC,QAAQ,MAAM,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,YAAY,WAAW,GAAG,CAAC;QAgC1E;;WAEG;sBACiB,CAAC,QACb,MAAM,MACR,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,YACpB,WAAW,GACpB,OAAO,CAAC,CAAC,CAAC;QAiBb;;WAEG;yBACc,IAAI,GAAG,SAAS;QAIjC;;WAEG;6BACkB,MAAM,GAAG,SAAS;QASvC;;WAEG;4BACiB,MAAM,GAAG,SAAS;;;;;AAcxC,wBAKE"}