@vtvlive/interactive-apm 0.0.6 → 0.0.8

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.
@@ -1 +1 @@
1
- {"version":3,"file":"elastic-apm-init.d.ts","sourceRoot":"","sources":["../../src/init/elastic-apm-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,MAAM,WAAW,qBAAqB;IACpC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;CAClE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAG7C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG;IACnE,SAAS,IAAI,OAAO,CAAC;IACrB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,GAAG,IAAI,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACrE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,GAAG,IAAI,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9D,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACjC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,GAAG,IAAI,CA8CP;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAQ7C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,SAAS,IAAI,OAAO,CAAC;IACrB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,GAAG,IAAI,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACrE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,GAAG,IAAI,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9D,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACjC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,GAAG,IAAI,CAWP"}
1
+ {"version":3,"file":"elastic-apm-init.d.ts","sourceRoot":"","sources":["../../src/init/elastic-apm-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,MAAM,WAAW,qBAAqB;IACpC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;CAClE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAG7C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG;IACnE,SAAS,IAAI,OAAO,CAAC;IACrB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,GAAG,IAAI,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACrE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,GAAG,IAAI,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9D,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACjC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,GAAG,IAAI,CA4CP;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAQ7C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,SAAS,IAAI,OAAO,CAAC;IACrB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,GAAG,IAAI,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACrE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG;QAAE,GAAG,IAAI,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9D,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACjC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,GAAG,IAAI,CAWP"}
@@ -1 +1 @@
1
- {"version":3,"file":"opentelemetry-init.d.ts","sourceRoot":"","sources":["../../src/init/opentelemetry-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAgD7D,MAAM,WAAW,wBAAwB;IACvC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mHAAmH;IACnH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kCAAkC;IAClC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,qCAAqC;IACrC,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,8DAA8D;IAC9D,aAAa,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;CACxC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD;AAwCD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC;IACvF,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC,CAwJD"}
1
+ {"version":3,"file":"opentelemetry-init.d.ts","sourceRoot":"","sources":["../../src/init/opentelemetry-init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAgD7D,MAAM,WAAW,wBAAwB;IACvC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mHAAmH;IACnH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kCAAkC;IAClC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,qCAAqC;IACrC,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,8DAA8D;IAC9D,aAAa,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;CACxC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD;AAwCD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC;IACvF,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC,CA+MD"}
@@ -175,6 +175,11 @@ async function initOpenTelemetry(options = {}) {
175
175
  // Build exporters array
176
176
  const exporters = [];
177
177
  // Create OTLP exporter based on transport type
178
+ // NOTE: For PROTO/GRPC exporters, we need to set env var because url parameter is not respected
179
+ const originalEnv = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;
180
+ if (isProto || isGrpc) {
181
+ process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = normalizedEndpoint;
182
+ }
178
183
  let otlpExporterBase;
179
184
  if (isGrpc) {
180
185
  // @ts-ignore - Optional peer dependency
@@ -203,6 +208,15 @@ async function initOpenTelemetry(options = {}) {
203
208
  // Wrap with debug exporter for detailed request/response logging
204
209
  const otlpExporter = (0, debug_exporter_wrapper_1.createDebugExporter)(otlpExporterBase, normalizedEndpoint);
205
210
  exporters.push(otlpExporter);
211
+ // Restore original env var after creating exporter
212
+ if (isProto || isGrpc) {
213
+ if (originalEnv !== undefined) {
214
+ process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = originalEnv;
215
+ }
216
+ else {
217
+ delete process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT;
218
+ }
219
+ }
206
220
  // Console Exporter for debugging
207
221
  if (options.enableConsoleExporter ??
208
222
  process.env.ELASTIC_OTLP_ENABLE_CONSOLE_EXPORTER === "true") {
@@ -222,6 +236,18 @@ async function initOpenTelemetry(options = {}) {
222
236
  const { ExpressInstrumentation } = await Promise.resolve().then(() => __importStar(require("@opentelemetry/instrumentation-express")));
223
237
  instrumentations.push(new ExpressInstrumentation());
224
238
  }
239
+ console.log('[DEBUG] About to load Redis instrumentation...');
240
+ try {
241
+ const { IORedisInstrumentation } = await Promise.resolve().then(() => __importStar(require("@opentelemetry/instrumentation-ioredis")));
242
+ console.log('[DEBUG] Redis import successful');
243
+ instrumentations.push(new IORedisInstrumentation());
244
+ console.log('[DEBUG] Redis instrumentation added');
245
+ (0, debug_logger_1.infoLog)("[OpenTelemetry] Redis instrumentation enabled");
246
+ }
247
+ catch (err) {
248
+ console.error('[DEBUG] Redis instrumentation failed:', err);
249
+ (0, debug_logger_1.infoLog)("[OpenTelemetry] Redis instrumentation not available");
250
+ }
225
251
  // Resource attributes
226
252
  const sdkResource = resourceFromAttributes({
227
253
  "service.name": serviceName,
@@ -230,13 +256,37 @@ async function initOpenTelemetry(options = {}) {
230
256
  "service.instance.id": `${process.pid}`,
231
257
  "host.name": require("os").hostname(),
232
258
  });
259
+ // Use BatchSpanProcessor for efficient batching with transaction naming
260
+ // @ts-ignore - Optional peer dependency
261
+ const { BatchSpanProcessor } = await Promise.resolve().then(() => __importStar(require("@opentelemetry/sdk-trace-base")));
262
+ // Create a combined processor that does both transaction naming AND export
263
+ const transactionNameProcessor = new TransactionNameProcessor();
264
+ const traceExporterToUse = exporters.length === 1 ? exporters[0] : exporters;
265
+ const batchProcessor = new BatchSpanProcessor(traceExporterToUse);
266
+ // Wrap batch processor to also apply transaction naming
267
+ const processorWithNaming = {
268
+ onStart: (span, context) => {
269
+ transactionNameProcessor.onStart(span);
270
+ batchProcessor.onStart(span, context);
271
+ },
272
+ onEnd: (span) => {
273
+ transactionNameProcessor.onEnd(span);
274
+ batchProcessor.onEnd(span);
275
+ },
276
+ forceFlush: async () => {
277
+ await batchProcessor.forceFlush();
278
+ },
279
+ shutdown: async () => {
280
+ await batchProcessor.shutdown();
281
+ },
282
+ };
233
283
  // Initialize SDK
234
284
  const sdk = new NodeSDK({
235
285
  serviceName,
236
- traceExporter: exporters.length === 1 ? exporters[0] : exporters, // Handle single/multiple exporters
286
+ traceExporter: undefined, // Don't use traceExporter when using spanProcessor
237
287
  instrumentations: instrumentations,
238
288
  resource: sdkResource,
239
- spanProcessor: new TransactionNameProcessor(),
289
+ spanProcessor: processorWithNaming,
240
290
  });
241
291
  // Start SDK
242
292
  sdk.start();
@@ -1,4 +1,4 @@
1
- import { ISpan } from "../types/apm.types";
1
+ import { ISpan, SpanKind } from "../types/apm.types";
2
2
  /**
3
3
  * Interface chung cho APM Tracing Provider
4
4
  * Cho phép switch giữa OpenTelemetry và Elastic APM thông qua DI
@@ -13,10 +13,10 @@ export interface ITracingProvider {
13
13
  * Bắt đầu một span mới để trace operation
14
14
  * @param name Tên của span
15
15
  * @param attributes Các attributes metadata
16
- * @param spanKind Loại span (INTERNAL, SERVER, CLIENT, PRODUCER, CONSUMER)
16
+ * @param spanKind Loại span (INTERNAL, SERVER, CLIENT, PRODUCER, CONSUMER, WEBSOCKET, OTHER)
17
17
  * @returns Span object - cần gọi end() khi hoàn thành
18
18
  */
19
- startSpan(name: string, attributes?: Record<string, string | number>, spanKind?: string): ISpan | null;
19
+ startSpan(name: string, attributes?: Record<string, string | number>, spanKind?: SpanKind): ISpan | null;
20
20
  /**
21
21
  * Thực thi function với context tracing (auto-close span)
22
22
  * @param name Tên của span
@@ -1 +1 @@
1
- {"version":3,"file":"tracing-provider.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/tracing-provider.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,UAAU,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C;;;;;;OAMG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC5C,QAAQ,CAAC,EAAE,MAAM,GAChB,KAAK,GAAG,IAAI,CAAC;IAEhB;;;;;;OAMG;IACH,mBAAmB,CAAC,CAAC,EACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC,CAAC;IAEd;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEjC;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAExD;;OAEG;IACH,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B;;;OAGG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;IAEnC;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B"}
1
+ {"version":3,"file":"tracing-provider.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/tracing-provider.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,UAAU,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C;;;;;;OAMG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC5C,QAAQ,CAAC,EAAE,QAAQ,GAClB,KAAK,GAAG,IAAI,CAAC;IAEhB;;;;;;OAMG;IACH,mBAAmB,CAAC,CAAC,EACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC,CAAC;IAEd;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAEjC;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAExD;;OAEG;IACH,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B;;;OAGG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;IAEnC;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B"}
@@ -1,3 +1,4 @@
1
+ import { SpanKind } from "../types/apm-provider.type";
1
2
  import { ITracingProvider } from "../interfaces/tracing-provider.interface";
2
3
  import { ISpan } from "../types/apm.types";
3
4
  /**
@@ -42,7 +43,7 @@ export declare class ElasticApmTracingProvider implements ITracingProvider {
42
43
  /**
43
44
  * Bắt đầu một span mới
44
45
  */
45
- startSpan(name: string, attributes?: Record<string, string | number>, spanKind?: string): IElasticApmSpan | null;
46
+ startSpan(name: string, attributes?: Record<string, string | number>, spanKind?: SpanKind): IElasticApmSpan | null;
46
47
  /**
47
48
  * Thực thi function với tracing context
48
49
  */
@@ -64,11 +65,11 @@ export declare class ElasticApmTracingProvider implements ITracingProvider {
64
65
  */
65
66
  shutdown(): Promise<void>;
66
67
  /**
67
- * Map string span kind to Elastic APM span type
68
+ * Map SpanKind enum to Elastic APM span type
68
69
  */
69
70
  private mapSpanKindToType;
70
71
  /**
71
- * Map string span kind to numeric value (for logging)
72
+ * Map SpanKind enum to numeric value (for logging)
72
73
  */
73
74
  private mapSpanKindToNumber;
74
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"elastic-apm.tracing-provider.d.ts","sourceRoot":"","sources":["../../src/providers/elastic-apm.tracing-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAU3C;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK;IAC5C,8BAA8B;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3C,wBAAwB;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,mBAAmB;IACnB,GAAG,IAAI,IAAI,CAAC;CACb;AA0BD;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,gBAAgB;IAChE,OAAO,CAAC,GAAG,CAAiC;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGnC,MAAM,GAAE;QACN,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACpB;IAOR;;;OAGG;IACG,UAAU,CAAC,MAAM,CAAC,EAAE;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDjB;;OAEG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC5C,QAAQ,GAAE,MAAmB,GAC5B,eAAe,GAAG,IAAI;IAiHzB;;OAEG;IACG,mBAAmB,CAAC,CAAC,EACzB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC;IAsBb;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAMhC;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOvD;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI;IAOlC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAe5B"}
1
+ {"version":3,"file":"elastic-apm.tracing-provider.d.ts","sourceRoot":"","sources":["../../src/providers/elastic-apm.tracing-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAU3C;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK;IAC5C,8BAA8B;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3C,wBAAwB;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,mBAAmB;IACnB,GAAG,IAAI,IAAI,CAAC;CACb;AA0BD;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,gBAAgB;IAChE,OAAO,CAAC,GAAG,CAAiC;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGnC,MAAM,GAAE;QACN,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACpB;IAOR;;;OAGG;IACG,UAAU,CAAC,MAAM,CAAC,EAAE;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDjB;;OAEG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC5C,QAAQ,GAAE,QAA4B,GACrC,eAAe,GAAG,IAAI;IAiHzB;;OAEG;IACG,mBAAmB,CAAC,CAAC,EACzB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC;IAsBb;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAMhC;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOvD;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI;IAOlC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAe5B"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ElasticApmTracingProvider = void 0;
4
+ const apm_provider_type_1 = require("../types/apm-provider.type");
4
5
  const debug_logger_1 = require("../utils/debug-logger");
5
6
  const elastic_apm_compat_1 = require("../utils/elastic-apm-compat");
6
7
  /**
@@ -64,7 +65,7 @@ class ElasticApmTracingProvider {
64
65
  /**
65
66
  * Bắt đầu một span mới
66
67
  */
67
- startSpan(name, attributes, spanKind = "INTERNAL") {
68
+ startSpan(name, attributes, spanKind = apm_provider_type_1.SpanKind.INTERNAL) {
68
69
  if (!this.apm) {
69
70
  if ((0, debug_logger_1.isDebugEnabled)()) {
70
71
  console.warn("[ElasticAPM] Not initialized");
@@ -224,37 +225,40 @@ class ElasticApmTracingProvider {
224
225
  }
225
226
  }
226
227
  /**
227
- * Map string span kind to Elastic APM span type
228
+ * Map SpanKind enum to Elastic APM span type
228
229
  */
229
230
  mapSpanKindToType(kind) {
230
- switch (kind.toUpperCase()) {
231
- case "SERVER":
231
+ switch (kind) {
232
+ case apm_provider_type_1.SpanKind.SERVER:
232
233
  return "request";
233
- case "CLIENT":
234
+ case apm_provider_type_1.SpanKind.CLIENT:
234
235
  return "db";
235
- case "PRODUCER":
236
+ case apm_provider_type_1.SpanKind.PRODUCER:
236
237
  return "messaging";
237
- case "CONSUMER":
238
+ case apm_provider_type_1.SpanKind.CONSUMER:
238
239
  return "messaging";
239
- case "INTERNAL":
240
+ case apm_provider_type_1.SpanKind.WEBSOCKET:
241
+ return "websocket";
242
+ case apm_provider_type_1.SpanKind.INTERNAL:
243
+ case apm_provider_type_1.SpanKind.OTHER:
240
244
  default:
241
245
  return "code";
242
246
  }
243
247
  }
244
248
  /**
245
- * Map string span kind to numeric value (for logging)
249
+ * Map SpanKind enum to numeric value (for logging)
246
250
  */
247
251
  mapSpanKindToNumber(kind) {
248
- switch (kind.toUpperCase()) {
249
- case "SERVER":
252
+ switch (kind) {
253
+ case apm_provider_type_1.SpanKind.SERVER:
250
254
  return 1;
251
- case "CLIENT":
255
+ case apm_provider_type_1.SpanKind.CLIENT:
252
256
  return 2;
253
- case "PRODUCER":
257
+ case apm_provider_type_1.SpanKind.PRODUCER:
254
258
  return 3;
255
- case "CONSUMER":
259
+ case apm_provider_type_1.SpanKind.CONSUMER:
256
260
  return 4;
257
- case "INTERNAL":
261
+ case apm_provider_type_1.SpanKind.INTERNAL:
258
262
  default:
259
263
  return 0;
260
264
  }
@@ -1,6 +1,6 @@
1
1
  import { ITracingProvider } from "../interfaces/tracing-provider.interface";
2
2
  import { OtlpTransport } from "../types/otlp-transport.type";
3
- import { ISpan } from "../types/apm.types";
3
+ import { ISpan, SpanKind } from "../types/apm.types";
4
4
  /**
5
5
  * OpenTelemetry Tracing Provider Implementation
6
6
  * Sử dụng OpenTelemetry SDK với OTLP exporter để gửi traces về Elastic APM
@@ -43,7 +43,7 @@ export declare class OpenTelemetryTracingProvider implements ITracingProvider {
43
43
  /**
44
44
  * Bắt đầu một span mới
45
45
  */
46
- startSpan(name: string, attributes?: Record<string, string | number>, spanKind?: string): ISpan | null;
46
+ startSpan(name: string, attributes?: Record<string, string | number>, spanKind?: SpanKind): ISpan | null;
47
47
  /**
48
48
  * Thực thi function với tracing context
49
49
  */
@@ -69,7 +69,7 @@ export declare class OpenTelemetryTracingProvider implements ITracingProvider {
69
69
  */
70
70
  shutdown(): Promise<void>;
71
71
  /**
72
- * Map string span kind to OpenTelemetry SpanKind enum
72
+ * Map SpanKind enum to OpenTelemetry SpanKind enum
73
73
  */
74
74
  private mapSpanKind;
75
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"opentelemetry.tracing-provider.d.ts","sourceRoot":"","sources":["../../src/providers/opentelemetry.tracing-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAyG3C;;;GAGG;AACH,qBAAa,4BAA6B,YAAW,gBAAgB;IACnE,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;IACrD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAU;IAChD,OAAO,CAAC,WAAW,CAAS;gBAG1B,MAAM,GAAE;QACN,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;QACvC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,qBAAqB,CAAC,EAAE,OAAO,CAAC;KAC5B;IA6BR;;;OAGG;IACG,UAAU,CAAC,MAAM,CAAC,EAAE;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+NjB;;OAEG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC5C,QAAQ,GAAE,MAAmB,GAC5B,KAAK,GAAG,IAAI;IA+Gf;;OAEG;IACG,mBAAmB,CAAC,CAAC,EACzB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC;IAmCb;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAiBhC;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAavD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAajC;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI;IAalC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B;;OAEG;IACH,OAAO,CAAC,WAAW;CAiBpB"}
1
+ {"version":3,"file":"opentelemetry.tracing-provider.d.ts","sourceRoot":"","sources":["../../src/providers/opentelemetry.tracing-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAyGrD;;;GAGG;AACH,qBAAa,4BAA6B,YAAW,gBAAgB;IACnE,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;IACrD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAU;IAChD,OAAO,CAAC,WAAW,CAAS;gBAG1B,MAAM,GAAE;QACN,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;QACvC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,qBAAqB,CAAC,EAAE,OAAO,CAAC;KAC5B;IA6BR;;;OAGG;IACG,UAAU,CAAC,MAAM,CAAC,EAAE;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+NjB;;OAEG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC5C,QAAQ,GAAE,QAA4B,GACrC,KAAK,GAAG,IAAI;IA+Gf;;OAEG;IACG,mBAAmB,CAAC,CAAC,EACzB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC;IAmCb;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAiBhC;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAavD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAajC;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI;IAalC;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B;;OAEG;IACH,OAAO,CAAC,WAAW;CAmBpB"}
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.OpenTelemetryTracingProvider = void 0;
37
37
  const otlp_transport_type_1 = require("../types/otlp-transport.type");
38
+ const apm_types_1 = require("../types/apm.types");
38
39
  const debug_logger_1 = require("../utils/debug-logger");
39
40
  const debug_exporter_wrapper_1 = require("../utils/debug-exporter-wrapper");
40
41
  /**
@@ -341,7 +342,7 @@ class OpenTelemetryTracingProvider {
341
342
  /**
342
343
  * Bắt đầu một span mới
343
344
  */
344
- startSpan(name, attributes, spanKind = "INTERNAL") {
345
+ startSpan(name, attributes, spanKind = apm_types_1.SpanKind.INTERNAL) {
345
346
  if (!this.initialized || !this.tracer) {
346
347
  if ((0, debug_logger_1.isDebugEnabled)()) {
347
348
  console.warn("[OpenTelemetry] Not initialized");
@@ -526,23 +527,25 @@ class OpenTelemetryTracingProvider {
526
527
  }
527
528
  }
528
529
  /**
529
- * Map string span kind to OpenTelemetry SpanKind enum
530
+ * Map SpanKind enum to OpenTelemetry SpanKind enum
530
531
  */
531
532
  mapSpanKind(kind) {
532
533
  // @ts-ignore - Optional peer dependency
533
- const { SpanKind } = require("@opentelemetry/api");
534
- switch (kind.toUpperCase()) {
535
- case "SERVER":
536
- return SpanKind.SERVER;
537
- case "CLIENT":
538
- return SpanKind.CLIENT;
539
- case "PRODUCER":
540
- return SpanKind.PRODUCER;
541
- case "CONSUMER":
542
- return SpanKind.CONSUMER;
543
- case "INTERNAL":
534
+ const { SpanKind: OtlpSpanKind } = require("@opentelemetry/api");
535
+ switch (kind) {
536
+ case apm_types_1.SpanKind.SERVER:
537
+ return OtlpSpanKind.SERVER;
538
+ case apm_types_1.SpanKind.CLIENT:
539
+ return OtlpSpanKind.CLIENT;
540
+ case apm_types_1.SpanKind.PRODUCER:
541
+ return OtlpSpanKind.PRODUCER;
542
+ case apm_types_1.SpanKind.CONSUMER:
543
+ return OtlpSpanKind.CONSUMER;
544
+ case apm_types_1.SpanKind.WEBSOCKET:
545
+ case apm_types_1.SpanKind.OTHER:
546
+ case apm_types_1.SpanKind.INTERNAL:
544
547
  default:
545
- return SpanKind.INTERNAL;
548
+ return OtlpSpanKind.INTERNAL;
546
549
  }
547
550
  }
548
551
  }
@@ -1,5 +1,5 @@
1
1
  import { ITracingProvider } from "../interfaces/tracing-provider.interface";
2
- import { ISpan } from "../types/apm.types";
2
+ import { ISpan, SpanKind } from "../types/apm.types";
3
3
  /**
4
4
  * Tracing Service - Wrapper cho ITracingProvider
5
5
  * Service này được inject vào controllers/services để sử dụng tracing
@@ -47,7 +47,7 @@ export declare class TracingService {
47
47
  * span.end();
48
48
  * }
49
49
  */
50
- startSpan(name: string, attributes?: Record<string, string | number>, spanKind?: string): ISpan | null;
50
+ startSpan(name: string, attributes?: Record<string, string | number>, spanKind?: SpanKind): ISpan | null;
51
51
  /**
52
52
  * Thực thi function với context tracing (auto-close span)
53
53
  * @param name Tên của span
@@ -1 +1 @@
1
- {"version":3,"file":"tracing.service.d.ts","sourceRoot":"","sources":["../../src/services/tracing.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,gBAAgB;IAEvD;;;;;;;;;;;;;;;;;;;OAmBG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC5C,QAAQ,GAAE,MAAmB,GAC5B,KAAK,GAAG,IAAI;IAIf;;;;;;;;;;;;;;;OAeG;IACH,mBAAmB,CAAC,CAAC,EACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC;IAIb;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAIhC;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIvD;;;OAGG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI;IAI3B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
1
+ {"version":3,"file":"tracing.service.d.ts","sourceRoot":"","sources":["../../src/services/tracing.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,gBAAgB;IAEvD;;;;;;;;;;;;;;;;;;;OAmBG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC5C,QAAQ,GAAE,QAA4B,GACrC,KAAK,GAAG,IAAI;IAIf;;;;;;;;;;;;;;;OAeG;IACH,mBAAmB,CAAC,CAAC,EACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC;IAIb;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAIhC;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIvD;;;OAGG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI;IAI3B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TracingService = void 0;
4
+ const apm_types_1 = require("../types/apm.types");
4
5
  /**
5
6
  * Tracing Service - Wrapper cho ITracingProvider
6
7
  * Service này được inject vào controllers/services để sử dụng tracing
@@ -49,7 +50,7 @@ class TracingService {
49
50
  * span.end();
50
51
  * }
51
52
  */
52
- startSpan(name, attributes, spanKind = "INTERNAL") {
53
+ startSpan(name, attributes, spanKind = apm_types_1.SpanKind.INTERNAL) {
53
54
  return this.provider.startSpan(name, attributes, spanKind);
54
55
  }
55
56
  /**
@@ -25,7 +25,11 @@ export declare enum SpanKind {
25
25
  /** Message producer */
26
26
  PRODUCER = "PRODUCER",
27
27
  /** Message consumer */
28
- CONSUMER = "CONSUMER"
28
+ CONSUMER = "CONSUMER",
29
+ /** WebSocket communication */
30
+ WEBSOCKET = "WEBSOCKET",
31
+ /** Other custom span kind */
32
+ OTHER = "OTHER"
29
33
  }
30
34
  /**
31
35
  * APM provider configuration options
@@ -1 +1 @@
1
- {"version":3,"file":"apm-provider.type.d.ts","sourceRoot":"","sources":["../../src/types/apm-provider.type.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,oBAAY,WAAW;IACrB,uCAAuC;IACvC,aAAa,kBAAkB;IAC/B,gCAAgC;IAChC,WAAW,gBAAgB;CAC5B;AAED,+BAA+B;AAC/B,MAAM,MAAM,eAAe,GAAG,GAAG,WAAW,EAAE,CAAC;AAE/C;;GAEG;AACH,oBAAY,QAAQ;IAClB,yBAAyB;IACzB,QAAQ,aAAa;IACrB,kDAAkD;IAClD,MAAM,WAAW;IACjB,iDAAiD;IACjD,MAAM,WAAW;IACjB,uBAAuB;IACvB,QAAQ,aAAa;IACrB,uBAAuB;IACvB,QAAQ,aAAa;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,oBAAoB;IACpB,QAAQ,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAChC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB"}
1
+ {"version":3,"file":"apm-provider.type.d.ts","sourceRoot":"","sources":["../../src/types/apm-provider.type.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,oBAAY,WAAW;IACrB,uCAAuC;IACvC,aAAa,kBAAkB;IAC/B,gCAAgC;IAChC,WAAW,gBAAgB;CAC5B;AAED,+BAA+B;AAC/B,MAAM,MAAM,eAAe,GAAG,GAAG,WAAW,EAAE,CAAC;AAE/C;;GAEG;AACH,oBAAY,QAAQ;IAClB,yBAAyB;IACzB,QAAQ,aAAa;IACrB,kDAAkD;IAClD,MAAM,WAAW;IACjB,iDAAiD;IACjD,MAAM,WAAW;IACjB,uBAAuB;IACvB,QAAQ,aAAa;IACrB,uBAAuB;IACvB,QAAQ,aAAa;IACrB,8BAA8B;IAC9B,SAAS,cAAc;IACvB,6BAA6B;IAC7B,KAAK,UAAU;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,oBAAoB;IACpB,QAAQ,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAChC,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB"}
@@ -29,4 +29,8 @@ var SpanKind;
29
29
  SpanKind["PRODUCER"] = "PRODUCER";
30
30
  /** Message consumer */
31
31
  SpanKind["CONSUMER"] = "CONSUMER";
32
+ /** WebSocket communication */
33
+ SpanKind["WEBSOCKET"] = "WEBSOCKET";
34
+ /** Other custom span kind */
35
+ SpanKind["OTHER"] = "OTHER";
32
36
  })(SpanKind || (exports.SpanKind = SpanKind = {}));
@@ -1,11 +1,10 @@
1
- import { Span, SpanKind } from "@opentelemetry/api";
1
+ import { Span } from "@opentelemetry/api";
2
+ import { SpanKind } from "../types/apm-provider.type";
2
3
  /**
3
- * TracingHelper - Static utility class for direct OpenTelemetry usage
4
+ * TracingHelper - Static utility class for unified APM usage
4
5
  *
5
- * This class provides direct access to OpenTelemetry tracing without requiring
6
- * dependency injection or the TracingService wrapper.
7
- *
8
- * Note: This requires @opentelemetry/api to be installed.
6
+ * This class automatically detects the APM provider (OpenTelemetry or Elastic APM)
7
+ * and uses the appropriate API.
9
8
  *
10
9
  * @example
11
10
  * import { TracingHelper } from '@vtvlive/interactive-apm';
@@ -13,15 +12,21 @@ import { Span, SpanKind } from "@opentelemetry/api";
13
12
  * const span = TracingHelper.startSpan('my.operation', { 'key': 'value' }, SpanKind.SERVER);
14
13
  * try {
15
14
  * // ... code
16
- * } catch (error) {
17
- * TracingHelper.captureError(error);
18
- * throw error;
19
15
  * } finally {
20
16
  * TracingHelper.endSpan(span);
21
17
  * }
22
18
  */
23
19
  export declare class TracingHelper {
24
20
  private static tracer;
21
+ private static apmProvider;
22
+ /**
23
+ * Get the current APM provider (cached)
24
+ */
25
+ private static getProvider;
26
+ /**
27
+ * Reset cached provider (useful for testing)
28
+ */
29
+ static resetProviderCache(): void;
25
30
  /**
26
31
  * Bắt đầu một span mới để trace operation
27
32
  * @param name Tên của span
@@ -30,6 +35,27 @@ export declare class TracingHelper {
30
35
  * @returns Span object
31
36
  */
32
37
  static startSpan(name: string, attributes?: Record<string, string | number>, spanKind?: SpanKind): Span;
38
+ private static mapSpanKindToOtlpSpanKind;
39
+ /**
40
+ * Start span using OpenTelemetry API
41
+ */
42
+ private static startSpanOpenTelemetry;
43
+ /**
44
+ * Start span using Elastic APM API
45
+ */
46
+ private static startSpanElasticApm;
47
+ /**
48
+ * Map OpenTelemetry SpanKind to Elastic APM transaction type
49
+ */
50
+ private static mapSpanKindToTransactionType;
51
+ /**
52
+ * Map OpenTelemetry SpanKind to Elastic APM span type
53
+ */
54
+ private static mapSpanKindToSpanType;
55
+ /**
56
+ * Create a no-op span that does nothing
57
+ */
58
+ private static createNoOpSpan;
33
59
  /**
34
60
  * Thực thi function với context tracing (auto-close span)
35
61
  * @param name Tên của span
@@ -1 +1 @@
1
- {"version":3,"file":"tracing.helper.d.ts","sourceRoot":"","sources":["../../src/utils/tracing.helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,IAAI,EAAkB,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAsC;IAE3D;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CACd,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC5C,QAAQ,GAAE,QAA4B,GACrC,IAAI;IAaP;;;;;;OAMG;IACH,MAAM,CAAC,mBAAmB,CAAC,CAAC,EAC1B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC;IA2Bb;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAQvC;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAO9D;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI;IAOjC;;;OAGG;IACH,MAAM,CAAC,aAAa,IAAI,IAAI,GAAG,SAAS;IAIxC;;;OAGG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM,GAAG,SAAS;CAIxC"}
1
+ {"version":3,"file":"tracing.helper.d.ts","sourceRoot":"","sources":["../../src/utils/tracing.helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,IAAI,EAA4C,MAAM,oBAAoB,CAAC;AACpG,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAwCtD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAsC;IAC3D,OAAO,CAAC,MAAM,CAAC,WAAW,CAAoD;IAE9E;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAO1B;;OAEG;IACH,MAAM,CAAC,kBAAkB,IAAI,IAAI;IAIjC;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CACd,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC5C,QAAQ,GAAE,QAA4B,GACrC,IAAI;IAWP,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAiBxC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAiBrC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAsFlC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;IAqB3C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAsBpC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAe7B;;;;;;OAMG;WACU,mBAAmB,CAAC,CAAC,EAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC;IA2Cb;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAsBvC;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAwB9D;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI;IA2BjC;;;OAGG;IACH,MAAM,CAAC,aAAa,IAAI,IAAI,GAAG,SAAS;IAqBxC;;;OAGG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM,GAAG,SAAS;CAqBxC"}
@@ -3,13 +3,43 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TracingHelper = void 0;
4
4
  // @ts-ignore - Optional peer dependency
5
5
  const api_1 = require("@opentelemetry/api");
6
+ const apm_provider_type_1 = require("../types/apm-provider.type");
6
7
  /**
7
- * TracingHelper - Static utility class for direct OpenTelemetry usage
8
- *
9
- * This class provides direct access to OpenTelemetry tracing without requiring
10
- * dependency injection or the TracingService wrapper.
8
+ * Get the current APM provider type
9
+ */
10
+ function getApmProvider() {
11
+ const provider = process.env.APM_PROVIDER;
12
+ if (provider === "elastic-apm")
13
+ return "elastic-apm";
14
+ if (provider === "opentelemetry")
15
+ return "opentelemetry";
16
+ // Auto-detect: check if elastic-apm is available and started
17
+ try {
18
+ // @ts-ignore - Optional dependency
19
+ const apm = require("elastic-apm-node");
20
+ if (apm.isStarted?.())
21
+ return "elastic-apm";
22
+ }
23
+ catch {
24
+ // elastic-apm-node not installed
25
+ }
26
+ // Check if OpenTelemetry is available
27
+ try {
28
+ // @ts-ignore - Optional dependency
29
+ const api = require("@opentelemetry/api");
30
+ if (api.trace.getTracerProvider())
31
+ return "opentelemetry";
32
+ }
33
+ catch {
34
+ // @opentelemetry/api not installed
35
+ }
36
+ return "none";
37
+ }
38
+ /**
39
+ * TracingHelper - Static utility class for unified APM usage
11
40
  *
12
- * Note: This requires @opentelemetry/api to be installed.
41
+ * This class automatically detects the APM provider (OpenTelemetry or Elastic APM)
42
+ * and uses the appropriate API.
13
43
  *
14
44
  * @example
15
45
  * import { TracingHelper } from '@vtvlive/interactive-apm';
@@ -17,14 +47,26 @@ const api_1 = require("@opentelemetry/api");
17
47
  * const span = TracingHelper.startSpan('my.operation', { 'key': 'value' }, SpanKind.SERVER);
18
48
  * try {
19
49
  * // ... code
20
- * } catch (error) {
21
- * TracingHelper.captureError(error);
22
- * throw error;
23
50
  * } finally {
24
51
  * TracingHelper.endSpan(span);
25
52
  * }
26
53
  */
27
54
  class TracingHelper {
55
+ /**
56
+ * Get the current APM provider (cached)
57
+ */
58
+ static getProvider() {
59
+ if (this.apmProvider === "none") {
60
+ this.apmProvider = getApmProvider();
61
+ }
62
+ return this.apmProvider;
63
+ }
64
+ /**
65
+ * Reset cached provider (useful for testing)
66
+ */
67
+ static resetProviderCache() {
68
+ this.apmProvider = "none";
69
+ }
28
70
  /**
29
71
  * Bắt đầu một span mới để trace operation
30
72
  * @param name Tên của span
@@ -32,13 +74,175 @@ class TracingHelper {
32
74
  * @param spanKind Loại span (mặc định: INTERNAL). Dùng SERVER cho API endpoints
33
75
  * @returns Span object
34
76
  */
35
- static startSpan(name, attributes, spanKind = api_1.SpanKind.INTERNAL) {
77
+ static startSpan(name, attributes, spanKind = apm_provider_type_1.SpanKind.INTERNAL) {
78
+ const provider = this.getProvider();
79
+ if (provider === "elastic-apm") {
80
+ return this.startSpanElasticApm(name, attributes, spanKind);
81
+ }
82
+ // Default to OpenTelemetry
83
+ return this.startSpanOpenTelemetry(name, attributes, spanKind);
84
+ }
85
+ static mapSpanKindToOtlpSpanKind(spanKind) {
86
+ switch (spanKind) {
87
+ case apm_provider_type_1.SpanKind.SERVER:
88
+ return api_1.SpanKind.SERVER;
89
+ case apm_provider_type_1.SpanKind.CLIENT:
90
+ return api_1.SpanKind.CLIENT;
91
+ case apm_provider_type_1.SpanKind.PRODUCER:
92
+ return api_1.SpanKind.PRODUCER;
93
+ case apm_provider_type_1.SpanKind.CONSUMER:
94
+ return api_1.SpanKind.CONSUMER;
95
+ case apm_provider_type_1.SpanKind.WEBSOCKET:
96
+ return api_1.SpanKind.SERVER;
97
+ default:
98
+ return api_1.SpanKind.INTERNAL;
99
+ }
100
+ }
101
+ /**
102
+ * Start span using OpenTelemetry API
103
+ */
104
+ static startSpanOpenTelemetry(name, attributes, spanKind = apm_provider_type_1.SpanKind.INTERNAL) {
36
105
  const span = this.tracer.startSpan(name, {
37
106
  attributes,
38
- kind: spanKind,
107
+ kind: this.mapSpanKindToOtlpSpanKind(spanKind),
39
108
  }, api_1.context.active());
40
109
  return span;
41
110
  }
111
+ /**
112
+ * Start span using Elastic APM API
113
+ */
114
+ static startSpanElasticApm(name, attributes, spanKind = apm_provider_type_1.SpanKind.INTERNAL) {
115
+ try {
116
+ // @ts-ignore - Optional dependency
117
+ const apm = require("elastic-apm-node");
118
+ // Map spanKind to elastic-apm transaction type
119
+ const transactionType = this.mapSpanKindToTransactionType(spanKind);
120
+ // Get or create transaction
121
+ let transaction = apm.currentTransaction;
122
+ let createdTransaction = false;
123
+ if (!transaction) {
124
+ transaction = apm.startTransaction(name, transactionType);
125
+ if (!transaction) {
126
+ // Return a no-op span if transaction creation failed
127
+ return this.createNoOpSpan(name);
128
+ }
129
+ createdTransaction = true;
130
+ }
131
+ // Start span within transaction
132
+ const apmSpan = apm.startSpan(name, "custom");
133
+ if (!apmSpan) {
134
+ if (createdTransaction && transaction) {
135
+ transaction.end();
136
+ }
137
+ return this.createNoOpSpan(name);
138
+ }
139
+ // Set attributes as labels
140
+ if (attributes) {
141
+ for (const [key, value] of Object.entries(attributes)) {
142
+ apmSpan.setLabel(key, String(value));
143
+ }
144
+ }
145
+ // Set span type
146
+ apmSpan.setType(this.mapSpanKindToSpanType(spanKind));
147
+ // Wrap span to handle transaction ending
148
+ const span = apmSpan;
149
+ // Add OpenTelemetry-compatible methods to elastic-apm span
150
+ // This allows code using TracingHelper to work with both providers
151
+ if (span && typeof apmSpan.setLabel === 'function') {
152
+ const originalSetLabel = apmSpan.setLabel.bind(apmSpan);
153
+ // Add setAttribute method that maps to setLabel
154
+ span.setAttribute = (key, value) => {
155
+ originalSetLabel(key, String(value));
156
+ return span; // Return span for chaining
157
+ };
158
+ // Add setAttributes method for batch setting
159
+ span.setAttributes = (attrs) => {
160
+ for (const [k, v] of Object.entries(attrs)) {
161
+ originalSetLabel(k, String(v));
162
+ }
163
+ return span; // Return span for chaining
164
+ };
165
+ }
166
+ // Override end() to also end transaction if we created it
167
+ if (createdTransaction) {
168
+ const originalEnd = apmSpan.end.bind(apmSpan);
169
+ apmSpan.end = () => {
170
+ originalEnd();
171
+ if (transaction) {
172
+ transaction.end();
173
+ }
174
+ };
175
+ }
176
+ return span;
177
+ }
178
+ catch (error) {
179
+ console.error("[TracingHelper] ElasticAPM span creation failed:", error);
180
+ return this.createNoOpSpan(name);
181
+ }
182
+ }
183
+ /**
184
+ * Map OpenTelemetry SpanKind to Elastic APM transaction type
185
+ */
186
+ static mapSpanKindToTransactionType(spanKind) {
187
+ switch (spanKind) {
188
+ case apm_provider_type_1.SpanKind.SERVER:
189
+ return "request";
190
+ case apm_provider_type_1.SpanKind.CLIENT:
191
+ return "client";
192
+ case apm_provider_type_1.SpanKind.PRODUCER:
193
+ return "messaging";
194
+ case apm_provider_type_1.SpanKind.CONSUMER:
195
+ return "messaging";
196
+ case apm_provider_type_1.SpanKind.WEBSOCKET:
197
+ return "unknown";
198
+ case apm_provider_type_1.SpanKind.OTHER:
199
+ return "other";
200
+ case apm_provider_type_1.SpanKind.INTERNAL:
201
+ return "internal";
202
+ default:
203
+ return "custom";
204
+ }
205
+ }
206
+ /**
207
+ * Map OpenTelemetry SpanKind to Elastic APM span type
208
+ */
209
+ static mapSpanKindToSpanType(spanKind) {
210
+ switch (spanKind) {
211
+ case apm_provider_type_1.SpanKind.SERVER:
212
+ return "request";
213
+ case apm_provider_type_1.SpanKind.CLIENT:
214
+ return "external";
215
+ case apm_provider_type_1.SpanKind.PRODUCER:
216
+ return "messaging";
217
+ case apm_provider_type_1.SpanKind.CONSUMER:
218
+ return "messaging";
219
+ case apm_provider_type_1.SpanKind.WEBSOCKET:
220
+ return "unknown";
221
+ case apm_provider_type_1.SpanKind.OTHER:
222
+ return "other";
223
+ case apm_provider_type_1.SpanKind.INTERNAL:
224
+ return "internal";
225
+ default:
226
+ return "custom";
227
+ }
228
+ }
229
+ /**
230
+ * Create a no-op span that does nothing
231
+ */
232
+ static createNoOpSpan(name) {
233
+ return {
234
+ name,
235
+ kind: apm_provider_type_1.SpanKind.INTERNAL,
236
+ spanContext: () => ({ traceId: "noop", spanId: "noop" }),
237
+ setAttribute: () => ({}),
238
+ setAttributes: () => ({}),
239
+ addEvent: () => ({}),
240
+ recordException: () => ({}),
241
+ setStatus: () => ({}),
242
+ end: () => ({}),
243
+ isRecording: () => false,
244
+ };
245
+ }
42
246
  /**
43
247
  * Thực thi function với context tracing (auto-close span)
44
248
  * @param name Tên của span
@@ -46,7 +250,22 @@ class TracingHelper {
46
250
  * @param attributes Các attributes metadata
47
251
  * @returns Kết quả của function
48
252
  */
49
- static startSpanWithParent(name, fn, attributes) {
253
+ static async startSpanWithParent(name, fn, attributes) {
254
+ const provider = this.getProvider();
255
+ if (provider === "elastic-apm") {
256
+ // Elastic APM doesn't have the same context propagation
257
+ const span = this.startSpan(name, attributes);
258
+ try {
259
+ const result = await fn(span);
260
+ return result;
261
+ }
262
+ finally {
263
+ if (span) {
264
+ this.endSpan(span);
265
+ }
266
+ }
267
+ }
268
+ // OpenTelemetry with context propagation
50
269
  return api_1.context.with(api_1.trace.setSpan(api_1.context.active(), TracingHelper.startSpan(name, attributes)), async () => {
51
270
  const span = api_1.trace.getActiveSpan();
52
271
  // If no active span, throw an error - this should not happen if the span was just started
@@ -72,6 +291,19 @@ class TracingHelper {
72
291
  * @param error Error object
73
292
  */
74
293
  static captureError(error) {
294
+ const provider = this.getProvider();
295
+ if (provider === "elastic-apm") {
296
+ try {
297
+ // @ts-ignore - Optional dependency
298
+ const apm = require("elastic-apm-node");
299
+ apm.captureError(error);
300
+ }
301
+ catch {
302
+ // Ignore if elastic-apm is not available
303
+ }
304
+ return;
305
+ }
306
+ // OpenTelemetry
75
307
  const span = api_1.trace.getActiveSpan();
76
308
  if (span) {
77
309
  span.recordException(error);
@@ -84,6 +316,22 @@ class TracingHelper {
84
316
  * @param value Giá trị attribute
85
317
  */
86
318
  static setAttribute(key, value) {
319
+ const provider = this.getProvider();
320
+ if (provider === "elastic-apm") {
321
+ try {
322
+ // @ts-ignore - Optional dependency
323
+ const apm = require("elastic-apm-node");
324
+ const span = apm.currentSpan;
325
+ if (span) {
326
+ span.setLabel(key, String(value));
327
+ }
328
+ }
329
+ catch {
330
+ // Ignore if elastic-apm is not available
331
+ }
332
+ return;
333
+ }
334
+ // OpenTelemetry
87
335
  const span = api_1.trace.getActiveSpan();
88
336
  if (span) {
89
337
  span.setAttribute(key, value);
@@ -94,9 +342,27 @@ class TracingHelper {
94
342
  * @param span Span cần end
95
343
  */
96
344
  static endSpan(span) {
97
- const activeSpan = span || api_1.trace.getActiveSpan();
98
- if (activeSpan) {
99
- activeSpan.end();
345
+ if (!span) {
346
+ const provider = this.getProvider();
347
+ if (provider === "elastic-apm") {
348
+ try {
349
+ // @ts-ignore - Optional dependency
350
+ const apm = require("elastic-apm-node");
351
+ const apmSpan = apm.currentSpan;
352
+ if (apmSpan) {
353
+ apmSpan.end();
354
+ }
355
+ }
356
+ catch {
357
+ // Ignore if elastic-apm is not available
358
+ }
359
+ return;
360
+ }
361
+ // OpenTelemetry
362
+ span = api_1.trace.getActiveSpan();
363
+ }
364
+ if (span) {
365
+ span.end();
100
366
  }
101
367
  }
102
368
  /**
@@ -104,6 +370,22 @@ class TracingHelper {
104
370
  * @returns The active span or undefined
105
371
  */
106
372
  static getActiveSpan() {
373
+ const provider = this.getProvider();
374
+ if (provider === "elastic-apm") {
375
+ try {
376
+ // @ts-ignore - Optional dependency
377
+ const apm = require("elastic-apm-node");
378
+ const apmSpan = apm.currentSpan;
379
+ if (apmSpan) {
380
+ return apmSpan;
381
+ }
382
+ }
383
+ catch {
384
+ // Ignore if elastic-apm is not available
385
+ }
386
+ return undefined;
387
+ }
388
+ // OpenTelemetry
107
389
  return api_1.trace.getActiveSpan();
108
390
  }
109
391
  /**
@@ -111,9 +393,26 @@ class TracingHelper {
111
393
  * @returns The trace ID or undefined
112
394
  */
113
395
  static getTraceId() {
396
+ const provider = this.getProvider();
397
+ if (provider === "elastic-apm") {
398
+ try {
399
+ // @ts-ignore - Optional dependency
400
+ const apm = require("elastic-apm-node");
401
+ const transaction = apm.currentTransaction;
402
+ if (transaction && transaction.traceId) {
403
+ return transaction.traceId;
404
+ }
405
+ }
406
+ catch {
407
+ // Ignore if elastic-apm is not available
408
+ }
409
+ return undefined;
410
+ }
411
+ // OpenTelemetry
114
412
  const span = api_1.trace.getActiveSpan();
115
413
  return span?.spanContext().traceId;
116
414
  }
117
415
  }
118
416
  exports.TracingHelper = TracingHelper;
119
417
  TracingHelper.tracer = api_1.trace.getTracer("interactive-apm");
418
+ TracingHelper.apmProvider = "none";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtvlive/interactive-apm",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "APM integration package supporting both Elastic APM and OpenTelemetry with NestJS integration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -39,13 +39,14 @@
39
39
  "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
40
40
  "@nestjs/config": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0",
41
41
  "@opentelemetry/api": "^1.0.0",
42
- "@opentelemetry/exporter-trace-otlp-http": ">=0.200.0",
43
- "@opentelemetry/exporter-trace-otlp-grpc": ">=0.200.0",
44
- "@opentelemetry/exporter-trace-otlp-proto": ">=0.200.0",
45
- "@opentelemetry/instrumentation-express": ">=0.50.0",
46
- "@opentelemetry/instrumentation-http": ">=0.200.0",
42
+ "@opentelemetry/exporter-trace-otlp-http": ">=0.40.0",
43
+ "@opentelemetry/exporter-trace-otlp-grpc": ">=0.40.0",
44
+ "@opentelemetry/exporter-trace-otlp-proto": ">=0.40.0",
45
+ "@opentelemetry/instrumentation-express": ">=0.40.0",
46
+ "@opentelemetry/instrumentation-http": ">=0.40.0",
47
+ "@opentelemetry/instrumentation-ioredis": ">=0.50.0",
47
48
  "@opentelemetry/resources": ">=1.0.0",
48
- "@opentelemetry/sdk-node": ">=0.200.0",
49
+ "@opentelemetry/sdk-node": ">=0.40.0",
49
50
  "@opentelemetry/sdk-trace-base": ">=1.0.0",
50
51
  "@opentelemetry/semantic-conventions": ">=1.0.0",
51
52
  "elastic-apm-node": ">=3.0.0 <5.0.0"
@@ -75,6 +76,9 @@
75
76
  "@opentelemetry/instrumentation-http": {
76
77
  "optional": true
77
78
  },
79
+ "@opentelemetry/instrumentation-ioredis": {
80
+ "optional": true
81
+ },
78
82
  "@opentelemetry/resources": {
79
83
  "optional": true
80
84
  },
@@ -92,33 +96,42 @@
92
96
  }
93
97
  },
94
98
  "devDependencies": {
95
- "@nestjs/common": "^11.1.17",
96
- "@nestjs/config": "^4.0.3",
99
+ "@nestjs/common": "^10.4.0",
100
+ "@nestjs/config": "^3.2.0",
97
101
  "@opentelemetry/api": "^1.9.0",
98
- "@opentelemetry/exporter-trace-otlp-http": "^0.213.0",
99
- "@opentelemetry/exporter-trace-otlp-grpc": "^0.213.0",
100
- "@opentelemetry/exporter-trace-otlp-proto": "^0.213.0",
101
- "@opentelemetry/instrumentation-express": "^0.61.0",
102
- "@opentelemetry/instrumentation-http": "^0.213.0",
103
- "@opentelemetry/resources": "^2.6.0",
104
- "@opentelemetry/sdk-node": "^0.213.0",
105
- "@opentelemetry/sdk-trace-base": "^1.22.0",
102
+ "@opentelemetry/exporter-trace-otlp-http": "^0.56.0",
103
+ "@opentelemetry/exporter-trace-otlp-grpc": "^0.56.0",
104
+ "@opentelemetry/exporter-trace-otlp-proto": "^0.56.0",
105
+ "@opentelemetry/instrumentation-express": "^0.56.0",
106
+ "@opentelemetry/instrumentation-http": "^0.56.0",
107
+ "@opentelemetry/instrumentation-ioredis": "^0.56.0",
108
+ "@opentelemetry/resources": "^1.30.0",
109
+ "@opentelemetry/sdk-node": "^0.56.0",
110
+ "@opentelemetry/sdk-trace-base": "^1.29.0",
106
111
  "@opentelemetry/semantic-conventions": "^1.40.0",
107
112
  "@types/jest": "^29.5.0",
108
- "@types/node": "^20.0.0",
109
- "elastic-apm-node": "^4.15.0",
110
- "eslint": "^9.18.0",
113
+ "@types/node": "^16.0.0",
114
+ "elastic-apm-node": "^3.30.0",
115
+ "eslint": "^8.57.0",
111
116
  "eslint-config-prettier": "^9.1.0",
112
117
  "eslint-plugin-prettier": "^5.2.1",
113
118
  "jest": "^29.7.0",
114
119
  "prettier": "^3.4.2",
115
120
  "ts-jest": "^29.1.0",
116
121
  "typescript": "^5.3.0",
117
- "@typescript-eslint/eslint-plugin": "^8.19.1",
118
- "@typescript-eslint/parser": "^8.19.1"
122
+ "@typescript-eslint/eslint-plugin": "^7.18.0",
123
+ "@typescript-eslint/parser": "^7.18.0"
119
124
  },
120
125
  "engines": {
121
- "node": ">=14.0.0"
126
+ "node": ">=16.0.0"
127
+ },
128
+ "resolutions": {
129
+ "lodash": "4.17.21",
130
+ "cookie": "0.7.2"
131
+ },
132
+ "overrides": {
133
+ "lodash": "4.17.21",
134
+ "cookie": "0.7.2"
122
135
  },
123
136
  "files": [
124
137
  "dist"