@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.
- package/dist/init/elastic-apm-init.d.ts.map +1 -1
- package/dist/init/opentelemetry-init.d.ts.map +1 -1
- package/dist/init/opentelemetry-init.js +52 -2
- package/dist/interfaces/tracing-provider.interface.d.ts +3 -3
- package/dist/interfaces/tracing-provider.interface.d.ts.map +1 -1
- package/dist/providers/elastic-apm.tracing-provider.d.ts +4 -3
- package/dist/providers/elastic-apm.tracing-provider.d.ts.map +1 -1
- package/dist/providers/elastic-apm.tracing-provider.js +19 -15
- package/dist/providers/opentelemetry.tracing-provider.d.ts +3 -3
- package/dist/providers/opentelemetry.tracing-provider.d.ts.map +1 -1
- package/dist/providers/opentelemetry.tracing-provider.js +17 -14
- package/dist/services/tracing.service.d.ts +2 -2
- package/dist/services/tracing.service.d.ts.map +1 -1
- package/dist/services/tracing.service.js +2 -1
- package/dist/types/apm-provider.type.d.ts +5 -1
- package/dist/types/apm-provider.type.d.ts.map +1 -1
- package/dist/types/apm-provider.type.js +4 -0
- package/dist/utils/tracing.helper.d.ts +35 -9
- package/dist/utils/tracing.helper.d.ts.map +1 -1
- package/dist/utils/tracing.helper.js +313 -14
- package/package.json +36 -23
|
@@ -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,
|
|
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,
|
|
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:
|
|
286
|
+
traceExporter: undefined, // Don't use traceExporter when using spanProcessor
|
|
237
287
|
instrumentations: instrumentations,
|
|
238
288
|
resource: sdkResource,
|
|
239
|
-
spanProcessor:
|
|
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?:
|
|
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;
|
|
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?:
|
|
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
|
|
68
|
+
* Map SpanKind enum to Elastic APM span type
|
|
68
69
|
*/
|
|
69
70
|
private mapSpanKindToType;
|
|
70
71
|
/**
|
|
71
|
-
* Map
|
|
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,
|
|
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 =
|
|
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
|
|
228
|
+
* Map SpanKind enum to Elastic APM span type
|
|
228
229
|
*/
|
|
229
230
|
mapSpanKindToType(kind) {
|
|
230
|
-
switch (kind
|
|
231
|
-
case
|
|
231
|
+
switch (kind) {
|
|
232
|
+
case apm_provider_type_1.SpanKind.SERVER:
|
|
232
233
|
return "request";
|
|
233
|
-
case
|
|
234
|
+
case apm_provider_type_1.SpanKind.CLIENT:
|
|
234
235
|
return "db";
|
|
235
|
-
case
|
|
236
|
+
case apm_provider_type_1.SpanKind.PRODUCER:
|
|
236
237
|
return "messaging";
|
|
237
|
-
case
|
|
238
|
+
case apm_provider_type_1.SpanKind.CONSUMER:
|
|
238
239
|
return "messaging";
|
|
239
|
-
case
|
|
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
|
|
249
|
+
* Map SpanKind enum to numeric value (for logging)
|
|
246
250
|
*/
|
|
247
251
|
mapSpanKindToNumber(kind) {
|
|
248
|
-
switch (kind
|
|
249
|
-
case
|
|
252
|
+
switch (kind) {
|
|
253
|
+
case apm_provider_type_1.SpanKind.SERVER:
|
|
250
254
|
return 1;
|
|
251
|
-
case
|
|
255
|
+
case apm_provider_type_1.SpanKind.CLIENT:
|
|
252
256
|
return 2;
|
|
253
|
-
case
|
|
257
|
+
case apm_provider_type_1.SpanKind.PRODUCER:
|
|
254
258
|
return 3;
|
|
255
|
-
case
|
|
259
|
+
case apm_provider_type_1.SpanKind.CONSUMER:
|
|
256
260
|
return 4;
|
|
257
|
-
case
|
|
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?:
|
|
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
|
|
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;
|
|
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 =
|
|
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
|
|
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
|
|
535
|
-
case
|
|
536
|
-
return
|
|
537
|
-
case
|
|
538
|
-
return
|
|
539
|
-
case
|
|
540
|
-
return
|
|
541
|
-
case
|
|
542
|
-
return
|
|
543
|
-
case
|
|
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
|
|
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?:
|
|
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;
|
|
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 =
|
|
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;
|
|
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
|
|
1
|
+
import { Span } from "@opentelemetry/api";
|
|
2
|
+
import { SpanKind } from "../types/apm-provider.type";
|
|
2
3
|
/**
|
|
3
|
-
* TracingHelper - Static utility class for
|
|
4
|
+
* TracingHelper - Static utility class for unified APM usage
|
|
4
5
|
*
|
|
5
|
-
* This class
|
|
6
|
-
*
|
|
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,
|
|
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
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
*
|
|
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 =
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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.
|
|
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.
|
|
43
|
-
"@opentelemetry/exporter-trace-otlp-grpc": ">=0.
|
|
44
|
-
"@opentelemetry/exporter-trace-otlp-proto": ">=0.
|
|
45
|
-
"@opentelemetry/instrumentation-express": ">=0.
|
|
46
|
-
"@opentelemetry/instrumentation-http": ">=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.
|
|
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": "^
|
|
96
|
-
"@nestjs/config": "^
|
|
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.
|
|
99
|
-
"@opentelemetry/exporter-trace-otlp-grpc": "^0.
|
|
100
|
-
"@opentelemetry/exporter-trace-otlp-proto": "^0.
|
|
101
|
-
"@opentelemetry/instrumentation-express": "^0.
|
|
102
|
-
"@opentelemetry/instrumentation-http": "^0.
|
|
103
|
-
"@opentelemetry/
|
|
104
|
-
"@opentelemetry/
|
|
105
|
-
"@opentelemetry/sdk-
|
|
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": "^
|
|
109
|
-
"elastic-apm-node": "^
|
|
110
|
-
"eslint": "^
|
|
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": "^
|
|
118
|
-
"@typescript-eslint/parser": "^
|
|
122
|
+
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
123
|
+
"@typescript-eslint/parser": "^7.18.0"
|
|
119
124
|
},
|
|
120
125
|
"engines": {
|
|
121
|
-
"node": ">=
|
|
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"
|