@vtvlive/interactive-apm 0.0.14 → 0.0.15
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/interfaces/tracing-provider.interface.d.ts +6 -0
- package/dist/interfaces/tracing-provider.interface.d.ts.map +1 -1
- package/dist/providers/elastic-apm.tracing-provider.d.ts +7 -2
- package/dist/providers/elastic-apm.tracing-provider.d.ts.map +1 -1
- package/dist/providers/elastic-apm.tracing-provider.js +24 -7
- package/dist/providers/opentelemetry.tracing-provider.d.ts +5 -0
- package/dist/providers/opentelemetry.tracing-provider.d.ts.map +1 -1
- package/dist/providers/opentelemetry.tracing-provider.js +59 -10
- package/dist/services/tracing.service.d.ts +6 -0
- package/dist/services/tracing.service.d.ts.map +1 -1
- package/dist/services/tracing.service.js +8 -0
- package/dist/utils/opentelemetry-transaction-context.d.ts +4 -0
- package/dist/utils/opentelemetry-transaction-context.d.ts.map +1 -0
- package/dist/utils/opentelemetry-transaction-context.js +19 -0
- package/dist/utils/tracing.helper.d.ts +6 -0
- package/dist/utils/tracing.helper.d.ts.map +1 -1
- package/dist/utils/tracing.helper.js +80 -18
- package/package.json +1 -1
|
@@ -36,6 +36,12 @@ export interface ITracingProvider {
|
|
|
36
36
|
* @param value Giá trị attribute
|
|
37
37
|
*/
|
|
38
38
|
setAttribute(key: string, value: SpanAttributeValue): void;
|
|
39
|
+
/**
|
|
40
|
+
* Set label/attribute cho active transaction hiện tại
|
|
41
|
+
* @param key Tên label
|
|
42
|
+
* @param value Giá trị label
|
|
43
|
+
*/
|
|
44
|
+
setTransactionLabel(key: string, value: SpanAttributeValue): void;
|
|
39
45
|
/**
|
|
40
46
|
* Force flush all pending spans
|
|
41
47
|
*/
|
|
@@ -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,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEzF;;;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,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC;IAExF;;;;;;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,cAAc,GAC1B,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,kBAAkB,GAAG,IAAI,CAAC;IAE3D;;OAEG;IACH,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B;;;OAGG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAErD;;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,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEzF;;;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,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC;IAExF;;;;;;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,cAAc,GAC1B,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,kBAAkB,GAAG,IAAI,CAAC;IAE3D;;;;OAIG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAElE;;OAEG;IACH,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7B;;;OAGG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAErD;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B"}
|
|
@@ -6,7 +6,7 @@ import { ISpan, SpanAttributes, SpanAttributeValue } from "../types/apm.types";
|
|
|
6
6
|
*/
|
|
7
7
|
export interface IElasticApmSpan extends ISpan {
|
|
8
8
|
/** Set a label on the span */
|
|
9
|
-
setLabel(key: string, value: string | number | boolean): void;
|
|
9
|
+
setLabel(key: string, value: string | number | boolean, stringify?: boolean): void;
|
|
10
10
|
/** Set the span type */
|
|
11
11
|
setType(type: string): void;
|
|
12
12
|
/** Set the outcome (success, failure) */
|
|
@@ -23,6 +23,7 @@ export declare class ElasticApmTracingProvider implements ITracingProvider {
|
|
|
23
23
|
private readonly serviceName;
|
|
24
24
|
private readonly environment;
|
|
25
25
|
private static isElasticLabelValue;
|
|
26
|
+
private static setElasticLabel;
|
|
26
27
|
constructor(config?: {
|
|
27
28
|
serviceName?: string;
|
|
28
29
|
environment?: string;
|
|
@@ -54,9 +55,13 @@ export declare class ElasticApmTracingProvider implements ITracingProvider {
|
|
|
54
55
|
*/
|
|
55
56
|
captureError(error: Error): void;
|
|
56
57
|
/**
|
|
57
|
-
* Set label cho current
|
|
58
|
+
* Set label cho current span
|
|
58
59
|
*/
|
|
59
60
|
setAttribute(key: string, value: SpanAttributeValue): void;
|
|
61
|
+
/**
|
|
62
|
+
* Set label cho current transaction
|
|
63
|
+
*/
|
|
64
|
+
setTransactionLabel(key: string, value: SpanAttributeValue): void;
|
|
60
65
|
/**
|
|
61
66
|
* End span manually
|
|
62
67
|
*/
|
|
@@ -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,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAU/E;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK;IAC5C,8BAA8B;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;
|
|
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,cAAc,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAU/E;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK;IAC5C,8BAA8B;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEnF,wBAAwB;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,mBAAmB;IACnB,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC7B;AA2BD;;;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;IAErC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAMlC,OAAO,CAAC,MAAM,CAAC,eAAe;gBAkB5B,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,cAAc,EAC3B,QAAQ,GAAE,QAA4B,GACrC,eAAe,GAAG,IAAI;IAoHzB;;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,cAAc,GAC1B,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,kBAAkB,GAAG,IAAI;IAO1D;;OAEG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAOjE;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IAOpD;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmBzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAe5B"}
|
|
@@ -12,6 +12,16 @@ class ElasticApmTracingProvider {
|
|
|
12
12
|
static isElasticLabelValue(value) {
|
|
13
13
|
return value !== undefined && !Array.isArray(value);
|
|
14
14
|
}
|
|
15
|
+
static setElasticLabel(target, key, value) {
|
|
16
|
+
if (!ElasticApmTracingProvider.isElasticLabelValue(value)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
20
|
+
target.setLabel(key, value, false);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
target.setLabel(key, value);
|
|
24
|
+
}
|
|
15
25
|
constructor(config = {}) {
|
|
16
26
|
this.apm = null;
|
|
17
27
|
this.serviceName =
|
|
@@ -96,9 +106,7 @@ class ElasticApmTracingProvider {
|
|
|
96
106
|
// Set labels từ attributes
|
|
97
107
|
if (attributes) {
|
|
98
108
|
for (const [key, value] of Object.entries(attributes)) {
|
|
99
|
-
|
|
100
|
-
span.setLabel(key, value);
|
|
101
|
-
}
|
|
109
|
+
ElasticApmTracingProvider.setElasticLabel(span, key, value);
|
|
102
110
|
}
|
|
103
111
|
}
|
|
104
112
|
// Set span type dựa trên kind
|
|
@@ -120,7 +128,7 @@ class ElasticApmTracingProvider {
|
|
|
120
128
|
if (!ElasticApmTracingProvider.isElasticLabelValue(value)) {
|
|
121
129
|
return;
|
|
122
130
|
}
|
|
123
|
-
originalSetLabel
|
|
131
|
+
ElasticApmTracingProvider.setElasticLabel({ setLabel: originalSetLabel }, key, value);
|
|
124
132
|
};
|
|
125
133
|
// Override setAttribute (if it exists, maps to setLabel)
|
|
126
134
|
if (typeof span.setAttribute === "function") {
|
|
@@ -196,12 +204,21 @@ class ElasticApmTracingProvider {
|
|
|
196
204
|
}
|
|
197
205
|
}
|
|
198
206
|
/**
|
|
199
|
-
* Set label cho current
|
|
207
|
+
* Set label cho current span
|
|
200
208
|
*/
|
|
201
209
|
setAttribute(key, value) {
|
|
202
210
|
const span = this.apm?.currentSpan;
|
|
203
|
-
if (span
|
|
204
|
-
|
|
211
|
+
if (span) {
|
|
212
|
+
ElasticApmTracingProvider.setElasticLabel(span, key, value);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Set label cho current transaction
|
|
217
|
+
*/
|
|
218
|
+
setTransactionLabel(key, value) {
|
|
219
|
+
const transaction = this.apm?.currentTransaction;
|
|
220
|
+
if (transaction) {
|
|
221
|
+
ElasticApmTracingProvider.setElasticLabel(transaction, key, value);
|
|
205
222
|
}
|
|
206
223
|
}
|
|
207
224
|
/**
|
|
@@ -40,6 +40,7 @@ export declare class OpenTelemetryTracingProvider implements ITracingProvider {
|
|
|
40
40
|
enableConsoleExporter?: boolean;
|
|
41
41
|
environment?: string;
|
|
42
42
|
}): Promise<void>;
|
|
43
|
+
private getTransactionSpanFromContext;
|
|
43
44
|
/**
|
|
44
45
|
* Bắt đầu một span mới
|
|
45
46
|
*/
|
|
@@ -56,6 +57,10 @@ export declare class OpenTelemetryTracingProvider implements ITracingProvider {
|
|
|
56
57
|
* Set attribute cho active span
|
|
57
58
|
*/
|
|
58
59
|
setAttribute(key: string, value: SpanAttributeValue): void;
|
|
60
|
+
/**
|
|
61
|
+
* Set transaction label on the root request span when available
|
|
62
|
+
*/
|
|
63
|
+
setTransactionLabel(key: string, value: SpanAttributeValue): void;
|
|
59
64
|
/**
|
|
60
65
|
* Force flush all pending spans
|
|
61
66
|
*/
|
|
@@ -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,cAAc,EAAE,kBAAkB,EAAE,QAAQ,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,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AA8GzF;;;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,OAAO,CAAC,6BAA6B;IAuBrC;;OAEG;IACH,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,cAAc,EAC3B,QAAQ,GAAE,QAA4B,GACrC,KAAK,GAAG,IAAI;IA4If;;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,cAAc,GAC1B,OAAO,CAAC,CAAC,CAAC;IA4Cb;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAiBhC;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAa1D;;OAEG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAWjE;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAajC;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IAapD;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B;;OAEG;IACH,OAAO,CAAC,WAAW;CAmBpB"}
|
|
@@ -38,6 +38,7 @@ const otlp_transport_type_1 = require("../types/otlp-transport.type");
|
|
|
38
38
|
const apm_types_1 = require("../types/apm.types");
|
|
39
39
|
const debug_logger_1 = require("../utils/debug-logger");
|
|
40
40
|
const debug_exporter_wrapper_1 = require("../utils/debug-exporter-wrapper");
|
|
41
|
+
const opentelemetry_transaction_context_1 = require("../utils/opentelemetry-transaction-context");
|
|
41
42
|
/**
|
|
42
43
|
* Transaction Name Processor for OpenTelemetry
|
|
43
44
|
* Sets transaction names to format: "GET /api/healthcheck/ping"
|
|
@@ -339,6 +340,20 @@ class OpenTelemetryTracingProvider {
|
|
|
339
340
|
throw error;
|
|
340
341
|
}
|
|
341
342
|
}
|
|
343
|
+
getTransactionSpanFromContext() {
|
|
344
|
+
// @ts-ignore - Optional peer dependency
|
|
345
|
+
const { context, trace } = require("@opentelemetry/api");
|
|
346
|
+
const activeContext = context.active();
|
|
347
|
+
const transactionSpan = activeContext?.getValue?.(opentelemetry_transaction_context_1.transactionSpanContextKey);
|
|
348
|
+
if (transactionSpan) {
|
|
349
|
+
return transactionSpan;
|
|
350
|
+
}
|
|
351
|
+
const activeSpan = trace.getActiveSpan();
|
|
352
|
+
if (activeSpan?.[opentelemetry_transaction_context_1.transactionSpanRef]) {
|
|
353
|
+
return activeSpan[opentelemetry_transaction_context_1.transactionSpanRef] ?? null;
|
|
354
|
+
}
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
342
357
|
/**
|
|
343
358
|
* Bắt đầu một span mới
|
|
344
359
|
*/
|
|
@@ -350,8 +365,10 @@ class OpenTelemetryTracingProvider {
|
|
|
350
365
|
return null;
|
|
351
366
|
}
|
|
352
367
|
// @ts-ignore - Optional peer dependency
|
|
353
|
-
const { context } = require("@opentelemetry/api");
|
|
368
|
+
const { context, trace } = require("@opentelemetry/api");
|
|
354
369
|
const tracer = this.tracer;
|
|
370
|
+
const activeContext = context.active();
|
|
371
|
+
const activeTransactionSpan = this.getTransactionSpanFromContext();
|
|
355
372
|
const span = tracer.startSpan(name, {
|
|
356
373
|
attributes,
|
|
357
374
|
kind: this.mapSpanKind(spanKind),
|
|
@@ -360,6 +377,21 @@ class OpenTelemetryTracingProvider {
|
|
|
360
377
|
if (span) {
|
|
361
378
|
const spanForLog = { name, kind: this.mapSpanKind(spanKind) };
|
|
362
379
|
(0, debug_logger_1.logSpan)("OpenTelemetry", spanForLog);
|
|
380
|
+
const transactionSpan = spanKind === apm_types_1.SpanKind.SERVER ? span : activeTransactionSpan;
|
|
381
|
+
if (transactionSpan) {
|
|
382
|
+
span[opentelemetry_transaction_context_1.transactionSpanRef] = transactionSpan;
|
|
383
|
+
let transactionContext;
|
|
384
|
+
if (typeof activeContext.setValue === "function") {
|
|
385
|
+
transactionContext = activeContext.setValue(opentelemetry_transaction_context_1.transactionSpanContextKey, transactionSpan);
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
if ((0, debug_logger_1.isDebugEnabled)()) {
|
|
389
|
+
console.warn("[OpenTelemetry] activeContext.setValue is unavailable; falling back to trace.setSpan for transaction span propagation");
|
|
390
|
+
}
|
|
391
|
+
transactionContext = trace.setSpan(context.active(), transactionSpan);
|
|
392
|
+
}
|
|
393
|
+
span[opentelemetry_transaction_context_1.spanExecutionContextRef] = transactionContext;
|
|
394
|
+
}
|
|
363
395
|
}
|
|
364
396
|
// Add end protection to prevent operations on ended span
|
|
365
397
|
if (span) {
|
|
@@ -412,7 +444,7 @@ class OpenTelemetryTracingProvider {
|
|
|
412
444
|
// Override end to prevent duplicate ends
|
|
413
445
|
if (typeof span.end === "function") {
|
|
414
446
|
const originalEnd = span.end.bind(span);
|
|
415
|
-
span.end = () => {
|
|
447
|
+
span.end = (result) => {
|
|
416
448
|
if (isEnded) {
|
|
417
449
|
if ((0, debug_logger_1.isDebugEnabled)()) {
|
|
418
450
|
console.warn(`[OpenTelemetry] Span "${name}" has already been ended. Ignoring duplicate end().`);
|
|
@@ -420,7 +452,7 @@ class OpenTelemetryTracingProvider {
|
|
|
420
452
|
return;
|
|
421
453
|
}
|
|
422
454
|
isEnded = true;
|
|
423
|
-
originalEnd();
|
|
455
|
+
originalEnd(result);
|
|
424
456
|
};
|
|
425
457
|
}
|
|
426
458
|
}
|
|
@@ -432,16 +464,21 @@ class OpenTelemetryTracingProvider {
|
|
|
432
464
|
async startSpanWithParent(name, fn, attributes) {
|
|
433
465
|
// @ts-ignore - Optional peer dependency
|
|
434
466
|
const { context, trace, SpanStatusCode } = require("@opentelemetry/api");
|
|
435
|
-
|
|
436
|
-
|
|
467
|
+
const span = this.startSpan(name, attributes);
|
|
468
|
+
const spanContext = span?.[opentelemetry_transaction_context_1.spanExecutionContextRef] ??
|
|
469
|
+
context.active();
|
|
470
|
+
const executionContext = span ? trace.setSpan(spanContext, span) : spanContext;
|
|
471
|
+
return context.with(executionContext, async () => {
|
|
472
|
+
const activeSpan = trace.getActiveSpan();
|
|
473
|
+
const currentSpan = activeSpan ?? span;
|
|
437
474
|
try {
|
|
438
|
-
const result = await fn(
|
|
475
|
+
const result = await fn(currentSpan);
|
|
439
476
|
return result;
|
|
440
477
|
}
|
|
441
478
|
catch (error) {
|
|
442
|
-
if (
|
|
443
|
-
|
|
444
|
-
|
|
479
|
+
if (currentSpan) {
|
|
480
|
+
currentSpan.recordException(error);
|
|
481
|
+
currentSpan.setStatus({
|
|
445
482
|
code: SpanStatusCode.ERROR,
|
|
446
483
|
message: error.message,
|
|
447
484
|
});
|
|
@@ -452,7 +489,7 @@ class OpenTelemetryTracingProvider {
|
|
|
452
489
|
throw error;
|
|
453
490
|
}
|
|
454
491
|
finally {
|
|
455
|
-
|
|
492
|
+
currentSpan?.end();
|
|
456
493
|
}
|
|
457
494
|
});
|
|
458
495
|
}
|
|
@@ -488,6 +525,18 @@ class OpenTelemetryTracingProvider {
|
|
|
488
525
|
span.setAttribute(key, value);
|
|
489
526
|
}
|
|
490
527
|
}
|
|
528
|
+
/**
|
|
529
|
+
* Set transaction label on the root request span when available
|
|
530
|
+
*/
|
|
531
|
+
setTransactionLabel(key, value) {
|
|
532
|
+
if (!this.initialized || value === undefined || Array.isArray(value)) {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
const transactionSpan = this.getTransactionSpanFromContext();
|
|
536
|
+
if (transactionSpan) {
|
|
537
|
+
transactionSpan.setAttribute(key, value);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
491
540
|
/**
|
|
492
541
|
* Force flush all pending spans
|
|
493
542
|
*/
|
|
@@ -76,6 +76,12 @@ export declare class TracingService {
|
|
|
76
76
|
* @param value Giá trị attribute
|
|
77
77
|
*/
|
|
78
78
|
setAttribute(key: string, value: SpanAttributeValue): void;
|
|
79
|
+
/**
|
|
80
|
+
* Set label/attribute cho active transaction hiện tại
|
|
81
|
+
* @param key Tên label
|
|
82
|
+
* @param value Giá trị label
|
|
83
|
+
*/
|
|
84
|
+
setTransactionLabel(key: string, value: SpanAttributeValue): void;
|
|
79
85
|
/**
|
|
80
86
|
* Kết thúc span manually
|
|
81
87
|
* @param span Span cần end (nếu không truyền, sẽ end active 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,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEzF;;;;;;;;;;;;;;;;;;;;;;;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,cAAc,EAC3B,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,cAAc,GAC1B,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,kBAAkB,GAAG,IAAI;IAI1D;;;OAGG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IAI7C;;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,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEzF;;;;;;;;;;;;;;;;;;;;;;;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,cAAc,EAC3B,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,cAAc,GAC1B,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,kBAAkB,GAAG,IAAI;IAI1D;;;;OAIG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAIjE;;;OAGG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IAI7C;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
|
|
@@ -87,6 +87,14 @@ class TracingService {
|
|
|
87
87
|
setAttribute(key, value) {
|
|
88
88
|
this.provider.setAttribute(key, value);
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Set label/attribute cho active transaction hiện tại
|
|
92
|
+
* @param key Tên label
|
|
93
|
+
* @param value Giá trị label
|
|
94
|
+
*/
|
|
95
|
+
setTransactionLabel(key, value) {
|
|
96
|
+
this.provider.setTransactionLabel(key, value);
|
|
97
|
+
}
|
|
90
98
|
/**
|
|
91
99
|
* Kết thúc span manually
|
|
92
100
|
* @param span Span cần end (nếu không truyền, sẽ end active span)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opentelemetry-transaction-context.d.ts","sourceRoot":"","sources":["../../src/utils/opentelemetry-transaction-context.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,yBAAyB,QAErC,CAAC;AAEF,eAAO,MAAM,kBAAkB,eAAiD,CAAC;AACjF,eAAO,MAAM,uBAAuB,eAA8C,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.spanExecutionContextRef = exports.transactionSpanRef = exports.transactionSpanContextKey = void 0;
|
|
4
|
+
const resolveCreateContextKey = () => {
|
|
5
|
+
try {
|
|
6
|
+
// @ts-ignore - Optional peer dependency
|
|
7
|
+
const { createContextKey } = require("@opentelemetry/api");
|
|
8
|
+
if (typeof createContextKey === "function") {
|
|
9
|
+
return createContextKey;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// Ignore when optional dependency is unavailable
|
|
14
|
+
}
|
|
15
|
+
return (description) => Symbol(description);
|
|
16
|
+
};
|
|
17
|
+
exports.transactionSpanContextKey = resolveCreateContextKey()("interactive-apm.transaction-span");
|
|
18
|
+
exports.transactionSpanRef = Symbol("interactive-apm.transaction-span-ref");
|
|
19
|
+
exports.spanExecutionContextRef = Symbol("interactive-apm.execution-context");
|
|
@@ -20,10 +20,12 @@ export declare class TracingHelper {
|
|
|
20
20
|
private static tracer;
|
|
21
21
|
private static apmProvider;
|
|
22
22
|
private static isElasticLabelValue;
|
|
23
|
+
private static setElasticLabel;
|
|
23
24
|
/**
|
|
24
25
|
* Get the current APM provider (cached)
|
|
25
26
|
*/
|
|
26
27
|
private static getProvider;
|
|
28
|
+
private static getTransactionSpanFromContext;
|
|
27
29
|
/**
|
|
28
30
|
* Reset cached provider (useful for testing)
|
|
29
31
|
*/
|
|
@@ -76,6 +78,10 @@ export declare class TracingHelper {
|
|
|
76
78
|
* @param value Giá trị attribute
|
|
77
79
|
*/
|
|
78
80
|
static setAttribute(key: string, value: SpanAttributeValue): void;
|
|
81
|
+
/**
|
|
82
|
+
* Set label/attribute cho active transaction hiện tại
|
|
83
|
+
*/
|
|
84
|
+
static setTransactionLabel(key: string, value: SpanAttributeValue): void;
|
|
79
85
|
/**
|
|
80
86
|
* Kết thúc span manually
|
|
81
87
|
* @param span Span cần end
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracing.helper.d.ts","sourceRoot":"","sources":["../../src/utils/tracing.helper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tracing.helper.d.ts","sourceRoot":"","sources":["../../src/utils/tracing.helper.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAkDtD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAsC;IAC3D,OAAO,CAAC,MAAM,CAAC,WAAW,CAAoD;IAE9E,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAMlC,OAAO,CAAC,MAAM,CAAC,eAAe;IAiB9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAO1B,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAqB5C;;OAEG;IACH,MAAM,CAAC,kBAAkB,IAAI,IAAI;IAIjC;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CACd,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,cAAc,EAC3B,QAAQ,GAAE,QAA4B,GACrC,KAAK;IAWR,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAiBxC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAmCrC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAgGlC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,4BAA4B;IAqB3C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAsBpC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAoB7B;;;;;;OAMG;WACU,mBAAmB,CAAC,CAAC,EAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,EAC3C,UAAU,CAAC,EAAE,cAAc,GAC1B,OAAO,CAAC,CAAC,CAAC;IAyDb;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAsBvC;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI;IAwBjE;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI;IA2BxE;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IA2BpD;;;OAGG;IACH,MAAM,CAAC,aAAa,IAAI,KAAK,GAAG,SAAS;IAqBzC;;;OAGG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM,GAAG,SAAS;CAqBxC"}
|
|
@@ -4,6 +4,7 @@ exports.TracingHelper = void 0;
|
|
|
4
4
|
// @ts-ignore - Optional peer dependency
|
|
5
5
|
const api_1 = require("@opentelemetry/api");
|
|
6
6
|
const apm_provider_type_1 = require("../types/apm-provider.type");
|
|
7
|
+
const opentelemetry_transaction_context_1 = require("./opentelemetry-transaction-context");
|
|
7
8
|
/**
|
|
8
9
|
* Get the current APM provider type
|
|
9
10
|
*/
|
|
@@ -55,6 +56,16 @@ class TracingHelper {
|
|
|
55
56
|
static isElasticLabelValue(value) {
|
|
56
57
|
return value !== undefined && !Array.isArray(value);
|
|
57
58
|
}
|
|
59
|
+
static setElasticLabel(target, key, value) {
|
|
60
|
+
if (!TracingHelper.isElasticLabelValue(value)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
64
|
+
target.setLabel(key, value, false);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
target.setLabel(key, value);
|
|
68
|
+
}
|
|
58
69
|
/**
|
|
59
70
|
* Get the current APM provider (cached)
|
|
60
71
|
*/
|
|
@@ -64,6 +75,18 @@ class TracingHelper {
|
|
|
64
75
|
}
|
|
65
76
|
return this.apmProvider;
|
|
66
77
|
}
|
|
78
|
+
static getTransactionSpanFromContext() {
|
|
79
|
+
const activeContext = api_1.context.active();
|
|
80
|
+
const transactionSpan = activeContext?.getValue?.(opentelemetry_transaction_context_1.transactionSpanContextKey);
|
|
81
|
+
if (transactionSpan) {
|
|
82
|
+
return transactionSpan;
|
|
83
|
+
}
|
|
84
|
+
const activeSpan = api_1.trace.getActiveSpan();
|
|
85
|
+
if (activeSpan?.[opentelemetry_transaction_context_1.transactionSpanRef]) {
|
|
86
|
+
return activeSpan[opentelemetry_transaction_context_1.transactionSpanRef] ?? null;
|
|
87
|
+
}
|
|
88
|
+
return activeSpan ?? null;
|
|
89
|
+
}
|
|
67
90
|
/**
|
|
68
91
|
* Reset cached provider (useful for testing)
|
|
69
92
|
*/
|
|
@@ -105,10 +128,18 @@ class TracingHelper {
|
|
|
105
128
|
* Start span using OpenTelemetry API
|
|
106
129
|
*/
|
|
107
130
|
static startSpanOpenTelemetry(name, attributes, spanKind = apm_provider_type_1.SpanKind.INTERNAL) {
|
|
131
|
+
const activeContext = api_1.context.active();
|
|
132
|
+
const activeTransactionSpan = this.getTransactionSpanFromContext();
|
|
108
133
|
const span = this.tracer.startSpan(name, {
|
|
109
134
|
attributes,
|
|
110
135
|
kind: this.mapSpanKindToOtlpSpanKind(spanKind),
|
|
111
136
|
}, api_1.context.active());
|
|
137
|
+
const transactionSpan = spanKind === apm_provider_type_1.SpanKind.SERVER ? span : activeTransactionSpan;
|
|
138
|
+
if (transactionSpan) {
|
|
139
|
+
span[opentelemetry_transaction_context_1.transactionSpanRef] = transactionSpan;
|
|
140
|
+
const transactionContext = activeContext.setValue?.(opentelemetry_transaction_context_1.transactionSpanContextKey, transactionSpan);
|
|
141
|
+
span[opentelemetry_transaction_context_1.spanExecutionContextRef] = transactionContext ?? api_1.context.active();
|
|
142
|
+
}
|
|
112
143
|
return span;
|
|
113
144
|
}
|
|
114
145
|
/**
|
|
@@ -142,9 +173,7 @@ class TracingHelper {
|
|
|
142
173
|
// Set attributes as labels
|
|
143
174
|
if (attributes) {
|
|
144
175
|
for (const [key, value] of Object.entries(attributes)) {
|
|
145
|
-
|
|
146
|
-
apmSpan.setLabel(key, value);
|
|
147
|
-
}
|
|
176
|
+
TracingHelper.setElasticLabel(apmSpan, key, value);
|
|
148
177
|
}
|
|
149
178
|
}
|
|
150
179
|
// Set span type
|
|
@@ -158,18 +187,14 @@ class TracingHelper {
|
|
|
158
187
|
// Add setAttribute method that maps to setLabel
|
|
159
188
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
160
189
|
span.setAttribute = (key, value) => {
|
|
161
|
-
|
|
162
|
-
originalSetLabel(key, value);
|
|
163
|
-
}
|
|
190
|
+
TracingHelper.setElasticLabel({ setLabel: originalSetLabel }, key, value);
|
|
164
191
|
return span; // Return span for chaining
|
|
165
192
|
};
|
|
166
193
|
// Add setAttributes method for batch setting
|
|
167
194
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
168
195
|
span.setAttributes = (attrs) => {
|
|
169
196
|
for (const [k, v] of Object.entries(attrs)) {
|
|
170
|
-
|
|
171
|
-
originalSetLabel(k, v);
|
|
172
|
-
}
|
|
197
|
+
TracingHelper.setElasticLabel({ setLabel: originalSetLabel }, k, v);
|
|
173
198
|
}
|
|
174
199
|
return span; // Return span for chaining
|
|
175
200
|
};
|
|
@@ -285,23 +310,33 @@ class TracingHelper {
|
|
|
285
310
|
}
|
|
286
311
|
}
|
|
287
312
|
// OpenTelemetry with context propagation
|
|
288
|
-
|
|
289
|
-
|
|
313
|
+
const span = TracingHelper.startSpan(name, attributes);
|
|
314
|
+
const spanContext = span?.[opentelemetry_transaction_context_1.spanExecutionContextRef] ??
|
|
315
|
+
api_1.context.active();
|
|
316
|
+
const executionContext = span
|
|
317
|
+
? api_1.trace.setSpan(spanContext, span)
|
|
318
|
+
: api_1.context.active();
|
|
319
|
+
return api_1.context.with(executionContext, async () => {
|
|
320
|
+
const activeSpan = api_1.trace.getActiveSpan();
|
|
321
|
+
const currentSpan = activeSpan ?? span;
|
|
290
322
|
// If no active span, throw an error - this should not happen if the span was just started
|
|
291
|
-
if (!
|
|
323
|
+
if (!currentSpan) {
|
|
292
324
|
throw new Error(`Failed to get active span for "${name}". The OpenTelemetry context may not be properly initialized.`);
|
|
293
325
|
}
|
|
294
326
|
try {
|
|
295
|
-
const result = await fn(
|
|
327
|
+
const result = await fn(currentSpan);
|
|
296
328
|
return result;
|
|
297
329
|
}
|
|
298
330
|
catch (error) {
|
|
299
|
-
|
|
300
|
-
|
|
331
|
+
currentSpan.recordException(error);
|
|
332
|
+
currentSpan.setStatus({
|
|
333
|
+
code: api_1.SpanStatusCode.ERROR,
|
|
334
|
+
message: error.message,
|
|
335
|
+
});
|
|
301
336
|
throw error;
|
|
302
337
|
}
|
|
303
338
|
finally {
|
|
304
|
-
|
|
339
|
+
currentSpan.end();
|
|
305
340
|
}
|
|
306
341
|
});
|
|
307
342
|
}
|
|
@@ -341,8 +376,8 @@ class TracingHelper {
|
|
|
341
376
|
// @ts-ignore - Optional dependency
|
|
342
377
|
const apm = require("elastic-apm-node");
|
|
343
378
|
const span = apm.currentSpan;
|
|
344
|
-
if (span
|
|
345
|
-
|
|
379
|
+
if (span) {
|
|
380
|
+
TracingHelper.setElasticLabel(span, key, value);
|
|
346
381
|
}
|
|
347
382
|
}
|
|
348
383
|
catch {
|
|
@@ -356,6 +391,33 @@ class TracingHelper {
|
|
|
356
391
|
span.setAttribute(key, value);
|
|
357
392
|
}
|
|
358
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Set label/attribute cho active transaction hiện tại
|
|
396
|
+
*/
|
|
397
|
+
static setTransactionLabel(key, value) {
|
|
398
|
+
const provider = this.getProvider();
|
|
399
|
+
if (provider === "elastic-apm") {
|
|
400
|
+
try {
|
|
401
|
+
// @ts-ignore - Optional dependency
|
|
402
|
+
const apm = require("elastic-apm-node");
|
|
403
|
+
const transaction = apm.currentTransaction;
|
|
404
|
+
if (transaction) {
|
|
405
|
+
TracingHelper.setElasticLabel(transaction, key, value);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
// Ignore if elastic-apm is not available
|
|
410
|
+
}
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
if (value === undefined || Array.isArray(value)) {
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
const transactionSpan = this.getTransactionSpanFromContext();
|
|
417
|
+
if (transactionSpan) {
|
|
418
|
+
transactionSpan.setAttribute(key, value);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
359
421
|
/**
|
|
360
422
|
* Kết thúc span manually
|
|
361
423
|
* @param span Span cần end
|
package/package.json
CHANGED