@use-tusk/drift-node-sdk 0.1.17 → 0.1.19
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/index.cjs +1561 -693
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1561 -693
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -4989,31 +4989,31 @@ var require_SamplingResult = /* @__PURE__ */ __commonJS({ "node_modules/@opentel
|
|
|
4989
4989
|
var require_span_kind = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/api/build/src/trace/span_kind.js": ((exports) => {
|
|
4990
4990
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4991
4991
|
exports.SpanKind = void 0;
|
|
4992
|
-
(function(SpanKind$
|
|
4992
|
+
(function(SpanKind$26) {
|
|
4993
4993
|
/** Default value. Indicates that the span is used internally. */
|
|
4994
|
-
SpanKind$
|
|
4994
|
+
SpanKind$26[SpanKind$26["INTERNAL"] = 0] = "INTERNAL";
|
|
4995
4995
|
/**
|
|
4996
4996
|
* Indicates that the span covers server-side handling of an RPC or other
|
|
4997
4997
|
* remote request.
|
|
4998
4998
|
*/
|
|
4999
|
-
SpanKind$
|
|
4999
|
+
SpanKind$26[SpanKind$26["SERVER"] = 1] = "SERVER";
|
|
5000
5000
|
/**
|
|
5001
5001
|
* Indicates that the span covers the client-side wrapper around an RPC or
|
|
5002
5002
|
* other remote request.
|
|
5003
5003
|
*/
|
|
5004
|
-
SpanKind$
|
|
5004
|
+
SpanKind$26[SpanKind$26["CLIENT"] = 2] = "CLIENT";
|
|
5005
5005
|
/**
|
|
5006
5006
|
* Indicates that the span describes producer sending a message to a
|
|
5007
5007
|
* broker. Unlike client and server, there is no direct critical path latency
|
|
5008
5008
|
* relationship between producer and consumer spans.
|
|
5009
5009
|
*/
|
|
5010
|
-
SpanKind$
|
|
5010
|
+
SpanKind$26[SpanKind$26["PRODUCER"] = 3] = "PRODUCER";
|
|
5011
5011
|
/**
|
|
5012
5012
|
* Indicates that the span describes consumer receiving a message from a
|
|
5013
5013
|
* broker. Unlike client and server, there is no direct critical path latency
|
|
5014
5014
|
* relationship between producer and consumer spans.
|
|
5015
5015
|
*/
|
|
5016
|
-
SpanKind$
|
|
5016
|
+
SpanKind$26[SpanKind$26["CONSUMER"] = 4] = "CONSUMER";
|
|
5017
5017
|
})(exports.SpanKind || (exports.SpanKind = {}));
|
|
5018
5018
|
}) });
|
|
5019
5019
|
|
|
@@ -5022,20 +5022,20 @@ var require_span_kind = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetr
|
|
|
5022
5022
|
var require_status = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/api/build/src/trace/status.js": ((exports) => {
|
|
5023
5023
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5024
5024
|
exports.SpanStatusCode = void 0;
|
|
5025
|
-
(function(SpanStatusCode$
|
|
5025
|
+
(function(SpanStatusCode$15) {
|
|
5026
5026
|
/**
|
|
5027
5027
|
* The default status.
|
|
5028
5028
|
*/
|
|
5029
|
-
SpanStatusCode$
|
|
5029
|
+
SpanStatusCode$15[SpanStatusCode$15["UNSET"] = 0] = "UNSET";
|
|
5030
5030
|
/**
|
|
5031
5031
|
* The operation has been validated by an Application developer or
|
|
5032
5032
|
* Operator to have completed successfully.
|
|
5033
5033
|
*/
|
|
5034
|
-
SpanStatusCode$
|
|
5034
|
+
SpanStatusCode$15[SpanStatusCode$15["OK"] = 1] = "OK";
|
|
5035
5035
|
/**
|
|
5036
5036
|
* The operation contains an error.
|
|
5037
5037
|
*/
|
|
5038
|
-
SpanStatusCode$
|
|
5038
|
+
SpanStatusCode$15[SpanStatusCode$15["ERROR"] = 2] = "ERROR";
|
|
5039
5039
|
})(exports.SpanStatusCode || (exports.SpanStatusCode = {}));
|
|
5040
5040
|
}) });
|
|
5041
5041
|
|
|
@@ -5684,7 +5684,7 @@ var require_src$7 = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/ap
|
|
|
5684
5684
|
|
|
5685
5685
|
//#endregion
|
|
5686
5686
|
//#region node_modules/@use-tusk/drift-schemas/dist/duration-B3fwb4jB.js
|
|
5687
|
-
var import_src$
|
|
5687
|
+
var import_src$35 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
5688
5688
|
var import_commonjs$9 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
|
|
5689
5689
|
var Duration$Type = class extends import_commonjs$9.MessageType {
|
|
5690
5690
|
constructor() {
|
|
@@ -6209,7 +6209,7 @@ var JsonSchema$Type = class extends import_commonjs$7.MessageType {
|
|
|
6209
6209
|
const JsonSchema = new JsonSchema$Type();
|
|
6210
6210
|
|
|
6211
6211
|
//#endregion
|
|
6212
|
-
//#region node_modules/@use-tusk/drift-schemas/dist/span-
|
|
6212
|
+
//#region node_modules/@use-tusk/drift-schemas/dist/span-CsBrzhI_.js
|
|
6213
6213
|
var import_commonjs$6 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
|
|
6214
6214
|
/**
|
|
6215
6215
|
* Package type classification enum
|
|
@@ -6295,7 +6295,7 @@ let PackageType = /* @__PURE__ */ function(PackageType$1) {
|
|
|
6295
6295
|
*
|
|
6296
6296
|
* @generated from protobuf enum tusk.drift.core.v1.SpanKind
|
|
6297
6297
|
*/
|
|
6298
|
-
let SpanKind = /* @__PURE__ */ function(SpanKind$1$1) {
|
|
6298
|
+
let SpanKind$1 = /* @__PURE__ */ function(SpanKind$1$1) {
|
|
6299
6299
|
/**
|
|
6300
6300
|
* @generated from protobuf enum value: SPAN_KIND_UNSPECIFIED = 0;
|
|
6301
6301
|
*/
|
|
@@ -6465,7 +6465,7 @@ var Span$Type = class extends import_commonjs$6.MessageType {
|
|
|
6465
6465
|
kind: "enum",
|
|
6466
6466
|
T: () => [
|
|
6467
6467
|
"tusk.drift.core.v1.SpanKind",
|
|
6468
|
-
SpanKind,
|
|
6468
|
+
SpanKind$1,
|
|
6469
6469
|
"SPAN_KIND_"
|
|
6470
6470
|
]
|
|
6471
6471
|
},
|
|
@@ -6504,6 +6504,13 @@ var Span$Type = class extends import_commonjs$6.MessageType {
|
|
|
6504
6504
|
name: "metadata",
|
|
6505
6505
|
kind: "message",
|
|
6506
6506
|
T: () => Struct
|
|
6507
|
+
},
|
|
6508
|
+
{
|
|
6509
|
+
no: 24,
|
|
6510
|
+
name: "environment",
|
|
6511
|
+
kind: "scalar",
|
|
6512
|
+
opt: true,
|
|
6513
|
+
T: 9
|
|
6507
6514
|
}
|
|
6508
6515
|
]);
|
|
6509
6516
|
}
|
|
@@ -6601,6 +6608,9 @@ var Span$Type = class extends import_commonjs$6.MessageType {
|
|
|
6601
6608
|
case 23:
|
|
6602
6609
|
message.metadata = Struct.internalBinaryRead(reader, reader.uint32(), options, message.metadata);
|
|
6603
6610
|
break;
|
|
6611
|
+
case 24:
|
|
6612
|
+
message.environment = reader.string();
|
|
6613
|
+
break;
|
|
6604
6614
|
default:
|
|
6605
6615
|
let u = options.readUnknownField;
|
|
6606
6616
|
if (u === "throw") throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
|
@@ -6634,6 +6644,7 @@ var Span$Type = class extends import_commonjs$6.MessageType {
|
|
|
6634
6644
|
if (message.duration) Duration.internalBinaryWrite(message.duration, writer.tag(21, import_commonjs$6.WireType.LengthDelimited).fork(), options).join();
|
|
6635
6645
|
if (message.isRootSpan !== false) writer.tag(22, import_commonjs$6.WireType.Varint).bool(message.isRootSpan);
|
|
6636
6646
|
if (message.metadata) Struct.internalBinaryWrite(message.metadata, writer.tag(23, import_commonjs$6.WireType.LengthDelimited).fork(), options).join();
|
|
6647
|
+
if (message.environment !== void 0) writer.tag(24, import_commonjs$6.WireType.LengthDelimited).string(message.environment);
|
|
6637
6648
|
let u = options.writeUnknownFields;
|
|
6638
6649
|
if (u !== false) (u == true ? import_commonjs$6.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
6639
6650
|
return writer;
|
|
@@ -6997,12 +7008,12 @@ const Trace = new Trace$Type();
|
|
|
6997
7008
|
const toStruct = (obj) => obj ? objectToProtobufStruct(obj) : void 0;
|
|
6998
7009
|
const mapOtToPb = (k) => {
|
|
6999
7010
|
switch (k) {
|
|
7000
|
-
case import_src$
|
|
7001
|
-
case import_src$
|
|
7002
|
-
case import_src$
|
|
7003
|
-
case import_src$
|
|
7004
|
-
case import_src$
|
|
7005
|
-
default: return SpanKind.UNSPECIFIED;
|
|
7011
|
+
case import_src$35.SpanKind.INTERNAL: return SpanKind$1.INTERNAL;
|
|
7012
|
+
case import_src$35.SpanKind.SERVER: return SpanKind$1.SERVER;
|
|
7013
|
+
case import_src$35.SpanKind.CLIENT: return SpanKind$1.CLIENT;
|
|
7014
|
+
case import_src$35.SpanKind.PRODUCER: return SpanKind$1.PRODUCER;
|
|
7015
|
+
case import_src$35.SpanKind.CONSUMER: return SpanKind$1.CONSUMER;
|
|
7016
|
+
default: return SpanKind$1.UNSPECIFIED;
|
|
7006
7017
|
}
|
|
7007
7018
|
};
|
|
7008
7019
|
/**
|
|
@@ -7405,13 +7416,13 @@ var TdInstrumentationNodeModule = class {
|
|
|
7405
7416
|
|
|
7406
7417
|
//#endregion
|
|
7407
7418
|
//#region src/core/types.ts
|
|
7408
|
-
var import_src$
|
|
7419
|
+
var import_src$34 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
7409
7420
|
const TD_INSTRUMENTATION_LIBRARY_NAME = "tusk-drift-sdk";
|
|
7410
|
-
const REPLAY_TRACE_ID_CONTEXT_KEY = (0, import_src$
|
|
7411
|
-
const SPAN_KIND_CONTEXT_KEY = (0, import_src$
|
|
7412
|
-
const IS_PRE_APP_START_CONTEXT_KEY = (0, import_src$
|
|
7413
|
-
const STOP_RECORDING_CHILD_SPANS_CONTEXT_KEY = (0, import_src$
|
|
7414
|
-
const CALLING_LIBRARY_CONTEXT_KEY = (0, import_src$
|
|
7421
|
+
const REPLAY_TRACE_ID_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.replayTraceId");
|
|
7422
|
+
const SPAN_KIND_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.spanKind");
|
|
7423
|
+
const IS_PRE_APP_START_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.isPreAppStart");
|
|
7424
|
+
const STOP_RECORDING_CHILD_SPANS_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.stopRecordingChildSpans");
|
|
7425
|
+
const CALLING_LIBRARY_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.callingLibrary");
|
|
7415
7426
|
let TdSpanAttributes = /* @__PURE__ */ function(TdSpanAttributes$1) {
|
|
7416
7427
|
/**
|
|
7417
7428
|
* Presentational information:
|
|
@@ -7523,7 +7534,7 @@ TraceBlockingManager.instance = null;
|
|
|
7523
7534
|
|
|
7524
7535
|
//#endregion
|
|
7525
7536
|
//#region src/core/tracing/SpanUtils.ts
|
|
7526
|
-
var import_src$
|
|
7537
|
+
var import_src$33 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
7527
7538
|
var SpanUtils = class SpanUtils {
|
|
7528
7539
|
/**
|
|
7529
7540
|
* Creates a new span and returns span info including trace ID and span ID
|
|
@@ -7531,8 +7542,8 @@ var SpanUtils = class SpanUtils {
|
|
|
7531
7542
|
static createSpan(options) {
|
|
7532
7543
|
try {
|
|
7533
7544
|
const tracer = TuskDriftCore.getInstance().getTracer();
|
|
7534
|
-
const parentContext = options.parentContext || import_src$
|
|
7535
|
-
const activeSpan = import_src$
|
|
7545
|
+
const parentContext = options.parentContext || import_src$33.context.active();
|
|
7546
|
+
const activeSpan = import_src$33.trace.getSpan(parentContext);
|
|
7536
7547
|
if (activeSpan) {
|
|
7537
7548
|
const parentTraceId = activeSpan.spanContext().traceId;
|
|
7538
7549
|
if (TraceBlockingManager.getInstance().isTraceBlocked(parentTraceId)) {
|
|
@@ -7541,11 +7552,11 @@ var SpanUtils = class SpanUtils {
|
|
|
7541
7552
|
}
|
|
7542
7553
|
}
|
|
7543
7554
|
const span = tracer.startSpan(options.name, {
|
|
7544
|
-
kind: options.kind || import_src$
|
|
7555
|
+
kind: options.kind || import_src$33.SpanKind.CLIENT,
|
|
7545
7556
|
attributes: options.attributes || {}
|
|
7546
7557
|
}, parentContext);
|
|
7547
7558
|
const spanContext = span.spanContext();
|
|
7548
|
-
const newContext = import_src$
|
|
7559
|
+
const newContext = import_src$33.trace.setSpan(parentContext, span).setValue(SPAN_KIND_CONTEXT_KEY, options.kind).setValue(IS_PRE_APP_START_CONTEXT_KEY, options.isPreAppStart);
|
|
7549
7560
|
return {
|
|
7550
7561
|
traceId: spanContext.traceId,
|
|
7551
7562
|
spanId: spanContext.spanId,
|
|
@@ -7562,7 +7573,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7562
7573
|
* Executes a function within a span context
|
|
7563
7574
|
*/
|
|
7564
7575
|
static withSpan(spanInfo, fn) {
|
|
7565
|
-
return import_src$
|
|
7576
|
+
return import_src$33.context.with(spanInfo.context, fn);
|
|
7566
7577
|
}
|
|
7567
7578
|
/**
|
|
7568
7579
|
* Execute a function within a properly configured span
|
|
@@ -7579,14 +7590,14 @@ var SpanUtils = class SpanUtils {
|
|
|
7579
7590
|
* @returns The result of the function execution
|
|
7580
7591
|
*/
|
|
7581
7592
|
static createAndExecuteSpan(mode, originalFunctionCall, options, fn) {
|
|
7582
|
-
const spanContext = import_src$
|
|
7593
|
+
const spanContext = import_src$33.trace.getActiveSpan()?.spanContext();
|
|
7583
7594
|
if (spanContext) {
|
|
7584
|
-
if (import_src$
|
|
7595
|
+
if (import_src$33.context.active().getValue(STOP_RECORDING_CHILD_SPANS_CONTEXT_KEY)) {
|
|
7585
7596
|
logger.debug(`[SpanUtils] Stopping recording of child spans for span ${spanContext.spanId}, packageName: ${options.packageName}, instrumentationName: ${options.instrumentationName}`);
|
|
7586
7597
|
return originalFunctionCall();
|
|
7587
7598
|
}
|
|
7588
7599
|
}
|
|
7589
|
-
const { name, kind, packageName, instrumentationName, packageType, submodule, inputValue, inputSchemaMerges, isPreAppStart, metadata, stopRecordingChildSpans } = options;
|
|
7600
|
+
const { name, kind, packageName, instrumentationName, packageType, submodule, inputValue, outputValue, inputSchemaMerges, isPreAppStart, metadata, stopRecordingChildSpans } = options;
|
|
7590
7601
|
let spanInfo = null;
|
|
7591
7602
|
try {
|
|
7592
7603
|
spanInfo = SpanUtils.createSpan({
|
|
@@ -7600,6 +7611,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7600
7611
|
[TdSpanAttributes.INSTRUMENTATION_NAME]: instrumentationName,
|
|
7601
7612
|
[TdSpanAttributes.PACKAGE_TYPE]: packageType,
|
|
7602
7613
|
[TdSpanAttributes.INPUT_VALUE]: createSpanInputValue(inputValue),
|
|
7614
|
+
...outputValue && { [TdSpanAttributes.OUTPUT_VALUE]: JSON.stringify(outputValue) },
|
|
7603
7615
|
[TdSpanAttributes.IS_PRE_APP_START]: isPreAppStart,
|
|
7604
7616
|
...inputSchemaMerges && { [TdSpanAttributes.INPUT_SCHEMA_MERGES]: JSON.stringify(inputSchemaMerges) },
|
|
7605
7617
|
...metadata && { [TdSpanAttributes.METADATA]: JSON.stringify(metadata) }
|
|
@@ -7619,15 +7631,15 @@ var SpanUtils = class SpanUtils {
|
|
|
7619
7631
|
*/
|
|
7620
7632
|
static getCurrentSpanInfo() {
|
|
7621
7633
|
try {
|
|
7622
|
-
const activeSpan = import_src$
|
|
7634
|
+
const activeSpan = import_src$33.trace.getActiveSpan();
|
|
7623
7635
|
if (!activeSpan) return null;
|
|
7624
7636
|
const spanContext = activeSpan.spanContext();
|
|
7625
7637
|
return {
|
|
7626
7638
|
traceId: spanContext.traceId,
|
|
7627
7639
|
spanId: spanContext.spanId,
|
|
7628
7640
|
span: activeSpan,
|
|
7629
|
-
context: import_src$
|
|
7630
|
-
isPreAppStart: import_src$
|
|
7641
|
+
context: import_src$33.context.active(),
|
|
7642
|
+
isPreAppStart: import_src$33.context.active().getValue(IS_PRE_APP_START_CONTEXT_KEY)
|
|
7631
7643
|
};
|
|
7632
7644
|
} catch (error) {
|
|
7633
7645
|
logger.error("SpanUtils error getting current span info:", error);
|
|
@@ -7691,7 +7703,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7691
7703
|
}
|
|
7692
7704
|
static setCurrentReplayTraceId(replayTraceId) {
|
|
7693
7705
|
try {
|
|
7694
|
-
return import_src$
|
|
7706
|
+
return import_src$33.context.active().setValue(REPLAY_TRACE_ID_CONTEXT_KEY, replayTraceId);
|
|
7695
7707
|
} catch (error) {
|
|
7696
7708
|
logger.error("SpanUtils error setting current replay trace id:", error);
|
|
7697
7709
|
return null;
|
|
@@ -7702,7 +7714,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7702
7714
|
*/
|
|
7703
7715
|
static getCurrentReplayTraceId() {
|
|
7704
7716
|
try {
|
|
7705
|
-
return import_src$
|
|
7717
|
+
return import_src$33.context.active().getValue(REPLAY_TRACE_ID_CONTEXT_KEY);
|
|
7706
7718
|
} catch (error) {
|
|
7707
7719
|
logger.error("SpanUtils error getting current replay trace id:", error);
|
|
7708
7720
|
return null;
|
|
@@ -7966,30 +7978,6 @@ var TdHttpMockSocket = class extends events.EventEmitter {
|
|
|
7966
7978
|
}
|
|
7967
7979
|
};
|
|
7968
7980
|
|
|
7969
|
-
//#endregion
|
|
7970
|
-
//#region src/instrumentation/core/trackers/EnvVarTracker.ts
|
|
7971
|
-
var EnvVarTracker = class {
|
|
7972
|
-
static setEnvVar({ traceId, key, value }) {
|
|
7973
|
-
this.envVars.set(traceId, {
|
|
7974
|
-
...this.envVars.get(traceId) || {},
|
|
7975
|
-
[key]: value
|
|
7976
|
-
});
|
|
7977
|
-
}
|
|
7978
|
-
static setEnvVars(traceId, envVars) {
|
|
7979
|
-
this.envVars.set(traceId, envVars);
|
|
7980
|
-
}
|
|
7981
|
-
static getEnvVar(traceId, key) {
|
|
7982
|
-
return this.envVars.get(traceId)?.[key];
|
|
7983
|
-
}
|
|
7984
|
-
static getEnvVars(traceId) {
|
|
7985
|
-
return this.envVars.get(traceId);
|
|
7986
|
-
}
|
|
7987
|
-
static clearEnvVars(traceId) {
|
|
7988
|
-
this.envVars.delete(traceId);
|
|
7989
|
-
}
|
|
7990
|
-
};
|
|
7991
|
-
EnvVarTracker.envVars = /* @__PURE__ */ new Map();
|
|
7992
|
-
|
|
7993
7981
|
//#endregion
|
|
7994
7982
|
//#region src/instrumentation/core/trackers/DateTracker.ts
|
|
7995
7983
|
/**
|
|
@@ -8290,6 +8278,7 @@ function convertMockRequestDataToCleanSpanData(mockRequestData, tuskDrift, input
|
|
|
8290
8278
|
return {
|
|
8291
8279
|
...mockRequestData,
|
|
8292
8280
|
parentSpanId: "",
|
|
8281
|
+
environment: tuskDrift.getEnvironment(),
|
|
8293
8282
|
inputValueHash,
|
|
8294
8283
|
inputSchema,
|
|
8295
8284
|
inputSchemaHash,
|
|
@@ -8374,7 +8363,7 @@ function findMockResponseSync({ mockRequestData, tuskDrift, inputValueSchemaMerg
|
|
|
8374
8363
|
|
|
8375
8364
|
//#endregion
|
|
8376
8365
|
//#region src/instrumentation/libraries/http/mocks/TdMockClientRequest.ts
|
|
8377
|
-
var import_src$
|
|
8366
|
+
var import_src$32 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
8378
8367
|
let ClientRequest;
|
|
8379
8368
|
/**
|
|
8380
8369
|
* Mock ClientRequest implementation for Tusk Drift HTTP replay
|
|
@@ -8545,7 +8534,7 @@ var TdMockClientRequest = class TdMockClientRequest extends events.EventEmitter
|
|
|
8545
8534
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
8546
8535
|
submoduleName: rawInputValue.method,
|
|
8547
8536
|
inputValue,
|
|
8548
|
-
kind: import_src$
|
|
8537
|
+
kind: import_src$32.SpanKind.CLIENT,
|
|
8549
8538
|
stackTrace: this.stackTrace
|
|
8550
8539
|
},
|
|
8551
8540
|
tuskDrift: this.tuskDrift,
|
|
@@ -8686,13 +8675,6 @@ var HttpReplayHooks = class {
|
|
|
8686
8675
|
return traceIdHeader ? String(traceIdHeader) : null;
|
|
8687
8676
|
}
|
|
8688
8677
|
/**
|
|
8689
|
-
* Check if we should fetch env vars from CLI
|
|
8690
|
-
*/
|
|
8691
|
-
extractShouldFetchEnvVars(req) {
|
|
8692
|
-
const fetchHeader = req.headers["x-td-fetch-env-vars"] || req.headers["X-TD-FETCH-ENV-VARS"];
|
|
8693
|
-
return fetchHeader === "true" || fetchHeader === true;
|
|
8694
|
-
}
|
|
8695
|
-
/**
|
|
8696
8678
|
* Handle outbound HTTP requests in replay mode
|
|
8697
8679
|
* Uses TdMockClientRequest for simplified mocking approach
|
|
8698
8680
|
*/
|
|
@@ -8722,7 +8704,7 @@ var HttpReplayHooks = class {
|
|
|
8722
8704
|
|
|
8723
8705
|
//#endregion
|
|
8724
8706
|
//#region src/instrumentation/core/utils/modeUtils.ts
|
|
8725
|
-
var import_src$
|
|
8707
|
+
var import_src$31 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
8726
8708
|
/**
|
|
8727
8709
|
* Utility function that abstracts the common record mode pattern of checking for current span context
|
|
8728
8710
|
* and deciding whether to execute record mode logic or just call the original function.
|
|
@@ -8743,7 +8725,7 @@ function handleRecordMode({ originalFunctionCall, recordModeHandler, spanKind })
|
|
|
8743
8725
|
return originalFunctionCall();
|
|
8744
8726
|
}
|
|
8745
8727
|
if (!isAppReady) return recordModeHandler({ isPreAppStart: true });
|
|
8746
|
-
if (!currentSpanInfo && spanKind !== import_src$
|
|
8728
|
+
if (!currentSpanInfo && spanKind !== import_src$31.SpanKind.SERVER || currentSpanInfo?.isPreAppStart) return originalFunctionCall();
|
|
8747
8729
|
else return recordModeHandler({ isPreAppStart: false });
|
|
8748
8730
|
}
|
|
8749
8731
|
/**
|
|
@@ -9981,7 +9963,7 @@ var require_commonjs$1 = /* @__PURE__ */ __commonJS({ "node_modules/@protobuf-ts
|
|
|
9981
9963
|
}) });
|
|
9982
9964
|
|
|
9983
9965
|
//#endregion
|
|
9984
|
-
//#region node_modules/@use-tusk/drift-schemas/dist/span_export_service-
|
|
9966
|
+
//#region node_modules/@use-tusk/drift-schemas/dist/span_export_service-CmkFvTqD.js
|
|
9985
9967
|
var import_commonjs$4 = /* @__PURE__ */ __toESM(require_commonjs$1(), 1);
|
|
9986
9968
|
var import_commonjs$5 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
|
|
9987
9969
|
var ExportSpansRequest$Type = class extends import_commonjs$5.MessageType {
|
|
@@ -10223,7 +10205,7 @@ function captureStackTrace(excludeClassNames = []) {
|
|
|
10223
10205
|
|
|
10224
10206
|
//#endregion
|
|
10225
10207
|
//#region src/instrumentation/libraries/http/HttpTransformEngine.ts
|
|
10226
|
-
var import_src$
|
|
10208
|
+
var import_src$30 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
10227
10209
|
/**
|
|
10228
10210
|
* Creates an empty HttpClientInputValue object for dropped spans
|
|
10229
10211
|
*/
|
|
@@ -10276,7 +10258,7 @@ var HttpTransformEngine = class {
|
|
|
10276
10258
|
const testSpan = {
|
|
10277
10259
|
traceId: "",
|
|
10278
10260
|
spanId: "",
|
|
10279
|
-
kind: import_src$
|
|
10261
|
+
kind: import_src$30.SpanKind.SERVER,
|
|
10280
10262
|
protocol: "http",
|
|
10281
10263
|
inputValue: {
|
|
10282
10264
|
method,
|
|
@@ -10299,7 +10281,7 @@ var HttpTransformEngine = class {
|
|
|
10299
10281
|
const testSpan = {
|
|
10300
10282
|
traceId: "",
|
|
10301
10283
|
spanId: "",
|
|
10302
|
-
kind: import_src$
|
|
10284
|
+
kind: import_src$30.SpanKind.CLIENT,
|
|
10303
10285
|
protocol: inputValue.protocol || "http",
|
|
10304
10286
|
inputValue: clonedInputValue
|
|
10305
10287
|
};
|
|
@@ -10326,8 +10308,8 @@ var HttpTransformEngine = class {
|
|
|
10326
10308
|
const matcherFunction = this.compileMatcher(matcher);
|
|
10327
10309
|
if (action.type === "drop") return (span) => {
|
|
10328
10310
|
if (!matcherFunction(span)) return;
|
|
10329
|
-
if (span.inputValue) span.inputValue = span.kind === import_src$
|
|
10330
|
-
if (span.outputValue) span.outputValue = span.kind === import_src$
|
|
10311
|
+
if (span.inputValue) span.inputValue = span.kind === import_src$30.SpanKind.CLIENT ? createEmptyClientInputValue(span.protocol) : createEmptyServerInputValue();
|
|
10312
|
+
if (span.outputValue) span.outputValue = span.kind === import_src$30.SpanKind.CLIENT ? createEmptyClientOutputValue() : createEmptyServerOutputValue();
|
|
10331
10313
|
return {
|
|
10332
10314
|
type: "drop",
|
|
10333
10315
|
field: "entire_span",
|
|
@@ -10357,8 +10339,8 @@ var HttpTransformEngine = class {
|
|
|
10357
10339
|
}
|
|
10358
10340
|
compileMatcher(matcher) {
|
|
10359
10341
|
const checks = [];
|
|
10360
|
-
if (matcher.direction === "outbound") checks.push((span) => span.kind === import_src$
|
|
10361
|
-
else if (matcher.direction === "inbound") checks.push((span) => span.kind === import_src$
|
|
10342
|
+
if (matcher.direction === "outbound") checks.push((span) => span.kind === import_src$30.SpanKind.CLIENT);
|
|
10343
|
+
else if (matcher.direction === "inbound") checks.push((span) => span.kind === import_src$30.SpanKind.SERVER);
|
|
10362
10344
|
if (matcher.method) if (matcher.method.length === 0) {} else {
|
|
10363
10345
|
const methods = matcher.method.map((method) => method.toUpperCase());
|
|
10364
10346
|
checks.push((span) => {
|
|
@@ -10586,7 +10568,7 @@ var HttpTransformEngine = class {
|
|
|
10586
10568
|
|
|
10587
10569
|
//#endregion
|
|
10588
10570
|
//#region src/instrumentation/libraries/http/Instrumentation.ts
|
|
10589
|
-
var import_src$
|
|
10571
|
+
var import_src$29 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
10590
10572
|
var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
10591
10573
|
constructor(config) {
|
|
10592
10574
|
super("http", config);
|
|
@@ -10671,19 +10653,12 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10671
10653
|
return originalHandler.call(this);
|
|
10672
10654
|
}
|
|
10673
10655
|
logger.debug(`[HttpInstrumentation] Setting replay trace id`, replayTraceId);
|
|
10674
|
-
if (this.replayHooks.extractShouldFetchEnvVars(req)) try {
|
|
10675
|
-
const envVars = this.tuskDrift.requestEnvVarsSync(replayTraceId);
|
|
10676
|
-
EnvVarTracker.setEnvVars(replayTraceId, envVars);
|
|
10677
|
-
logger.debug(`[HttpInstrumentation] Fetched env vars from CLI for trace ${replayTraceId}`);
|
|
10678
|
-
} catch (error) {
|
|
10679
|
-
logger.error(`[HttpInstrumentation] Failed to fetch env vars from CLI:`, error);
|
|
10680
|
-
}
|
|
10681
10656
|
const ctxWithReplayTraceId = SpanUtils.setCurrentReplayTraceId(replayTraceId);
|
|
10682
10657
|
if (!ctxWithReplayTraceId) throw new Error("Error setting current replay trace id");
|
|
10683
|
-
return import_src$
|
|
10658
|
+
return import_src$29.context.with(ctxWithReplayTraceId, () => {
|
|
10684
10659
|
return SpanUtils.createAndExecuteSpan(this.mode, () => originalHandler.call(this), {
|
|
10685
10660
|
name: `${target}`,
|
|
10686
|
-
kind: import_src$
|
|
10661
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10687
10662
|
packageName: spanProtocol,
|
|
10688
10663
|
submodule: method,
|
|
10689
10664
|
packageType: PackageType.HTTP,
|
|
@@ -10728,7 +10703,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10728
10703
|
logger.debug(`[HttpInstrumentation] Http inbound request arriving, inputValue: ${JSON.stringify(inputValue)}`);
|
|
10729
10704
|
return SpanUtils.createAndExecuteSpan(this.mode, () => originalHandler.call(this), {
|
|
10730
10705
|
name: `${target}`,
|
|
10731
|
-
kind: import_src$
|
|
10706
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10732
10707
|
packageName: spanProtocol,
|
|
10733
10708
|
packageType: PackageType.HTTP,
|
|
10734
10709
|
submodule: method,
|
|
@@ -10748,7 +10723,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10748
10723
|
});
|
|
10749
10724
|
});
|
|
10750
10725
|
},
|
|
10751
|
-
spanKind: import_src$
|
|
10726
|
+
spanKind: import_src$29.SpanKind.SERVER
|
|
10752
10727
|
});
|
|
10753
10728
|
} else return originalHandler.call(this);
|
|
10754
10729
|
}
|
|
@@ -10765,8 +10740,8 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10765
10740
|
_handleInboundRequestInSpan({ req, res, originalHandler, spanInfo, inputValue, schemaMerges, protocol }) {
|
|
10766
10741
|
const self = this;
|
|
10767
10742
|
const spanProtocol = this._normalizeProtocol(protocol, "http");
|
|
10768
|
-
import_src$
|
|
10769
|
-
import_src$
|
|
10743
|
+
import_src$29.context.bind(spanInfo.context, req);
|
|
10744
|
+
import_src$29.context.bind(spanInfo.context, res);
|
|
10770
10745
|
let completeInputValue = inputValue;
|
|
10771
10746
|
this._captureServerRequestBody(req, spanInfo, inputValue, schemaMerges, (updatedInputValue) => {
|
|
10772
10747
|
completeInputValue = updatedInputValue;
|
|
@@ -10804,7 +10779,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10804
10779
|
const spanData = {
|
|
10805
10780
|
traceId: spanInfo.traceId,
|
|
10806
10781
|
spanId: spanInfo.spanId,
|
|
10807
|
-
kind: import_src$
|
|
10782
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10808
10783
|
protocol: spanProtocol,
|
|
10809
10784
|
inputValue: completeInputValue,
|
|
10810
10785
|
outputValue
|
|
@@ -10820,14 +10795,12 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10820
10795
|
},
|
|
10821
10796
|
headers: { matchImportance: 0 }
|
|
10822
10797
|
},
|
|
10823
|
-
metadata: { ENV_VARS: EnvVarTracker.getEnvVars(spanInfo.traceId) },
|
|
10824
10798
|
...spanData.transformMetadata && { transformMetadata: spanData.transformMetadata }
|
|
10825
10799
|
});
|
|
10826
|
-
EnvVarTracker.clearEnvVars(spanInfo.traceId);
|
|
10827
10800
|
const status = statusCode >= 400 ? {
|
|
10828
|
-
code: import_src$
|
|
10801
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
10829
10802
|
message: `HTTP ${statusCode}`
|
|
10830
|
-
} : { code: import_src$
|
|
10803
|
+
} : { code: import_src$29.SpanStatusCode.OK };
|
|
10831
10804
|
SpanUtils.setStatus(spanInfo.span, status);
|
|
10832
10805
|
const decodedType = getDecodedType(outputValue.headers?.["content-type"] || "");
|
|
10833
10806
|
if (decodedType && !ACCEPTABLE_CONTENT_TYPES.has(decodedType)) {
|
|
@@ -10869,6 +10842,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10869
10842
|
instrumentationName: "HttpInstrumentation",
|
|
10870
10843
|
submoduleName: completeInputValue.method || inputValue.method,
|
|
10871
10844
|
inputValue: completeInputValue,
|
|
10845
|
+
environment: self.tuskDrift.getEnvironment(),
|
|
10872
10846
|
outputValue,
|
|
10873
10847
|
inputSchema,
|
|
10874
10848
|
outputSchema,
|
|
@@ -10876,7 +10850,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10876
10850
|
outputSchemaHash: JsonSchemaHelper.generateDeterministicHash(outputSchema),
|
|
10877
10851
|
inputValueHash,
|
|
10878
10852
|
outputValueHash,
|
|
10879
|
-
kind: import_src$
|
|
10853
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10880
10854
|
packageType: PackageType.HTTP,
|
|
10881
10855
|
status: {
|
|
10882
10856
|
code: statusCode >= 400 ? StatusCode.ERROR : StatusCode.OK,
|
|
@@ -10905,7 +10879,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10905
10879
|
try {
|
|
10906
10880
|
logger.debug(`[HttpInstrumentation] Server request error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
10907
10881
|
SpanUtils.endSpan(spanInfo.span, {
|
|
10908
|
-
code: import_src$
|
|
10882
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
10909
10883
|
message: error.message
|
|
10910
10884
|
});
|
|
10911
10885
|
} catch (error$1) {
|
|
@@ -10916,7 +10890,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10916
10890
|
try {
|
|
10917
10891
|
logger.debug(`[HttpInstrumentation] Server response error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
10918
10892
|
SpanUtils.endSpan(spanInfo.span, {
|
|
10919
|
-
code: import_src$
|
|
10893
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
10920
10894
|
message: error.message
|
|
10921
10895
|
});
|
|
10922
10896
|
} catch (error$1) {
|
|
@@ -11121,7 +11095,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11121
11095
|
inputValue: completeInputValue
|
|
11122
11096
|
});
|
|
11123
11097
|
SpanUtils.endSpan(spanInfo.span, {
|
|
11124
|
-
code: import_src$
|
|
11098
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
11125
11099
|
message: error.message
|
|
11126
11100
|
});
|
|
11127
11101
|
} catch (error$1) {
|
|
@@ -11138,7 +11112,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11138
11112
|
const spanData = {
|
|
11139
11113
|
traceId: spanInfo.traceId,
|
|
11140
11114
|
spanId: spanInfo.spanId,
|
|
11141
|
-
kind: import_src$
|
|
11115
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11142
11116
|
protocol: normalizedProtocol,
|
|
11143
11117
|
inputValue,
|
|
11144
11118
|
outputValue
|
|
@@ -11151,9 +11125,9 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11151
11125
|
transformMetadata: spanData.transformMetadata ? spanData.transformMetadata : void 0
|
|
11152
11126
|
});
|
|
11153
11127
|
const status = statusCode >= 400 ? {
|
|
11154
|
-
code: import_src$
|
|
11128
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
11155
11129
|
message: `HTTP ${statusCode}`
|
|
11156
|
-
} : { code: import_src$
|
|
11130
|
+
} : { code: import_src$29.SpanStatusCode.OK };
|
|
11157
11131
|
SpanUtils.endSpan(spanInfo.span, status);
|
|
11158
11132
|
}
|
|
11159
11133
|
_captureHeadersFromRawHeaders(rawHeaders) {
|
|
@@ -11207,7 +11181,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11207
11181
|
};
|
|
11208
11182
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalRequest.apply(this, args), {
|
|
11209
11183
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11210
|
-
kind: import_src$
|
|
11184
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11211
11185
|
packageName: requestProtocol,
|
|
11212
11186
|
packageType: PackageType.HTTP,
|
|
11213
11187
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11242,7 +11216,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11242
11216
|
};
|
|
11243
11217
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalRequest.apply(this, args), {
|
|
11244
11218
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11245
|
-
kind: import_src$
|
|
11219
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11246
11220
|
packageName: requestProtocol,
|
|
11247
11221
|
packageType: PackageType.HTTP,
|
|
11248
11222
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11254,7 +11228,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11254
11228
|
return self._handleOutboundRequestInSpan(originalRequest, args, spanInfo, inputValue, { headers: { matchImportance: 0 } });
|
|
11255
11229
|
});
|
|
11256
11230
|
},
|
|
11257
|
-
spanKind: import_src$
|
|
11231
|
+
spanKind: import_src$29.SpanKind.CLIENT
|
|
11258
11232
|
});
|
|
11259
11233
|
else return originalRequest.apply(this, args);
|
|
11260
11234
|
};
|
|
@@ -11300,7 +11274,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11300
11274
|
};
|
|
11301
11275
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalGet.apply(this, args), {
|
|
11302
11276
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11303
|
-
kind: import_src$
|
|
11277
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11304
11278
|
packageName: requestProtocol,
|
|
11305
11279
|
packageType: PackageType.HTTP,
|
|
11306
11280
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11334,7 +11308,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11334
11308
|
};
|
|
11335
11309
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalGet.apply(this, args), {
|
|
11336
11310
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11337
|
-
kind: import_src$
|
|
11311
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11338
11312
|
packageName: requestProtocol,
|
|
11339
11313
|
packageType: PackageType.HTTP,
|
|
11340
11314
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11346,7 +11320,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11346
11320
|
return self._handleOutboundRequestInSpan(originalGet, args, spanInfo, inputValue, { headers: { matchImportance: 0 } });
|
|
11347
11321
|
});
|
|
11348
11322
|
},
|
|
11349
|
-
spanKind: import_src$
|
|
11323
|
+
spanKind: import_src$29.SpanKind.CLIENT
|
|
11350
11324
|
});
|
|
11351
11325
|
else return originalGet.apply(this, args);
|
|
11352
11326
|
};
|
|
@@ -11389,99 +11363,9 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11389
11363
|
}
|
|
11390
11364
|
};
|
|
11391
11365
|
|
|
11392
|
-
//#endregion
|
|
11393
|
-
//#region src/instrumentation/libraries/env/Instrumentation.ts
|
|
11394
|
-
/**
|
|
11395
|
-
* Environment variable instrumentation that records and replays process.env access.
|
|
11396
|
-
* In record mode, captures environment variable values.
|
|
11397
|
-
* In replay mode, returns previously recorded values for deterministic behavior.
|
|
11398
|
-
*/
|
|
11399
|
-
var EnvInstrumentation = class extends TdInstrumentationBase {
|
|
11400
|
-
constructor(config = {}) {
|
|
11401
|
-
super("env", config);
|
|
11402
|
-
this.isInPatchedCall = false;
|
|
11403
|
-
this.mode = config.mode || TuskDriftMode.DISABLED;
|
|
11404
|
-
}
|
|
11405
|
-
init() {
|
|
11406
|
-
this.patchProcessEnv();
|
|
11407
|
-
return [];
|
|
11408
|
-
}
|
|
11409
|
-
patchProcessEnv() {
|
|
11410
|
-
if (this.mode === TuskDriftMode.DISABLED || !this._config.enabled) return;
|
|
11411
|
-
this.originalProcessEnv = process.env;
|
|
11412
|
-
const envProxy = new Proxy(this.originalProcessEnv, {
|
|
11413
|
-
get: (target, property, receiver) => {
|
|
11414
|
-
return this._handleEnvAccess(target, property);
|
|
11415
|
-
},
|
|
11416
|
-
set: (target, property, value, receiver) => {
|
|
11417
|
-
target[property] = value;
|
|
11418
|
-
return true;
|
|
11419
|
-
},
|
|
11420
|
-
deleteProperty: (target, property) => {
|
|
11421
|
-
delete target[property];
|
|
11422
|
-
return true;
|
|
11423
|
-
},
|
|
11424
|
-
ownKeys: (target) => {
|
|
11425
|
-
return Reflect.ownKeys(target);
|
|
11426
|
-
},
|
|
11427
|
-
getOwnPropertyDescriptor: (target, property) => {
|
|
11428
|
-
return Reflect.getOwnPropertyDescriptor(target, property);
|
|
11429
|
-
},
|
|
11430
|
-
has: (target, property) => {
|
|
11431
|
-
return Reflect.has(target, property);
|
|
11432
|
-
}
|
|
11433
|
-
});
|
|
11434
|
-
process.env = envProxy;
|
|
11435
|
-
}
|
|
11436
|
-
_handleEnvAccess(target, key) {
|
|
11437
|
-
if (this.isInPatchedCall) return target[key];
|
|
11438
|
-
if (!TuskDriftCore.getInstance().isAppReady()) return target[key];
|
|
11439
|
-
this.isInPatchedCall = true;
|
|
11440
|
-
try {
|
|
11441
|
-
return this._handleEnvAccessInMode(target, key);
|
|
11442
|
-
} finally {
|
|
11443
|
-
this.isInPatchedCall = false;
|
|
11444
|
-
}
|
|
11445
|
-
}
|
|
11446
|
-
_handleEnvAccessInMode(target, key) {
|
|
11447
|
-
let currentSpanInfo = null;
|
|
11448
|
-
try {
|
|
11449
|
-
currentSpanInfo = SpanUtils.getCurrentSpanInfo();
|
|
11450
|
-
} catch (error) {
|
|
11451
|
-
logger.error(`EnvInstrumentation error getting current span info:`, error);
|
|
11452
|
-
}
|
|
11453
|
-
if (!currentSpanInfo) return target[key];
|
|
11454
|
-
if (this.mode === TuskDriftMode.REPLAY) return this._handleReplayMode(target, key);
|
|
11455
|
-
else if (this.mode === TuskDriftMode.RECORD) return this._handleRecordMode(currentSpanInfo, target, key);
|
|
11456
|
-
else return target[key];
|
|
11457
|
-
}
|
|
11458
|
-
_handleReplayMode(target, key) {
|
|
11459
|
-
const replayTraceId = SpanUtils.getCurrentReplayTraceId();
|
|
11460
|
-
if (!replayTraceId) return target[key];
|
|
11461
|
-
const envVar = EnvVarTracker.getEnvVar(replayTraceId, key);
|
|
11462
|
-
if (envVar) {
|
|
11463
|
-
logger.debug(`Returning env var ${key} for trace ${replayTraceId}: ${envVar}`);
|
|
11464
|
-
return envVar;
|
|
11465
|
-
}
|
|
11466
|
-
return target[key];
|
|
11467
|
-
}
|
|
11468
|
-
_handleRecordMode(spanInfo, target, key) {
|
|
11469
|
-
try {
|
|
11470
|
-
EnvVarTracker.setEnvVar({
|
|
11471
|
-
traceId: spanInfo.traceId,
|
|
11472
|
-
key,
|
|
11473
|
-
value: target[key] || void 0
|
|
11474
|
-
});
|
|
11475
|
-
} catch (error) {
|
|
11476
|
-
logger.error(`EnvInstrumentation error storing env var:`, error);
|
|
11477
|
-
}
|
|
11478
|
-
return target[key];
|
|
11479
|
-
}
|
|
11480
|
-
};
|
|
11481
|
-
|
|
11482
11366
|
//#endregion
|
|
11483
11367
|
//#region src/instrumentation/libraries/date/Instrumentation.ts
|
|
11484
|
-
var import_src$
|
|
11368
|
+
var import_src$28 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
11485
11369
|
/**
|
|
11486
11370
|
* Date instrumentation that provides consistent dates in replay mode.
|
|
11487
11371
|
* In replay mode, new Date() calls return the latest mock response timestamp.
|
|
@@ -11520,7 +11404,7 @@ var DateInstrumentation = class DateInstrumentation extends TdInstrumentationBas
|
|
|
11520
11404
|
if (this.mode !== TuskDriftMode.REPLAY) return this._callOriginalDate(args, isConstructorCall);
|
|
11521
11405
|
const currentSpanInfo = SpanUtils.getCurrentSpanInfo();
|
|
11522
11406
|
if (!currentSpanInfo) return this._callOriginalDate(args, isConstructorCall);
|
|
11523
|
-
if (currentSpanInfo.context.getValue(SPAN_KIND_CONTEXT_KEY) !== import_src$
|
|
11407
|
+
if (currentSpanInfo.context.getValue(SPAN_KIND_CONTEXT_KEY) !== import_src$28.SpanKind.SERVER) return this._callOriginalDate(args, isConstructorCall);
|
|
11524
11408
|
this.isInPatchedCall = true;
|
|
11525
11409
|
try {
|
|
11526
11410
|
return this._handleReplayDate(args, isConstructorCall);
|
|
@@ -11766,7 +11650,7 @@ var TdPgClientMock = class extends events.EventEmitter {
|
|
|
11766
11650
|
|
|
11767
11651
|
//#endregion
|
|
11768
11652
|
//#region src/instrumentation/libraries/pg/Instrumentation.ts
|
|
11769
|
-
var import_src$
|
|
11653
|
+
var import_src$27 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
11770
11654
|
var PgInstrumentation = class extends TdInstrumentationBase {
|
|
11771
11655
|
constructor(config = {}) {
|
|
11772
11656
|
super("pg", config);
|
|
@@ -11807,6 +11691,10 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11807
11691
|
const self = this;
|
|
11808
11692
|
return (originalQuery) => {
|
|
11809
11693
|
return function query(...args) {
|
|
11694
|
+
if (self.isSubmittable(args[0])) {
|
|
11695
|
+
logger.debug(`[PgInstrumentation] Submittable query detected, passing through uninstrumented`);
|
|
11696
|
+
return originalQuery.apply(this, args);
|
|
11697
|
+
}
|
|
11810
11698
|
let queryConfig = null;
|
|
11811
11699
|
try {
|
|
11812
11700
|
queryConfig = self.parseQueryArgs(args);
|
|
@@ -11835,7 +11723,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11835
11723
|
const spanName = inputValue.clientType === "pool" ? "pg-pool.query" : "pg.query";
|
|
11836
11724
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalQuery.apply(this, args), {
|
|
11837
11725
|
name: spanName,
|
|
11838
|
-
kind: import_src$
|
|
11726
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11839
11727
|
submodule: "query",
|
|
11840
11728
|
packageType: PackageType.PG,
|
|
11841
11729
|
packageName,
|
|
@@ -11854,7 +11742,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11854
11742
|
const spanName = inputValue.clientType === "pool" ? "pg-pool.query" : "pg.query";
|
|
11855
11743
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalQuery.apply(this, args), {
|
|
11856
11744
|
name: spanName,
|
|
11857
|
-
kind: import_src$
|
|
11745
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11858
11746
|
submodule: "query",
|
|
11859
11747
|
packageType: PackageType.PG,
|
|
11860
11748
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11865,7 +11753,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11865
11753
|
return self._handleRecordQueryInSpan(spanInfo, originalQuery, queryConfig, args, this);
|
|
11866
11754
|
});
|
|
11867
11755
|
},
|
|
11868
|
-
spanKind: import_src$
|
|
11756
|
+
spanKind: import_src$27.SpanKind.CLIENT
|
|
11869
11757
|
});
|
|
11870
11758
|
else return originalQuery.apply(this, args);
|
|
11871
11759
|
};
|
|
@@ -11887,7 +11775,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11887
11775
|
replayModeHandler: () => {
|
|
11888
11776
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
11889
11777
|
name: `pg.connect`,
|
|
11890
|
-
kind: import_src$
|
|
11778
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11891
11779
|
submodule: "connect",
|
|
11892
11780
|
packageName: "pg",
|
|
11893
11781
|
packageType: PackageType.PG,
|
|
@@ -11904,7 +11792,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11904
11792
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
11905
11793
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
11906
11794
|
name: `pg.connect`,
|
|
11907
|
-
kind: import_src$
|
|
11795
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11908
11796
|
submodule: "connect",
|
|
11909
11797
|
packageName: "pg",
|
|
11910
11798
|
packageType: PackageType.PG,
|
|
@@ -11915,12 +11803,19 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11915
11803
|
return self._handleRecordConnectInSpan(spanInfo, originalConnect, callback, this);
|
|
11916
11804
|
});
|
|
11917
11805
|
},
|
|
11918
|
-
spanKind: import_src$
|
|
11806
|
+
spanKind: import_src$27.SpanKind.CLIENT
|
|
11919
11807
|
});
|
|
11920
11808
|
else return originalConnect.apply(this, [callback]);
|
|
11921
11809
|
};
|
|
11922
11810
|
};
|
|
11923
11811
|
}
|
|
11812
|
+
/**
|
|
11813
|
+
* Check if an object is a Submittable (Query object with submit method).
|
|
11814
|
+
* This is the same check pg uses internally: typeof config.submit === 'function'
|
|
11815
|
+
*/
|
|
11816
|
+
isSubmittable(arg) {
|
|
11817
|
+
return arg && typeof arg.submit === "function";
|
|
11818
|
+
}
|
|
11924
11819
|
parseQueryArgs(args) {
|
|
11925
11820
|
if (args.length === 0) return null;
|
|
11926
11821
|
const firstArg = args[0];
|
|
@@ -11948,7 +11843,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11948
11843
|
logger.debug(`[PgInstrumentation] PG query error (hasCallback): ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
11949
11844
|
try {
|
|
11950
11845
|
SpanUtils.endSpan(spanInfo.span, {
|
|
11951
|
-
code: import_src$
|
|
11846
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
11952
11847
|
message: error.message
|
|
11953
11848
|
});
|
|
11954
11849
|
} catch (error$1) {
|
|
@@ -11958,7 +11853,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11958
11853
|
logger.debug(`[PgInstrumentation] PG query completed successfully (hasCallback) (${SpanUtils.getTraceInfo()})`);
|
|
11959
11854
|
try {
|
|
11960
11855
|
this._addOutputAttributesToSpan(spanInfo, result);
|
|
11961
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
11856
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
11962
11857
|
} catch (error$1) {
|
|
11963
11858
|
logger.error(`[PgInstrumentation] error processing response:`, error$1);
|
|
11964
11859
|
}
|
|
@@ -11985,7 +11880,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11985
11880
|
logger.debug(`[PgInstrumentation] PG query completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
11986
11881
|
try {
|
|
11987
11882
|
this._addOutputAttributesToSpan(spanInfo, result);
|
|
11988
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
11883
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
11989
11884
|
} catch (error) {
|
|
11990
11885
|
logger.error(`[PgInstrumentation] error processing response:`, error);
|
|
11991
11886
|
}
|
|
@@ -11994,7 +11889,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11994
11889
|
logger.debug(`[PgInstrumentation] PG query error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
11995
11890
|
try {
|
|
11996
11891
|
SpanUtils.endSpan(spanInfo.span, {
|
|
11997
|
-
code: import_src$
|
|
11892
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
11998
11893
|
message: error.message
|
|
11999
11894
|
});
|
|
12000
11895
|
} catch (error$1) {
|
|
@@ -12026,7 +11921,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12026
11921
|
packageName,
|
|
12027
11922
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12028
11923
|
submoduleName: "query",
|
|
12029
|
-
kind: import_src$
|
|
11924
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
12030
11925
|
stackTrace
|
|
12031
11926
|
},
|
|
12032
11927
|
tuskDrift: this.tuskDrift
|
|
@@ -12070,6 +11965,8 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12070
11965
|
* Reference for data type IDs: https://jdbc.postgresql.org/documentation/publicapi/constant-values.html
|
|
12071
11966
|
*/
|
|
12072
11967
|
convertPostgresTypes(result, rowMode) {
|
|
11968
|
+
if (result && result.isMultiStatement && Array.isArray(result.results)) return result.results.map((singleResult) => this.convertPostgresTypes(singleResult, rowMode));
|
|
11969
|
+
if (Array.isArray(result)) return result.map((singleResult) => this.convertPostgresTypes(singleResult, rowMode));
|
|
12073
11970
|
if (!result || !result.fields || !result.rows) return result;
|
|
12074
11971
|
if (rowMode === "array") {
|
|
12075
11972
|
const convertedRows$1 = result.rows.map((row) => {
|
|
@@ -12110,7 +12007,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12110
12007
|
logger.debug(`[PgInstrumentation] PG connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12111
12008
|
try {
|
|
12112
12009
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12113
|
-
code: import_src$
|
|
12010
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12114
12011
|
message: error.message
|
|
12115
12012
|
});
|
|
12116
12013
|
} catch (error$1) {
|
|
@@ -12120,7 +12017,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12120
12017
|
logger.debug(`[PgInstrumentation] PG connect completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12121
12018
|
try {
|
|
12122
12019
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { connected: true } });
|
|
12123
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12020
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12124
12021
|
} catch (error$1) {
|
|
12125
12022
|
logger.error(`[PgInstrumentation] error processing connect response:`, error$1);
|
|
12126
12023
|
}
|
|
@@ -12132,7 +12029,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12132
12029
|
logger.debug(`[PgInstrumentation] PG connect completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12133
12030
|
try {
|
|
12134
12031
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { connected: true } });
|
|
12135
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12032
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12136
12033
|
} catch (error) {
|
|
12137
12034
|
logger.error(`[PgInstrumentation] error processing connect response:`, error);
|
|
12138
12035
|
}
|
|
@@ -12141,7 +12038,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12141
12038
|
logger.debug(`[PgInstrumentation] PG connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12142
12039
|
try {
|
|
12143
12040
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12144
|
-
code: import_src$
|
|
12041
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12145
12042
|
message: error.message
|
|
12146
12043
|
});
|
|
12147
12044
|
} catch (error$1) {
|
|
@@ -12159,7 +12056,18 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12159
12056
|
}
|
|
12160
12057
|
_addOutputAttributesToSpan(spanInfo, result) {
|
|
12161
12058
|
if (!result) return;
|
|
12162
|
-
|
|
12059
|
+
let outputValue;
|
|
12060
|
+
if (Array.isArray(result)) outputValue = {
|
|
12061
|
+
isMultiStatement: true,
|
|
12062
|
+
results: result.map((r) => ({
|
|
12063
|
+
command: r.command,
|
|
12064
|
+
rowCount: r.rowCount,
|
|
12065
|
+
oid: r.oid,
|
|
12066
|
+
rows: r.rows || [],
|
|
12067
|
+
fields: r.fields || []
|
|
12068
|
+
}))
|
|
12069
|
+
};
|
|
12070
|
+
else outputValue = {
|
|
12163
12071
|
command: result.command,
|
|
12164
12072
|
rowCount: result.rowCount,
|
|
12165
12073
|
oid: result.oid,
|
|
@@ -12202,7 +12110,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12202
12110
|
replayModeHandler: () => {
|
|
12203
12111
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
12204
12112
|
name: `pg-pool.connect`,
|
|
12205
|
-
kind: import_src$
|
|
12113
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
12206
12114
|
submodule: "connect",
|
|
12207
12115
|
packageName: "pg-pool",
|
|
12208
12116
|
packageType: PackageType.PG,
|
|
@@ -12219,7 +12127,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12219
12127
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
12220
12128
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
12221
12129
|
name: `pg-pool.connect`,
|
|
12222
|
-
kind: import_src$
|
|
12130
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
12223
12131
|
submodule: "connect",
|
|
12224
12132
|
packageName: "pg-pool",
|
|
12225
12133
|
packageType: PackageType.PG,
|
|
@@ -12230,7 +12138,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12230
12138
|
return self._handleRecordPoolConnectInSpan(spanInfo, originalConnect, callback, this);
|
|
12231
12139
|
});
|
|
12232
12140
|
},
|
|
12233
|
-
spanKind: import_src$
|
|
12141
|
+
spanKind: import_src$27.SpanKind.CLIENT
|
|
12234
12142
|
});
|
|
12235
12143
|
else return originalConnect.apply(this, [callback]);
|
|
12236
12144
|
};
|
|
@@ -12243,7 +12151,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12243
12151
|
logger.debug(`[PgInstrumentation] PG Pool connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12244
12152
|
try {
|
|
12245
12153
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12246
|
-
code: import_src$
|
|
12154
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12247
12155
|
message: error.message
|
|
12248
12156
|
});
|
|
12249
12157
|
} catch (error$1) {
|
|
@@ -12256,7 +12164,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12256
12164
|
connected: true,
|
|
12257
12165
|
hasClient: !!client
|
|
12258
12166
|
} });
|
|
12259
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12167
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12260
12168
|
} catch (error$1) {
|
|
12261
12169
|
logger.error(`[PgInstrumentation] error processing pool connect response:`, error$1);
|
|
12262
12170
|
}
|
|
@@ -12271,7 +12179,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12271
12179
|
connected: true,
|
|
12272
12180
|
hasClient: !!client
|
|
12273
12181
|
} });
|
|
12274
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12182
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12275
12183
|
} catch (error) {
|
|
12276
12184
|
logger.error(`[PgInstrumentation] error processing pool connect response:`, error);
|
|
12277
12185
|
}
|
|
@@ -12280,7 +12188,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12280
12188
|
logger.debug(`[PgInstrumentation] PG Pool connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12281
12189
|
try {
|
|
12282
12190
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12283
|
-
code: import_src$
|
|
12191
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12284
12192
|
message: error.message
|
|
12285
12193
|
});
|
|
12286
12194
|
} catch (error$1) {
|
|
@@ -12309,68 +12217,114 @@ function isPostgresOutputValueType(value) {
|
|
|
12309
12217
|
}
|
|
12310
12218
|
|
|
12311
12219
|
//#endregion
|
|
12312
|
-
//#region src/instrumentation/libraries/postgres/
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12316
|
-
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12220
|
+
//#region src/instrumentation/libraries/postgres/utils/typeConversion.ts
|
|
12221
|
+
/**
|
|
12222
|
+
* Convert PostgreSQL string values back to appropriate JavaScript types
|
|
12223
|
+
* based on field metadata from the recorded response.
|
|
12224
|
+
*/
|
|
12225
|
+
function convertPostgresTypes(result) {
|
|
12226
|
+
if (!isPostgresOutputValueType(result)) {
|
|
12227
|
+
logger.error(`[PostgresInstrumentation] output value is not of type PostgresOutputValueType`, result);
|
|
12228
|
+
return;
|
|
12320
12229
|
}
|
|
12321
|
-
|
|
12322
|
-
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
12230
|
+
const { rows, count, command, columns, state, statement } = result;
|
|
12231
|
+
const resultArray = Array.from((rows || []).map((row) => reconstructBuffers(row)));
|
|
12232
|
+
if (count !== void 0) Object.defineProperty(resultArray, "count", {
|
|
12233
|
+
value: count,
|
|
12234
|
+
writable: true,
|
|
12235
|
+
enumerable: false
|
|
12236
|
+
});
|
|
12237
|
+
if (command !== void 0) Object.defineProperty(resultArray, "command", {
|
|
12238
|
+
value: command,
|
|
12239
|
+
writable: true,
|
|
12240
|
+
enumerable: false
|
|
12241
|
+
});
|
|
12242
|
+
if (columns !== void 0) Object.defineProperty(resultArray, "columns", {
|
|
12243
|
+
value: columns,
|
|
12244
|
+
writable: true,
|
|
12245
|
+
enumerable: false
|
|
12246
|
+
});
|
|
12247
|
+
if (state !== void 0) Object.defineProperty(resultArray, "state", {
|
|
12248
|
+
value: state,
|
|
12249
|
+
writable: true,
|
|
12250
|
+
enumerable: false
|
|
12251
|
+
});
|
|
12252
|
+
if (statement !== void 0) Object.defineProperty(resultArray, "statement", {
|
|
12253
|
+
value: statement,
|
|
12254
|
+
writable: true,
|
|
12255
|
+
enumerable: false
|
|
12256
|
+
});
|
|
12257
|
+
return resultArray;
|
|
12258
|
+
}
|
|
12259
|
+
/**
|
|
12260
|
+
* Recursively reconstructs Buffer objects from their JSON-serialized format.
|
|
12261
|
+
* When Buffers are JSON.stringify'd, they become { type: "Buffer", data: [...] }.
|
|
12262
|
+
* This method converts them back to actual Buffer instances.
|
|
12263
|
+
*/
|
|
12264
|
+
function reconstructBuffers(value) {
|
|
12265
|
+
if (value === null || value === void 0) return value;
|
|
12266
|
+
if (typeof value === "object" && value.type === "Buffer" && Array.isArray(value.data)) return Buffer.from(value.data);
|
|
12267
|
+
if (Array.isArray(value)) return value.map((item) => reconstructBuffers(item));
|
|
12268
|
+
if (typeof value === "object") {
|
|
12269
|
+
const result = {};
|
|
12270
|
+
for (const key of Object.keys(value)) result[key] = reconstructBuffers(value[key]);
|
|
12271
|
+
return result;
|
|
12327
12272
|
}
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
|
|
12331
|
-
|
|
12332
|
-
|
|
12333
|
-
|
|
12334
|
-
|
|
12335
|
-
|
|
12336
|
-
|
|
12337
|
-
|
|
12338
|
-
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12352
|
-
|
|
12353
|
-
|
|
12354
|
-
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
logger.debug(`[PostgresInstrumentation] Postgres module patching complete`);
|
|
12366
|
-
return postgresModule;
|
|
12273
|
+
return value;
|
|
12274
|
+
}
|
|
12275
|
+
/**
|
|
12276
|
+
* Add output attributes to span for PostgreSQL results.
|
|
12277
|
+
*/
|
|
12278
|
+
function addOutputAttributesToSpan(spanInfo, result) {
|
|
12279
|
+
if (!result) return;
|
|
12280
|
+
const isArray$1 = Array.isArray(result);
|
|
12281
|
+
logger.debug(`[PostgresInstrumentation] Adding output attributes to span for ${isArray$1 ? "array" : "object"} result`);
|
|
12282
|
+
const normalizeValue = (val) => {
|
|
12283
|
+
if (Buffer.isBuffer(val)) return val.toString("utf8");
|
|
12284
|
+
else if (Array.isArray(val)) return val.map(normalizeValue);
|
|
12285
|
+
else if (val && typeof val === "object" && val.type === "Buffer" && Array.isArray(val.data)) return Buffer.from(val.data).toString("utf8");
|
|
12286
|
+
return val;
|
|
12287
|
+
};
|
|
12288
|
+
const outputValue = {
|
|
12289
|
+
rows: isArray$1 ? Array.from(result).map(normalizeValue) : (result.rows || []).map(normalizeValue),
|
|
12290
|
+
count: result.count !== void 0 && result.count !== null ? result.count : void 0,
|
|
12291
|
+
command: result.command || void 0,
|
|
12292
|
+
columns: result.columns || void 0,
|
|
12293
|
+
state: result.state || void 0,
|
|
12294
|
+
statement: result.statement || void 0
|
|
12295
|
+
};
|
|
12296
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
12297
|
+
}
|
|
12298
|
+
|
|
12299
|
+
//#endregion
|
|
12300
|
+
//#region src/instrumentation/libraries/postgres/utils/queryUtils.ts
|
|
12301
|
+
/**
|
|
12302
|
+
* Reconstruct a parameterized query string from template strings array and values.
|
|
12303
|
+
* Converts values to $1, $2, etc. placeholders.
|
|
12304
|
+
*/
|
|
12305
|
+
function reconstructQueryString(strings, values) {
|
|
12306
|
+
let queryString = "";
|
|
12307
|
+
for (let i = 0; i < strings.length; i++) {
|
|
12308
|
+
queryString += strings[i];
|
|
12309
|
+
if (i < values.length) queryString += `$${i + 1}`;
|
|
12367
12310
|
}
|
|
12368
|
-
|
|
12369
|
-
|
|
12370
|
-
|
|
12311
|
+
return queryString;
|
|
12312
|
+
}
|
|
12313
|
+
|
|
12314
|
+
//#endregion
|
|
12315
|
+
//#region src/instrumentation/libraries/postgres/handlers/ConnectionHandler.ts
|
|
12316
|
+
var import_src$26 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
12317
|
+
var ConnectionHandler = class {
|
|
12318
|
+
constructor(mode, instrumentationName, isAppReady, wrapSqlInstance) {
|
|
12319
|
+
this.mode = mode;
|
|
12320
|
+
this.instrumentationName = instrumentationName;
|
|
12321
|
+
this.isAppReady = isAppReady;
|
|
12322
|
+
this.wrapSqlInstance = wrapSqlInstance;
|
|
12323
|
+
}
|
|
12324
|
+
handlePostgresConnection(originalFunction, args) {
|
|
12371
12325
|
const inputValue = {
|
|
12372
|
-
connectionString:
|
|
12373
|
-
options:
|
|
12326
|
+
connectionString: typeof args[0] === "string" ? args[0] : void 0,
|
|
12327
|
+
options: typeof args[0] === "string" ? args[1] : args[0]
|
|
12374
12328
|
};
|
|
12375
12329
|
if (this.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
12376
12330
|
noOpRequestHandler: () => {
|
|
@@ -12384,96 +12338,148 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12384
12338
|
}));
|
|
12385
12339
|
mockSql.begin = () => Promise.resolve();
|
|
12386
12340
|
mockSql.end = () => Promise.resolve();
|
|
12341
|
+
mockSql.file = () => Promise.resolve(Object.assign([], {
|
|
12342
|
+
count: 0,
|
|
12343
|
+
command: null
|
|
12344
|
+
}));
|
|
12345
|
+
mockSql.reserve = () => Promise.resolve(mockSql);
|
|
12346
|
+
mockSql.listen = () => Promise.resolve({
|
|
12347
|
+
state: { state: "I" },
|
|
12348
|
+
unlisten: async () => {}
|
|
12349
|
+
});
|
|
12350
|
+
mockSql.notify = () => Promise.resolve();
|
|
12387
12351
|
return mockSql;
|
|
12388
12352
|
},
|
|
12389
12353
|
isServerRequest: false,
|
|
12390
12354
|
replayModeHandler: () => {
|
|
12391
12355
|
return SpanUtils.createAndExecuteSpan(this.mode, () => {
|
|
12392
12356
|
const sqlInstance = originalFunction(...args);
|
|
12393
|
-
return this.
|
|
12357
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12394
12358
|
}, {
|
|
12395
12359
|
name: "postgres.connect",
|
|
12396
|
-
kind: import_src$
|
|
12360
|
+
kind: import_src$26.SpanKind.CLIENT,
|
|
12397
12361
|
submodule: "connect",
|
|
12398
12362
|
packageType: PackageType.PG,
|
|
12399
12363
|
packageName: "postgres",
|
|
12400
|
-
instrumentationName: this.
|
|
12364
|
+
instrumentationName: this.instrumentationName,
|
|
12401
12365
|
inputValue,
|
|
12402
|
-
isPreAppStart: false
|
|
12366
|
+
isPreAppStart: this.isAppReady() ? false : true
|
|
12403
12367
|
}, (spanInfo) => {
|
|
12404
|
-
return this.
|
|
12368
|
+
return this.handleReplayConnect(originalFunction, args);
|
|
12405
12369
|
});
|
|
12406
12370
|
}
|
|
12407
12371
|
});
|
|
12408
12372
|
else if (this.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
12409
12373
|
originalFunctionCall: () => {
|
|
12410
12374
|
const sqlInstance = originalFunction(...args);
|
|
12411
|
-
return this.
|
|
12375
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12412
12376
|
},
|
|
12413
12377
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
12414
12378
|
return SpanUtils.createAndExecuteSpan(this.mode, () => {
|
|
12415
12379
|
const sqlInstance = originalFunction(...args);
|
|
12416
|
-
return this.
|
|
12380
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12417
12381
|
}, {
|
|
12418
12382
|
name: "postgres.connect",
|
|
12419
|
-
kind: import_src$
|
|
12383
|
+
kind: import_src$26.SpanKind.CLIENT,
|
|
12420
12384
|
submodule: "connect",
|
|
12421
12385
|
packageType: PackageType.PG,
|
|
12422
12386
|
packageName: "postgres",
|
|
12423
|
-
instrumentationName: this.
|
|
12387
|
+
instrumentationName: this.instrumentationName,
|
|
12424
12388
|
inputValue,
|
|
12425
12389
|
isPreAppStart
|
|
12426
12390
|
}, (spanInfo) => {
|
|
12427
|
-
return this.
|
|
12391
|
+
return this.handleRecordConnect(spanInfo, originalFunction, args);
|
|
12428
12392
|
});
|
|
12429
12393
|
},
|
|
12430
|
-
spanKind: import_src$
|
|
12394
|
+
spanKind: import_src$26.SpanKind.CLIENT
|
|
12431
12395
|
});
|
|
12432
12396
|
else return originalFunction(...args);
|
|
12433
12397
|
}
|
|
12434
|
-
|
|
12435
|
-
try {
|
|
12436
|
-
const url = new URL(connectionString);
|
|
12437
|
-
if (url.password) url.password = "***";
|
|
12438
|
-
return url.toString();
|
|
12439
|
-
} catch {
|
|
12440
|
-
return "[INVALID_URL]";
|
|
12441
|
-
}
|
|
12442
|
-
}
|
|
12443
|
-
_sanitizeConnectionOptions(options) {
|
|
12444
|
-
if (!options || typeof options !== "object") return options;
|
|
12445
|
-
const sanitized = { ...options };
|
|
12446
|
-
if (sanitized.password) sanitized.password = "***";
|
|
12447
|
-
if (sanitized.ssl && typeof sanitized.ssl === "object") {
|
|
12448
|
-
sanitized.ssl = { ...sanitized.ssl };
|
|
12449
|
-
if (sanitized.ssl.key) sanitized.ssl.key = "***";
|
|
12450
|
-
if (sanitized.ssl.cert) sanitized.ssl.cert = "***";
|
|
12451
|
-
if (sanitized.ssl.ca) sanitized.ssl.ca = "***";
|
|
12452
|
-
}
|
|
12453
|
-
return sanitized;
|
|
12454
|
-
}
|
|
12455
|
-
_handleRecordConnect(spanInfo, originalFunction, args) {
|
|
12398
|
+
handleRecordConnect(spanInfo, originalFunction, args) {
|
|
12456
12399
|
const sqlInstance = originalFunction(...args);
|
|
12457
|
-
const wrappedInstance = this.
|
|
12400
|
+
const wrappedInstance = this.wrapSqlInstance(sqlInstance);
|
|
12458
12401
|
try {
|
|
12459
12402
|
logger.debug(`[PostgresInstrumentation] Postgres connection created successfully (${SpanUtils.getTraceInfo()})`);
|
|
12460
12403
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { connected: true } });
|
|
12461
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12404
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$26.SpanStatusCode.OK });
|
|
12462
12405
|
} catch (error) {
|
|
12463
12406
|
logger.error(`[PostgresInstrumentation] error adding span attributes:`, error);
|
|
12464
12407
|
}
|
|
12465
12408
|
return wrappedInstance;
|
|
12466
12409
|
}
|
|
12467
|
-
|
|
12410
|
+
handleReplayConnect(originalFunction, args) {
|
|
12468
12411
|
logger.debug(`[PostgresInstrumentation] Replaying Postgres connection`);
|
|
12469
12412
|
try {
|
|
12470
12413
|
const sqlInstance = originalFunction(...args);
|
|
12471
|
-
return this.
|
|
12414
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12472
12415
|
} catch (error) {
|
|
12473
12416
|
logger.debug(`[PostgresInstrumentation] Postgres connection error in replay: ${error.message}`);
|
|
12474
12417
|
throw error;
|
|
12475
12418
|
}
|
|
12476
12419
|
}
|
|
12420
|
+
};
|
|
12421
|
+
|
|
12422
|
+
//#endregion
|
|
12423
|
+
//#region src/instrumentation/libraries/postgres/Instrumentation.ts
|
|
12424
|
+
var import_src$25 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
12425
|
+
var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
12426
|
+
constructor(config = {}) {
|
|
12427
|
+
super("postgres", config);
|
|
12428
|
+
this.INSTRUMENTATION_NAME = "PostgresInstrumentation";
|
|
12429
|
+
this.mode = config.mode || TuskDriftMode.DISABLED;
|
|
12430
|
+
this.tuskDrift = TuskDriftCore.getInstance();
|
|
12431
|
+
this.connectionHandler = new ConnectionHandler(this.mode, this.INSTRUMENTATION_NAME, () => this.tuskDrift.isAppReady(), (sqlInstance) => this._wrapSqlInstance(sqlInstance));
|
|
12432
|
+
}
|
|
12433
|
+
init() {
|
|
12434
|
+
return [new TdInstrumentationNodeModule({
|
|
12435
|
+
name: "postgres",
|
|
12436
|
+
supportedVersions: ["3.*"],
|
|
12437
|
+
patch: (moduleExports) => this._patchPostgresModule(moduleExports)
|
|
12438
|
+
})];
|
|
12439
|
+
}
|
|
12440
|
+
_patchPostgresModule(postgresModule) {
|
|
12441
|
+
logger.debug(`[PostgresInstrumentation] Patching Postgres module in ${this.mode} mode`);
|
|
12442
|
+
if (this.isModulePatched(postgresModule)) {
|
|
12443
|
+
logger.debug(`[PostgresInstrumentation] Postgres module already patched, skipping`);
|
|
12444
|
+
return postgresModule;
|
|
12445
|
+
}
|
|
12446
|
+
const self = this;
|
|
12447
|
+
if (isEsm(postgresModule)) {
|
|
12448
|
+
logger.debug(`[PostgresInstrumentation] Wrapping ESM default export`);
|
|
12449
|
+
this._wrap(postgresModule, "default", (originalFunction) => {
|
|
12450
|
+
return function(...args) {
|
|
12451
|
+
return self._handlePostgresConnection(originalFunction, args);
|
|
12452
|
+
};
|
|
12453
|
+
});
|
|
12454
|
+
} else {
|
|
12455
|
+
logger.debug(`[PostgresInstrumentation] Module is a function (CJS style)`);
|
|
12456
|
+
const originalFunction = postgresModule;
|
|
12457
|
+
const wrappedFunction = function(...args) {
|
|
12458
|
+
logger.debug(`[PostgresInstrumentation] Wrapped postgres() (CJS) called with args:`, args);
|
|
12459
|
+
return self._handlePostgresConnection(originalFunction, args);
|
|
12460
|
+
};
|
|
12461
|
+
Object.setPrototypeOf(wrappedFunction, Object.getPrototypeOf(originalFunction));
|
|
12462
|
+
Object.defineProperty(wrappedFunction, "name", { value: originalFunction.name });
|
|
12463
|
+
for (const key in originalFunction) if (originalFunction.hasOwnProperty(key)) wrappedFunction[key] = originalFunction[key];
|
|
12464
|
+
Object.getOwnPropertyNames(originalFunction).forEach((key) => {
|
|
12465
|
+
if (key !== "prototype" && key !== "length" && key !== "name") {
|
|
12466
|
+
const descriptor = Object.getOwnPropertyDescriptor(originalFunction, key);
|
|
12467
|
+
if (descriptor) Object.defineProperty(wrappedFunction, key, descriptor);
|
|
12468
|
+
}
|
|
12469
|
+
});
|
|
12470
|
+
postgresModule = wrappedFunction;
|
|
12471
|
+
}
|
|
12472
|
+
if (postgresModule.sql && typeof postgresModule.sql === "function") {
|
|
12473
|
+
this._wrap(postgresModule, "sql", this._getSqlPatchFn());
|
|
12474
|
+
logger.debug(`[PostgresInstrumentation] Wrapped sql function`);
|
|
12475
|
+
}
|
|
12476
|
+
this.markModuleAsPatched(postgresModule);
|
|
12477
|
+
logger.debug(`[PostgresInstrumentation] Postgres module patching complete`);
|
|
12478
|
+
return postgresModule;
|
|
12479
|
+
}
|
|
12480
|
+
_handlePostgresConnection(originalFunction, args) {
|
|
12481
|
+
return this.connectionHandler.handlePostgresConnection(originalFunction, args);
|
|
12482
|
+
}
|
|
12477
12483
|
_wrapSqlInstance(sqlInstance) {
|
|
12478
12484
|
if (!sqlInstance || typeof sqlInstance !== "function") return sqlInstance;
|
|
12479
12485
|
const self = this;
|
|
@@ -12489,11 +12495,34 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12489
12495
|
logger.debug(`[PostgresInstrumentation] Wrapped unsafe method on sql instance`);
|
|
12490
12496
|
}
|
|
12491
12497
|
if (typeof originalSql.begin === "function") {
|
|
12492
|
-
|
|
12493
|
-
|
|
12498
|
+
const wrappedBegin = self._wrapBeginMethod(originalSql);
|
|
12499
|
+
originalSql.begin = wrappedBegin;
|
|
12500
|
+
wrappedSql.begin = wrappedBegin;
|
|
12501
|
+
}
|
|
12502
|
+
if (typeof originalSql.file === "function") {
|
|
12503
|
+
wrappedSql.file = self._wrapFileMethod(originalSql);
|
|
12504
|
+
logger.debug(`[PostgresInstrumentation] Wrapped file method on sql instance`);
|
|
12505
|
+
}
|
|
12506
|
+
if (typeof originalSql.reserve === "function") {
|
|
12507
|
+
wrappedSql.reserve = self._wrapReserveMethod(originalSql);
|
|
12508
|
+
logger.debug(`[PostgresInstrumentation] Wrapped reserve method on sql instance`);
|
|
12509
|
+
}
|
|
12510
|
+
if (typeof originalSql.listen === "function") {
|
|
12511
|
+
wrappedSql.listen = self._wrapListenMethod(originalSql);
|
|
12512
|
+
logger.debug(`[PostgresInstrumentation] Wrapped listen method on sql instance`);
|
|
12513
|
+
}
|
|
12514
|
+
if (typeof originalSql.notify === "function") {
|
|
12515
|
+
wrappedSql.notify = self._wrapNotifyMethod(wrappedSql);
|
|
12516
|
+
logger.debug(`[PostgresInstrumentation] Wrapped notify method on sql instance`);
|
|
12494
12517
|
}
|
|
12495
12518
|
return wrappedSql;
|
|
12496
12519
|
}
|
|
12520
|
+
_wrapNotifyMethod(wrappedSqlInstance) {
|
|
12521
|
+
return async function notify(channel, payload) {
|
|
12522
|
+
logger.debug(`[PostgresInstrumentation] notify() called for channel ${channel}`);
|
|
12523
|
+
return wrappedSqlInstance`select pg_notify(${channel}, ${String(payload)})`;
|
|
12524
|
+
};
|
|
12525
|
+
}
|
|
12497
12526
|
_wrapUnsafeMethod(sqlInstance) {
|
|
12498
12527
|
const self = this;
|
|
12499
12528
|
const originalUnsafe = sqlInstance.unsafe;
|
|
@@ -12510,9 +12539,178 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12510
12539
|
return self._handleBeginTransaction(sqlInstance, originalBegin, options, transactionCallback);
|
|
12511
12540
|
};
|
|
12512
12541
|
}
|
|
12513
|
-
|
|
12542
|
+
_wrapFileMethod(sqlInstance) {
|
|
12514
12543
|
const self = this;
|
|
12515
|
-
|
|
12544
|
+
const originalFile = sqlInstance.file;
|
|
12545
|
+
return function file(path$5, parameters, queryOptions) {
|
|
12546
|
+
return self._handleFileQuery(sqlInstance, originalFile, path$5, parameters, queryOptions);
|
|
12547
|
+
};
|
|
12548
|
+
}
|
|
12549
|
+
_wrapReserveMethod(sqlInstance) {
|
|
12550
|
+
const self = this;
|
|
12551
|
+
const originalReserve = sqlInstance.reserve;
|
|
12552
|
+
return async function reserve() {
|
|
12553
|
+
if (self.mode === TuskDriftMode.REPLAY) {
|
|
12554
|
+
logger.debug(`[PostgresInstrumentation] REPLAY mode: Creating mock reserved connection without TCP`);
|
|
12555
|
+
const mockReservedSql = self._wrapSqlInstance(sqlInstance);
|
|
12556
|
+
if (typeof mockReservedSql === "function") mockReservedSql.release = function() {
|
|
12557
|
+
logger.debug(`[PostgresInstrumentation] Mock reserved connection released`);
|
|
12558
|
+
};
|
|
12559
|
+
return mockReservedSql;
|
|
12560
|
+
}
|
|
12561
|
+
const reservedSql = await originalReserve.call(sqlInstance);
|
|
12562
|
+
const wrappedReservedSql = self._wrapSqlInstance(reservedSql);
|
|
12563
|
+
logger.debug(`[PostgresInstrumentation] Reserved connection obtained and wrapped`);
|
|
12564
|
+
return wrappedReservedSql;
|
|
12565
|
+
};
|
|
12566
|
+
}
|
|
12567
|
+
_wrapListenMethod(sqlInstance) {
|
|
12568
|
+
const self = this;
|
|
12569
|
+
const originalListen = sqlInstance.listen;
|
|
12570
|
+
return async function listen(channelName, callback, onlisten) {
|
|
12571
|
+
return self._handleListenMethod(sqlInstance, originalListen, channelName, callback, onlisten);
|
|
12572
|
+
};
|
|
12573
|
+
}
|
|
12574
|
+
async _handleListenMethod(sqlInstance, originalListen, channelName, callback, onlisten) {
|
|
12575
|
+
const inputValue = {
|
|
12576
|
+
operation: "listen",
|
|
12577
|
+
channel: channelName
|
|
12578
|
+
};
|
|
12579
|
+
if (this.mode === TuskDriftMode.REPLAY) return this._handleReplayListen(channelName, callback, onlisten, inputValue);
|
|
12580
|
+
else if (this.mode === TuskDriftMode.RECORD) return this._handleRecordListen(sqlInstance, originalListen, channelName, callback, onlisten, inputValue);
|
|
12581
|
+
else return originalListen.call(sqlInstance, channelName, callback, onlisten);
|
|
12582
|
+
}
|
|
12583
|
+
async _handleRecordListen(sqlInstance, originalListen, channelName, callback, onlisten, inputValue) {
|
|
12584
|
+
const receivedPayloads = [];
|
|
12585
|
+
const wrappedCallback = (payload) => {
|
|
12586
|
+
logger.debug(`[PostgresInstrumentation] RECORD: Captured notification payload on channel ${channelName}: ${payload}`);
|
|
12587
|
+
receivedPayloads.push(payload);
|
|
12588
|
+
callback(payload);
|
|
12589
|
+
};
|
|
12590
|
+
return handleRecordMode({
|
|
12591
|
+
originalFunctionCall: () => originalListen.call(sqlInstance, channelName, callback, onlisten),
|
|
12592
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
12593
|
+
return SpanUtils.createAndExecuteSpan(this.mode, () => originalListen.call(sqlInstance, channelName, callback, onlisten), {
|
|
12594
|
+
name: "postgres.listen",
|
|
12595
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
12596
|
+
submodule: "listen",
|
|
12597
|
+
packageType: PackageType.PG,
|
|
12598
|
+
packageName: "postgres",
|
|
12599
|
+
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12600
|
+
inputValue,
|
|
12601
|
+
isPreAppStart
|
|
12602
|
+
}, async (spanInfo) => {
|
|
12603
|
+
try {
|
|
12604
|
+
const result = await originalListen.call(sqlInstance, channelName, wrappedCallback, onlisten);
|
|
12605
|
+
try {
|
|
12606
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12607
|
+
channel: channelName,
|
|
12608
|
+
state: result.state
|
|
12609
|
+
} });
|
|
12610
|
+
} catch (error) {
|
|
12611
|
+
logger.error(`[PostgresInstrumentation] error adding span attributes:`, error);
|
|
12612
|
+
}
|
|
12613
|
+
const originalUnlisten = result.unlisten;
|
|
12614
|
+
const wrappedUnlisten = async () => {
|
|
12615
|
+
logger.debug(`[PostgresInstrumentation] RECORD: Unlisten called, captured ${receivedPayloads.length} payloads`);
|
|
12616
|
+
try {
|
|
12617
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12618
|
+
channel: channelName,
|
|
12619
|
+
state: result.state,
|
|
12620
|
+
payloads: receivedPayloads
|
|
12621
|
+
} });
|
|
12622
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12623
|
+
} catch (error) {
|
|
12624
|
+
logger.error(`[PostgresInstrumentation] error adding span attributes:`, error);
|
|
12625
|
+
}
|
|
12626
|
+
return originalUnlisten();
|
|
12627
|
+
};
|
|
12628
|
+
return {
|
|
12629
|
+
state: result.state,
|
|
12630
|
+
unlisten: wrappedUnlisten
|
|
12631
|
+
};
|
|
12632
|
+
} catch (error) {
|
|
12633
|
+
logger.error(`[PostgresInstrumentation] RECORD listen error: ${error.message}`);
|
|
12634
|
+
try {
|
|
12635
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
12636
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
12637
|
+
message: error.message
|
|
12638
|
+
});
|
|
12639
|
+
} catch (error$1) {
|
|
12640
|
+
logger.error(`[PostgresInstrumentation] error ending span:`, error$1);
|
|
12641
|
+
}
|
|
12642
|
+
throw error;
|
|
12643
|
+
}
|
|
12644
|
+
});
|
|
12645
|
+
},
|
|
12646
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
12647
|
+
});
|
|
12648
|
+
}
|
|
12649
|
+
async _handleReplayListen(channelName, callback, onlisten, inputValue) {
|
|
12650
|
+
logger.debug(`[PostgresInstrumentation] REPLAY: Mocking listen for channel ${channelName} without TCP`);
|
|
12651
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
12652
|
+
return handleReplayMode({
|
|
12653
|
+
noOpRequestHandler: () => Promise.resolve({
|
|
12654
|
+
state: { state: "I" },
|
|
12655
|
+
unlisten: async () => {}
|
|
12656
|
+
}),
|
|
12657
|
+
isServerRequest: false,
|
|
12658
|
+
replayModeHandler: () => {
|
|
12659
|
+
return SpanUtils.createAndExecuteSpan(this.mode, () => Promise.resolve({
|
|
12660
|
+
state: { state: "I" },
|
|
12661
|
+
unlisten: async () => {}
|
|
12662
|
+
}), {
|
|
12663
|
+
name: "postgres.listen",
|
|
12664
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
12665
|
+
submodule: "listen",
|
|
12666
|
+
packageType: PackageType.PG,
|
|
12667
|
+
packageName: "postgres",
|
|
12668
|
+
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12669
|
+
inputValue,
|
|
12670
|
+
isPreAppStart: this.tuskDrift.isAppReady() ? false : true
|
|
12671
|
+
}, async (spanInfo) => {
|
|
12672
|
+
try {
|
|
12673
|
+
const mockData = await this._findMockData({
|
|
12674
|
+
spanInfo,
|
|
12675
|
+
name: "postgres.listen",
|
|
12676
|
+
inputValue,
|
|
12677
|
+
submoduleName: "listen",
|
|
12678
|
+
stackTrace
|
|
12679
|
+
});
|
|
12680
|
+
if (!mockData) {
|
|
12681
|
+
logger.warn(`[PostgresInstrumentation] No mock data found for listen channel: ${channelName}`);
|
|
12682
|
+
throw new Error(`No mock data found for listen channel: ${channelName}`);
|
|
12683
|
+
}
|
|
12684
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for listen: ${JSON.stringify(mockData)}`);
|
|
12685
|
+
const recordedPayloads = mockData.result?.payloads || [];
|
|
12686
|
+
const recordedState = mockData.result?.state || { state: "I" };
|
|
12687
|
+
if (onlisten) onlisten();
|
|
12688
|
+
for (const payload of recordedPayloads) {
|
|
12689
|
+
logger.debug(`[PostgresInstrumentation] REPLAY: Invoking callback with recorded payload: ${payload}`);
|
|
12690
|
+
callback(payload);
|
|
12691
|
+
}
|
|
12692
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12693
|
+
return {
|
|
12694
|
+
state: recordedState,
|
|
12695
|
+
unlisten: async () => {
|
|
12696
|
+
logger.debug(`[PostgresInstrumentation] REPLAY: Mock unlisten called`);
|
|
12697
|
+
}
|
|
12698
|
+
};
|
|
12699
|
+
} catch (error) {
|
|
12700
|
+
logger.error(`[PostgresInstrumentation] REPLAY listen error: ${error.message}`);
|
|
12701
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
12702
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
12703
|
+
message: error.message
|
|
12704
|
+
});
|
|
12705
|
+
throw error;
|
|
12706
|
+
}
|
|
12707
|
+
});
|
|
12708
|
+
}
|
|
12709
|
+
});
|
|
12710
|
+
}
|
|
12711
|
+
_getSqlPatchFn() {
|
|
12712
|
+
const self = this;
|
|
12713
|
+
return (originalSql) => {
|
|
12516
12714
|
return function sql(strings, ...values) {
|
|
12517
12715
|
return self._handleSqlQuery(originalSql, strings, values);
|
|
12518
12716
|
};
|
|
@@ -12522,93 +12720,19 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12522
12720
|
if (!strings || !Array.isArray(strings.raw)) return originalSql.call(this, strings, ...values);
|
|
12523
12721
|
const creationContext = import_src$25.context.active();
|
|
12524
12722
|
const query = originalSql.call(this, strings, ...values);
|
|
12525
|
-
const
|
|
12526
|
-
|
|
12527
|
-
|
|
12528
|
-
let queryString = "";
|
|
12529
|
-
for (let i = 0; i < strings.length; i++) {
|
|
12530
|
-
queryString += strings[i];
|
|
12531
|
-
if (i < values.length) queryString += `$${i + 1}`;
|
|
12532
|
-
}
|
|
12533
|
-
const inputValue = {
|
|
12534
|
-
query: queryString.trim(),
|
|
12535
|
-
parameters: values
|
|
12536
|
-
};
|
|
12537
|
-
return import_src$25.context.with(creationContext, () => {
|
|
12538
|
-
if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
12539
|
-
originalFunctionCall: () => originalThen(onFulfilled, onRejected),
|
|
12540
|
-
recordModeHandler: ({ isPreAppStart }) => {
|
|
12541
|
-
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12542
|
-
name: "postgres.query",
|
|
12543
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12544
|
-
submodule: "query",
|
|
12545
|
-
packageType: PackageType.PG,
|
|
12546
|
-
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
12547
|
-
packageName: "postgres",
|
|
12548
|
-
inputValue,
|
|
12549
|
-
isPreAppStart
|
|
12550
|
-
}, (spanInfo) => {
|
|
12551
|
-
const wrappedOnFulfilled = (result) => {
|
|
12552
|
-
try {
|
|
12553
|
-
logger.debug(`[PostgresInstrumentation] Postgres query completed successfully`, result);
|
|
12554
|
-
self._addOutputAttributesToSpan(spanInfo, result);
|
|
12555
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12556
|
-
} catch (error) {
|
|
12557
|
-
logger.error(`[PostgresInstrumentation] error processing query response:`, error);
|
|
12558
|
-
}
|
|
12559
|
-
return onFulfilled ? onFulfilled(result) : result;
|
|
12560
|
-
};
|
|
12561
|
-
const wrappedOnRejected = (error) => {
|
|
12562
|
-
try {
|
|
12563
|
-
logger.debug(`[PostgresInstrumentation] Postgres query error`, error);
|
|
12564
|
-
SpanUtils.endSpan(spanInfo.span, {
|
|
12565
|
-
code: import_src$25.SpanStatusCode.ERROR,
|
|
12566
|
-
message: error.message
|
|
12567
|
-
});
|
|
12568
|
-
} catch (spanError) {
|
|
12569
|
-
logger.error(`[PostgresInstrumentation] error ending span:`, spanError);
|
|
12570
|
-
}
|
|
12571
|
-
if (onRejected) return onRejected(error);
|
|
12572
|
-
throw error;
|
|
12573
|
-
};
|
|
12574
|
-
return originalThen(wrappedOnFulfilled, wrappedOnRejected);
|
|
12575
|
-
});
|
|
12576
|
-
},
|
|
12577
|
-
spanKind: import_src$25.SpanKind.CLIENT
|
|
12578
|
-
});
|
|
12579
|
-
else if (self.mode === TuskDriftMode.REPLAY) {
|
|
12580
|
-
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
12581
|
-
return handleReplayMode({
|
|
12582
|
-
noOpRequestHandler: () => Promise.resolve(Object.assign([], {
|
|
12583
|
-
count: 0,
|
|
12584
|
-
command: null
|
|
12585
|
-
})),
|
|
12586
|
-
isServerRequest: false,
|
|
12587
|
-
replayModeHandler: () => {
|
|
12588
|
-
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12589
|
-
name: "postgres.query",
|
|
12590
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12591
|
-
submodule: "query",
|
|
12592
|
-
packageType: PackageType.PG,
|
|
12593
|
-
packageName: "postgres",
|
|
12594
|
-
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
12595
|
-
inputValue,
|
|
12596
|
-
isPreAppStart: false
|
|
12597
|
-
}, async (spanInfo) => {
|
|
12598
|
-
const mockedResult = await self.handleReplaySqlQuery({
|
|
12599
|
-
inputValue,
|
|
12600
|
-
spanInfo,
|
|
12601
|
-
submodule: "query",
|
|
12602
|
-
name: "postgres.query",
|
|
12603
|
-
stackTrace
|
|
12604
|
-
});
|
|
12605
|
-
return onFulfilled ? onFulfilled(mockedResult) : mockedResult;
|
|
12606
|
-
});
|
|
12607
|
-
}
|
|
12608
|
-
});
|
|
12609
|
-
} else return originalThen(onFulfilled, onRejected);
|
|
12610
|
-
});
|
|
12723
|
+
const inputValue = {
|
|
12724
|
+
query: reconstructQueryString(strings, values).trim(),
|
|
12725
|
+
parameters: values
|
|
12611
12726
|
};
|
|
12727
|
+
const originalThen = query.then.bind(query);
|
|
12728
|
+
this._wrapThenMethod(query, originalThen, inputValue, creationContext, {
|
|
12729
|
+
name: "postgres.query",
|
|
12730
|
+
submodule: "query",
|
|
12731
|
+
operationType: "sql"
|
|
12732
|
+
});
|
|
12733
|
+
this._wrapExecuteMethod(query);
|
|
12734
|
+
this._wrapCursorMethod(query, inputValue, creationContext);
|
|
12735
|
+
this._wrapForEachMethod(query, inputValue, creationContext);
|
|
12612
12736
|
return query;
|
|
12613
12737
|
}
|
|
12614
12738
|
_handleUnsafeQuery(sqlInstance, originalUnsafe, query, parameters, queryOptions) {
|
|
@@ -12619,21 +12743,46 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12619
12743
|
})();
|
|
12620
12744
|
const creationContext = import_src$25.context.active();
|
|
12621
12745
|
const originalThen = unsafeQuery.then.bind(unsafeQuery);
|
|
12622
|
-
const self = this;
|
|
12623
12746
|
const inputValue = {
|
|
12624
12747
|
query: query.trim(),
|
|
12625
12748
|
parameters: parameters || [],
|
|
12626
12749
|
options: queryOptions
|
|
12627
12750
|
};
|
|
12628
|
-
unsafeQuery
|
|
12751
|
+
this._wrapThenMethod(unsafeQuery, originalThen, inputValue, creationContext, {
|
|
12752
|
+
name: "postgres.unsafe",
|
|
12753
|
+
submodule: "unsafe",
|
|
12754
|
+
operationType: "unsafe"
|
|
12755
|
+
});
|
|
12756
|
+
this._wrapExecuteMethod(unsafeQuery);
|
|
12757
|
+
this._wrapCursorMethod(unsafeQuery, inputValue, creationContext);
|
|
12758
|
+
this._wrapForEachMethod(unsafeQuery, inputValue, creationContext);
|
|
12759
|
+
return unsafeQuery;
|
|
12760
|
+
}
|
|
12761
|
+
_handleFileQuery(sqlInstance, originalFile, path$5, parameters, queryOptions) {
|
|
12762
|
+
const fileQuery = (() => {
|
|
12763
|
+
if (queryOptions !== void 0) return originalFile.call(sqlInstance, path$5, parameters, queryOptions);
|
|
12764
|
+
else if (parameters !== void 0) return originalFile.call(sqlInstance, path$5, parameters);
|
|
12765
|
+
else return originalFile.call(sqlInstance, path$5);
|
|
12766
|
+
})();
|
|
12767
|
+
const creationContext = import_src$25.context.active();
|
|
12768
|
+
const originalThen = fileQuery.then.bind(fileQuery);
|
|
12769
|
+
const self = this;
|
|
12770
|
+
const inputValue = {
|
|
12771
|
+
query: path$5,
|
|
12772
|
+
parameters: parameters || [],
|
|
12773
|
+
options: queryOptions
|
|
12774
|
+
};
|
|
12775
|
+
fileQuery.then = function(onFulfilled, onRejected) {
|
|
12776
|
+
if (fileQuery._tuskRecorded) return originalThen(onFulfilled, onRejected);
|
|
12777
|
+
fileQuery._tuskRecorded = true;
|
|
12629
12778
|
return import_src$25.context.with(creationContext, () => {
|
|
12630
12779
|
if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
12631
12780
|
originalFunctionCall: () => originalThen(onFulfilled, onRejected),
|
|
12632
12781
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
12633
12782
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12634
|
-
name: "postgres.
|
|
12783
|
+
name: "postgres.file",
|
|
12635
12784
|
kind: import_src$25.SpanKind.CLIENT,
|
|
12636
|
-
submodule: "
|
|
12785
|
+
submodule: "file",
|
|
12637
12786
|
packageType: PackageType.PG,
|
|
12638
12787
|
packageName: "postgres",
|
|
12639
12788
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -12642,17 +12791,17 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12642
12791
|
}, (spanInfo) => {
|
|
12643
12792
|
const wrappedOnFulfilled = (result) => {
|
|
12644
12793
|
try {
|
|
12645
|
-
logger.debug(`[PostgresInstrumentation] Postgres
|
|
12646
|
-
|
|
12794
|
+
logger.debug(`[PostgresInstrumentation] Postgres file query completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12795
|
+
addOutputAttributesToSpan(spanInfo, result);
|
|
12647
12796
|
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12648
12797
|
} catch (error) {
|
|
12649
|
-
logger.error(`[PostgresInstrumentation] error processing
|
|
12798
|
+
logger.error(`[PostgresInstrumentation] error processing file query response:`, error);
|
|
12650
12799
|
}
|
|
12651
12800
|
return onFulfilled ? onFulfilled(result) : result;
|
|
12652
12801
|
};
|
|
12653
12802
|
const wrappedOnRejected = (error) => {
|
|
12654
12803
|
try {
|
|
12655
|
-
logger.debug(`[PostgresInstrumentation] Postgres
|
|
12804
|
+
logger.debug(`[PostgresInstrumentation] Postgres file query error: ${error.message}`);
|
|
12656
12805
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12657
12806
|
code: import_src$25.SpanStatusCode.ERROR,
|
|
12658
12807
|
message: error.message
|
|
@@ -12678,22 +12827,24 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12678
12827
|
isServerRequest: false,
|
|
12679
12828
|
replayModeHandler: () => {
|
|
12680
12829
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12681
|
-
name: "postgres.
|
|
12830
|
+
name: "postgres.file",
|
|
12682
12831
|
kind: import_src$25.SpanKind.CLIENT,
|
|
12683
|
-
submodule: "
|
|
12832
|
+
submodule: "file",
|
|
12684
12833
|
packageType: PackageType.PG,
|
|
12685
12834
|
packageName: "postgres",
|
|
12686
12835
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
12687
12836
|
inputValue,
|
|
12688
|
-
isPreAppStart: false
|
|
12837
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
12689
12838
|
}, async (spanInfo) => {
|
|
12690
|
-
const mockedResult = await self.
|
|
12839
|
+
const mockedResult = await self._handleReplayQueryOperation({
|
|
12691
12840
|
inputValue,
|
|
12692
12841
|
spanInfo,
|
|
12693
|
-
submodule: "
|
|
12694
|
-
name: "postgres.
|
|
12695
|
-
stackTrace
|
|
12842
|
+
submodule: "file",
|
|
12843
|
+
name: "postgres.file",
|
|
12844
|
+
stackTrace,
|
|
12845
|
+
operationType: "file"
|
|
12696
12846
|
});
|
|
12847
|
+
if (!mockedResult) throw new Error(`No mock data found for Postgres file query: ${inputValue.query}`);
|
|
12697
12848
|
return onFulfilled ? onFulfilled(mockedResult) : mockedResult;
|
|
12698
12849
|
});
|
|
12699
12850
|
}
|
|
@@ -12701,16 +12852,45 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12701
12852
|
} else return originalThen(onFulfilled, onRejected);
|
|
12702
12853
|
});
|
|
12703
12854
|
};
|
|
12704
|
-
|
|
12855
|
+
const originalExecute = fileQuery.execute ? fileQuery.execute.bind(fileQuery) : void 0;
|
|
12856
|
+
if (originalExecute) fileQuery.execute = function() {
|
|
12857
|
+
if (self.mode === TuskDriftMode.REPLAY) return this;
|
|
12858
|
+
else return originalExecute.call(this);
|
|
12859
|
+
};
|
|
12860
|
+
return fileQuery;
|
|
12861
|
+
}
|
|
12862
|
+
/**
|
|
12863
|
+
* Wraps a transaction callback to ensure the inner SQL instance is instrumented.
|
|
12864
|
+
* This is necessary because postgres.js creates a new SQL instance inside begin()
|
|
12865
|
+
* that would otherwise bypass instrumentation.
|
|
12866
|
+
*/
|
|
12867
|
+
_wrapTransactionCallback(transactionCallback) {
|
|
12868
|
+
const self = this;
|
|
12869
|
+
return (transactionSql) => {
|
|
12870
|
+
const wrappedSql = self._wrapSqlInstance(transactionSql);
|
|
12871
|
+
if (typeof transactionSql.savepoint === "function") {
|
|
12872
|
+
const originalSavepoint = transactionSql.savepoint;
|
|
12873
|
+
wrappedSql.savepoint = function(nameOrFn, fn) {
|
|
12874
|
+
const savepointCallback = typeof nameOrFn === "function" ? nameOrFn : fn;
|
|
12875
|
+
const savepointName = typeof nameOrFn === "string" ? nameOrFn : void 0;
|
|
12876
|
+
const wrappedSavepointCallback = self._wrapTransactionCallback(savepointCallback);
|
|
12877
|
+
if (savepointName) return originalSavepoint.call(transactionSql, savepointName, wrappedSavepointCallback);
|
|
12878
|
+
else return originalSavepoint.call(transactionSql, wrappedSavepointCallback);
|
|
12879
|
+
};
|
|
12880
|
+
}
|
|
12881
|
+
if (typeof transactionSql.prepare === "function") wrappedSql.prepare = transactionSql.prepare.bind(transactionSql);
|
|
12882
|
+
return transactionCallback(wrappedSql);
|
|
12883
|
+
};
|
|
12705
12884
|
}
|
|
12706
12885
|
_handleBeginTransaction(sqlInstance, originalBegin, options, transactionCallback) {
|
|
12707
12886
|
const inputValue = {
|
|
12708
12887
|
query: "BEGIN",
|
|
12709
12888
|
options: options ? { transactionOptions: options } : void 0
|
|
12710
12889
|
};
|
|
12890
|
+
const wrappedCallback = transactionCallback ? this._wrapTransactionCallback(transactionCallback) : void 0;
|
|
12711
12891
|
const executeBegin = () => {
|
|
12712
|
-
if (options &&
|
|
12713
|
-
else if (
|
|
12892
|
+
if (options && wrappedCallback) return originalBegin.call(sqlInstance, options, wrappedCallback);
|
|
12893
|
+
else if (wrappedCallback) return originalBegin.call(sqlInstance, wrappedCallback);
|
|
12714
12894
|
else return originalBegin.call(sqlInstance, options || void 0);
|
|
12715
12895
|
};
|
|
12716
12896
|
if (this.mode === TuskDriftMode.REPLAY) {
|
|
@@ -12727,9 +12907,9 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12727
12907
|
packageName: "postgres",
|
|
12728
12908
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12729
12909
|
inputValue,
|
|
12730
|
-
isPreAppStart: false
|
|
12910
|
+
isPreAppStart: this.tuskDrift.isAppReady() ? false : true
|
|
12731
12911
|
}, (spanInfo) => {
|
|
12732
|
-
return this._handleReplayBeginTransaction(spanInfo, options, stackTrace);
|
|
12912
|
+
return this._handleReplayBeginTransaction(spanInfo, options, stackTrace, wrappedCallback);
|
|
12733
12913
|
});
|
|
12734
12914
|
}
|
|
12735
12915
|
});
|
|
@@ -12754,55 +12934,47 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12754
12934
|
else return executeBegin();
|
|
12755
12935
|
}
|
|
12756
12936
|
_handleRecordBeginTransaction(spanInfo, executeBegin) {
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
|
|
12775
|
-
|
|
12776
|
-
|
|
12777
|
-
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
12784
|
-
});
|
|
12937
|
+
return executeBegin().then((result) => {
|
|
12938
|
+
logger.debug(`[PostgresInstrumentation] Postgres transaction completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12939
|
+
try {
|
|
12940
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12941
|
+
status: "committed",
|
|
12942
|
+
result
|
|
12943
|
+
} });
|
|
12944
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12945
|
+
} catch (error) {
|
|
12946
|
+
logger.error(`[PostgresInstrumentation] error processing transaction response:`, error);
|
|
12947
|
+
}
|
|
12948
|
+
return result;
|
|
12949
|
+
}).catch((error) => {
|
|
12950
|
+
logger.debug(`[PostgresInstrumentation] Postgres transaction error (rolled back): ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12951
|
+
try {
|
|
12952
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12953
|
+
status: "rolled_back",
|
|
12954
|
+
error: error.message
|
|
12955
|
+
} });
|
|
12956
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
12957
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
12958
|
+
message: error.message
|
|
12959
|
+
});
|
|
12960
|
+
} catch (spanError) {
|
|
12961
|
+
logger.error(`[PostgresInstrumentation] error ending span:`, spanError);
|
|
12962
|
+
}
|
|
12963
|
+
throw error;
|
|
12785
12964
|
});
|
|
12786
|
-
return promise;
|
|
12787
12965
|
}
|
|
12788
|
-
async _handleReplayBeginTransaction(spanInfo, options, stackTrace) {
|
|
12966
|
+
async _handleReplayBeginTransaction(spanInfo, options, stackTrace, wrappedCallback) {
|
|
12789
12967
|
logger.debug(`[PostgresInstrumentation] Replaying Postgres transaction`);
|
|
12790
|
-
const
|
|
12791
|
-
|
|
12792
|
-
|
|
12793
|
-
|
|
12794
|
-
|
|
12795
|
-
|
|
12796
|
-
|
|
12797
|
-
|
|
12798
|
-
|
|
12799
|
-
|
|
12800
|
-
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12801
|
-
submoduleName: "transaction",
|
|
12802
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12803
|
-
stackTrace
|
|
12804
|
-
},
|
|
12805
|
-
tuskDrift: this.tuskDrift
|
|
12968
|
+
const transactionInputValue = {
|
|
12969
|
+
query: "BEGIN",
|
|
12970
|
+
options: options ? { transactionOptions: options } : void 0
|
|
12971
|
+
};
|
|
12972
|
+
const mockData = await this._findMockData({
|
|
12973
|
+
spanInfo,
|
|
12974
|
+
name: "postgres.begin",
|
|
12975
|
+
inputValue: transactionInputValue,
|
|
12976
|
+
submoduleName: "transaction",
|
|
12977
|
+
stackTrace
|
|
12806
12978
|
});
|
|
12807
12979
|
if (!mockData) {
|
|
12808
12980
|
logger.warn(`[PostgresInstrumentation] No mock data found for transaction BEGIN`);
|
|
@@ -12810,15 +12982,49 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12810
12982
|
}
|
|
12811
12983
|
logger.debug(`[PostgresInstrumentation] Found mock data for transaction: ${JSON.stringify(mockData)}`);
|
|
12812
12984
|
const transactionResult = mockData.result;
|
|
12813
|
-
|
|
12985
|
+
const wasCommitted = transactionResult && typeof transactionResult === "object" && "status" in transactionResult && transactionResult.status === "committed";
|
|
12986
|
+
if (!wrappedCallback) if (wasCommitted) return transactionResult.result;
|
|
12814
12987
|
else {
|
|
12815
12988
|
const errorMessage = transactionResult && typeof transactionResult === "object" && "error" in transactionResult && transactionResult.error ? transactionResult.error : "Transaction rolled back";
|
|
12816
12989
|
throw new Error(errorMessage);
|
|
12817
12990
|
}
|
|
12991
|
+
try {
|
|
12992
|
+
const result = await wrappedCallback(this._createMockTransactionSql());
|
|
12993
|
+
logger.debug(`[PostgresInstrumentation] Replay transaction callback completed with result`);
|
|
12994
|
+
return result;
|
|
12995
|
+
} catch (error) {
|
|
12996
|
+
if (!wasCommitted) throw error;
|
|
12997
|
+
logger.error(`[PostgresInstrumentation] Unexpected error during transaction replay: ${error.message}`);
|
|
12998
|
+
throw error;
|
|
12999
|
+
}
|
|
12818
13000
|
}
|
|
12819
|
-
|
|
12820
|
-
|
|
12821
|
-
|
|
13001
|
+
/**
|
|
13002
|
+
* Creates a minimal mock SQL instance for transaction replay.
|
|
13003
|
+
* _wrapSqlInstance will wrap this and handle all the actual REPLAY logic.
|
|
13004
|
+
* The mock just needs to return objects with .then() methods that can be wrapped.
|
|
13005
|
+
*/
|
|
13006
|
+
_createMockTransactionSql() {
|
|
13007
|
+
const self = this;
|
|
13008
|
+
const createThenable = () => ({ then: (onFulfilled, onRejected) => Promise.resolve([]).then(onFulfilled, onRejected) });
|
|
13009
|
+
const mockSql = function() {
|
|
13010
|
+
return createThenable();
|
|
13011
|
+
};
|
|
13012
|
+
mockSql.unsafe = function() {
|
|
13013
|
+
return createThenable();
|
|
13014
|
+
};
|
|
13015
|
+
mockSql.savepoint = function(nameOrFn, fn) {
|
|
13016
|
+
const callback = typeof nameOrFn === "function" ? nameOrFn : fn;
|
|
13017
|
+
const nestedMockSql = self._createMockTransactionSql();
|
|
13018
|
+
return Promise.resolve(callback(nestedMockSql));
|
|
13019
|
+
};
|
|
13020
|
+
return mockSql;
|
|
13021
|
+
}
|
|
13022
|
+
/**
|
|
13023
|
+
* Generic helper to find mock data for replay operations.
|
|
13024
|
+
* Consolidates the common findMockResponseAsync pattern used across multiple handlers.
|
|
13025
|
+
*/
|
|
13026
|
+
async _findMockData({ spanInfo, name, inputValue, submoduleName, stackTrace }) {
|
|
13027
|
+
return findMockResponseAsync({
|
|
12822
13028
|
mockRequestData: {
|
|
12823
13029
|
traceId: spanInfo.traceId,
|
|
12824
13030
|
spanId: spanInfo.spanId,
|
|
@@ -12826,79 +13032,574 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12826
13032
|
inputValue: createMockInputValue(inputValue),
|
|
12827
13033
|
packageName: "postgres",
|
|
12828
13034
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12829
|
-
submoduleName
|
|
13035
|
+
submoduleName,
|
|
12830
13036
|
kind: import_src$25.SpanKind.CLIENT,
|
|
12831
13037
|
stackTrace
|
|
12832
13038
|
},
|
|
12833
13039
|
tuskDrift: this.tuskDrift
|
|
12834
13040
|
});
|
|
13041
|
+
}
|
|
13042
|
+
/**
|
|
13043
|
+
* Helper to end a cursor span with collected rows.
|
|
13044
|
+
* Consolidates common span ending logic used in cursor and forEach operations.
|
|
13045
|
+
*/
|
|
13046
|
+
_endCursorSpan(spanInfo, allRows, result, operation = "Cursor") {
|
|
13047
|
+
addOutputAttributesToSpan(spanInfo, Object.assign(allRows, {
|
|
13048
|
+
count: allRows.length,
|
|
13049
|
+
columns: result?.columns,
|
|
13050
|
+
state: result?.state,
|
|
13051
|
+
statement: result?.statement
|
|
13052
|
+
}));
|
|
13053
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13054
|
+
logger.debug(`[PostgresInstrumentation] ${operation} completed, recorded ${allRows.length} rows`);
|
|
13055
|
+
}
|
|
13056
|
+
/**
|
|
13057
|
+
* Generic helper to handle replay for query operations (sql, unsafe, file).
|
|
13058
|
+
* Consolidates common logic for finding mock data and processing results.
|
|
13059
|
+
*/
|
|
13060
|
+
async _handleReplayQueryOperation({ inputValue, spanInfo, submodule, name, stackTrace, operationType }) {
|
|
13061
|
+
logger.debug(`[PostgresInstrumentation] Replaying Postgres ${operationType} query`);
|
|
13062
|
+
const mockData = await this._findMockData({
|
|
13063
|
+
spanInfo,
|
|
13064
|
+
name,
|
|
13065
|
+
inputValue,
|
|
13066
|
+
submoduleName: submodule,
|
|
13067
|
+
stackTrace
|
|
13068
|
+
});
|
|
12835
13069
|
if (!mockData) {
|
|
12836
|
-
const
|
|
12837
|
-
logger.warn(
|
|
12838
|
-
throw new Error(
|
|
13070
|
+
const errorMsg = `[PostgresInstrumentation] No matching mock found for Postgres ${operationType} query: ${inputValue.query || "UNKNOWN_QUERY"}`;
|
|
13071
|
+
logger.warn(errorMsg);
|
|
13072
|
+
throw new Error(errorMsg);
|
|
12839
13073
|
}
|
|
12840
|
-
logger.debug(`[PostgresInstrumentation] Found mock data for Postgres
|
|
12841
|
-
const processedResult =
|
|
12842
|
-
logger.debug(`[PostgresInstrumentation]
|
|
13074
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for Postgres ${operationType} query: ${JSON.stringify(mockData)}`);
|
|
13075
|
+
const processedResult = convertPostgresTypes(mockData.result);
|
|
13076
|
+
logger.debug(`[PostgresInstrumentation] ${operationType} query processed result: ${JSON.stringify(processedResult)}`);
|
|
12843
13077
|
return processedResult;
|
|
12844
13078
|
}
|
|
12845
|
-
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
|
|
12860
|
-
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
|
|
12865
|
-
|
|
12866
|
-
|
|
12867
|
-
|
|
12868
|
-
|
|
12869
|
-
|
|
13079
|
+
_handleCursorCallbackRecord({ originalCursor, rows, inputValue, creationContext, userCallback }) {
|
|
13080
|
+
const self = this;
|
|
13081
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13082
|
+
return handleRecordMode({
|
|
13083
|
+
originalFunctionCall: () => originalCursor(rows, userCallback),
|
|
13084
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
13085
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalCursor(rows, userCallback), {
|
|
13086
|
+
name: "postgres.cursor",
|
|
13087
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13088
|
+
submodule: "cursor",
|
|
13089
|
+
packageType: PackageType.PG,
|
|
13090
|
+
packageName: "postgres",
|
|
13091
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13092
|
+
inputValue,
|
|
13093
|
+
isPreAppStart
|
|
13094
|
+
}, (spanInfo) => {
|
|
13095
|
+
return self._executeAndRecordCursorCallback({
|
|
13096
|
+
originalCursor,
|
|
13097
|
+
rows,
|
|
13098
|
+
userCallback,
|
|
13099
|
+
spanInfo
|
|
13100
|
+
});
|
|
13101
|
+
});
|
|
13102
|
+
},
|
|
13103
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
13104
|
+
});
|
|
13105
|
+
});
|
|
13106
|
+
}
|
|
13107
|
+
async _executeAndRecordCursorCallback({ originalCursor, rows, userCallback, spanInfo }) {
|
|
13108
|
+
const allRows = [];
|
|
13109
|
+
try {
|
|
13110
|
+
const wrappedCallback = (batchRows) => {
|
|
13111
|
+
allRows.push(...batchRows);
|
|
13112
|
+
return userCallback(batchRows);
|
|
13113
|
+
};
|
|
13114
|
+
const cursorPromise = originalCursor(rows, wrappedCallback);
|
|
13115
|
+
cursorPromise._tuskRecorded = true;
|
|
13116
|
+
const result = await cursorPromise;
|
|
13117
|
+
if (spanInfo) try {
|
|
13118
|
+
this._endCursorSpan(spanInfo, allRows, result, "Cursor callback");
|
|
13119
|
+
} catch (error) {
|
|
13120
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13121
|
+
}
|
|
13122
|
+
} catch (error) {
|
|
13123
|
+
logger.debug(`[PostgresInstrumentation] Cursor callback error: ${error.message}`);
|
|
13124
|
+
if (spanInfo) try {
|
|
13125
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13126
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13127
|
+
message: error.message
|
|
13128
|
+
});
|
|
13129
|
+
} catch (error$1) {
|
|
13130
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error$1);
|
|
13131
|
+
}
|
|
13132
|
+
throw error;
|
|
13133
|
+
}
|
|
13134
|
+
}
|
|
13135
|
+
_handleCursorCallbackReplay({ inputValue, creationContext, cursorBatchSize, userCallback }) {
|
|
13136
|
+
const self = this;
|
|
13137
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13138
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13139
|
+
return handleReplayMode({
|
|
13140
|
+
noOpRequestHandler: () => Promise.resolve(),
|
|
13141
|
+
isServerRequest: false,
|
|
13142
|
+
replayModeHandler: () => {
|
|
13143
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => Promise.resolve(), {
|
|
13144
|
+
name: "postgres.cursor",
|
|
13145
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13146
|
+
submodule: "cursor",
|
|
13147
|
+
packageType: PackageType.PG,
|
|
13148
|
+
packageName: "postgres",
|
|
13149
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13150
|
+
inputValue,
|
|
13151
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
13152
|
+
}, async (spanInfo) => {
|
|
13153
|
+
try {
|
|
13154
|
+
const mockData = await this._findMockData({
|
|
13155
|
+
spanInfo,
|
|
13156
|
+
name: "postgres.cursor",
|
|
13157
|
+
inputValue,
|
|
13158
|
+
submoduleName: "cursor",
|
|
13159
|
+
stackTrace
|
|
13160
|
+
});
|
|
13161
|
+
if (!mockData) throw new Error(`[PostgresInstrumentation] No matching mock found for cursor query: ${inputValue.query}`);
|
|
13162
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for cursor query: ${JSON.stringify(mockData)}`);
|
|
13163
|
+
const processedResult = convertPostgresTypes(mockData.result);
|
|
13164
|
+
const mockedData = Array.isArray(processedResult) ? processedResult : [];
|
|
13165
|
+
for (let i = 0; i < mockedData.length; i += cursorBatchSize) {
|
|
13166
|
+
const batch = mockedData.slice(i, i + cursorBatchSize);
|
|
13167
|
+
logger.debug(`[PostgresInstrumentation] Cursor replay calling callback with batch of ${batch.length} rows`);
|
|
13168
|
+
await userCallback(batch);
|
|
13169
|
+
}
|
|
13170
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13171
|
+
} catch (error) {
|
|
13172
|
+
logger.debug(`[PostgresInstrumentation] Cursor callback replay error: ${error.message}`);
|
|
13173
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13174
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13175
|
+
message: error.message
|
|
13176
|
+
});
|
|
13177
|
+
throw error;
|
|
13178
|
+
}
|
|
13179
|
+
});
|
|
13180
|
+
}
|
|
13181
|
+
});
|
|
13182
|
+
});
|
|
13183
|
+
}
|
|
13184
|
+
_handleCursorRecord({ originalCursor, rows, inputValue, creationContext, queryObject }) {
|
|
13185
|
+
const self = this;
|
|
13186
|
+
return { [Symbol.asyncIterator]() {
|
|
13187
|
+
const iterator = originalCursor(rows)[Symbol.asyncIterator]();
|
|
13188
|
+
let allRows = [];
|
|
13189
|
+
let result;
|
|
13190
|
+
let spanInfo = null;
|
|
13191
|
+
let spanStarted = false;
|
|
13192
|
+
return {
|
|
13193
|
+
async next() {
|
|
13194
|
+
return import_src$25.context.with(creationContext, async () => {
|
|
13195
|
+
if (!spanStarted) {
|
|
13196
|
+
spanStarted = true;
|
|
13197
|
+
let spanInputValue;
|
|
13198
|
+
try {
|
|
13199
|
+
spanInputValue = createSpanInputValue(inputValue);
|
|
13200
|
+
} catch (error) {
|
|
13201
|
+
logger.error(`[PostgresInstrumentation] error creating span input value:`, error);
|
|
13202
|
+
spanInputValue = void 0;
|
|
13203
|
+
}
|
|
13204
|
+
spanInfo = SpanUtils.createSpan({
|
|
13205
|
+
name: "postgres.cursor",
|
|
13206
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13207
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true,
|
|
13208
|
+
attributes: {
|
|
13209
|
+
[TdSpanAttributes.NAME]: "postgres.cursor",
|
|
13210
|
+
[TdSpanAttributes.PACKAGE_NAME]: "postgres",
|
|
13211
|
+
[TdSpanAttributes.SUBMODULE_NAME]: "cursor",
|
|
13212
|
+
[TdSpanAttributes.INSTRUMENTATION_NAME]: self.INSTRUMENTATION_NAME,
|
|
13213
|
+
[TdSpanAttributes.PACKAGE_TYPE]: PackageType.PG,
|
|
13214
|
+
[TdSpanAttributes.INPUT_VALUE]: spanInputValue,
|
|
13215
|
+
[TdSpanAttributes.IS_PRE_APP_START]: self.tuskDrift.isAppReady() ? false : true
|
|
13216
|
+
}
|
|
13217
|
+
});
|
|
13218
|
+
if (!spanInfo) logger.warn(`[PostgresInstrumentation] Failed to create cursor span in RECORD mode`);
|
|
13219
|
+
}
|
|
13220
|
+
try {
|
|
13221
|
+
result = await iterator.next();
|
|
13222
|
+
if (result.done) {
|
|
13223
|
+
if (spanInfo) try {
|
|
13224
|
+
self._endCursorSpan(spanInfo, allRows, queryObject, "Cursor");
|
|
13225
|
+
} catch (error) {
|
|
13226
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13227
|
+
}
|
|
13228
|
+
return {
|
|
13229
|
+
done: true,
|
|
13230
|
+
value: void 0
|
|
13231
|
+
};
|
|
13232
|
+
}
|
|
13233
|
+
if (Array.isArray(result.value)) allRows.push(...result.value);
|
|
13234
|
+
return {
|
|
13235
|
+
done: false,
|
|
13236
|
+
value: result.value
|
|
13237
|
+
};
|
|
13238
|
+
} catch (error) {
|
|
13239
|
+
if (spanInfo) try {
|
|
13240
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13241
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13242
|
+
message: error.message
|
|
13243
|
+
});
|
|
13244
|
+
} catch (error$1) {
|
|
13245
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error$1);
|
|
13246
|
+
}
|
|
13247
|
+
throw error;
|
|
13248
|
+
}
|
|
13249
|
+
});
|
|
13250
|
+
},
|
|
13251
|
+
async return() {
|
|
13252
|
+
if (spanInfo) try {
|
|
13253
|
+
self._endCursorSpan(spanInfo, allRows, queryObject, "Cursor terminated early");
|
|
13254
|
+
} catch (error) {
|
|
13255
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13256
|
+
}
|
|
13257
|
+
if (iterator.return) await iterator.return();
|
|
13258
|
+
return {
|
|
13259
|
+
done: true,
|
|
13260
|
+
value: void 0
|
|
13261
|
+
};
|
|
13262
|
+
}
|
|
13263
|
+
};
|
|
13264
|
+
} };
|
|
13265
|
+
}
|
|
13266
|
+
_handleCursorReplay({ inputValue, creationContext, cursorBatchSize }) {
|
|
13267
|
+
const self = this;
|
|
13268
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13269
|
+
return { [Symbol.asyncIterator]() {
|
|
13270
|
+
let mockedData = null;
|
|
13271
|
+
let currentIndex = 0;
|
|
13272
|
+
let spanInfo = null;
|
|
13273
|
+
let dataFetched = false;
|
|
13274
|
+
return {
|
|
13275
|
+
async next() {
|
|
13276
|
+
return import_src$25.context.with(creationContext, async () => {
|
|
13277
|
+
if (!dataFetched) {
|
|
13278
|
+
dataFetched = true;
|
|
13279
|
+
spanInfo = SpanUtils.createSpan({
|
|
13280
|
+
name: "postgres.cursor",
|
|
13281
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13282
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true,
|
|
13283
|
+
attributes: {
|
|
13284
|
+
[TdSpanAttributes.NAME]: "postgres.cursor",
|
|
13285
|
+
[TdSpanAttributes.PACKAGE_NAME]: "postgres",
|
|
13286
|
+
[TdSpanAttributes.SUBMODULE_NAME]: "cursor",
|
|
13287
|
+
[TdSpanAttributes.INSTRUMENTATION_NAME]: self.INSTRUMENTATION_NAME,
|
|
13288
|
+
[TdSpanAttributes.PACKAGE_TYPE]: PackageType.PG,
|
|
13289
|
+
[TdSpanAttributes.INPUT_VALUE]: createSpanInputValue(inputValue),
|
|
13290
|
+
[TdSpanAttributes.IS_PRE_APP_START]: self.tuskDrift.isAppReady() ? false : true
|
|
13291
|
+
}
|
|
13292
|
+
});
|
|
13293
|
+
if (!spanInfo) throw new Error(`[PostgresInstrumentation] Failed to create cursor span in REPLAY mode`);
|
|
13294
|
+
const mockData = await self._findMockData({
|
|
13295
|
+
spanInfo,
|
|
13296
|
+
name: "postgres.cursor",
|
|
13297
|
+
inputValue,
|
|
13298
|
+
submoduleName: "cursor",
|
|
13299
|
+
stackTrace
|
|
13300
|
+
});
|
|
13301
|
+
if (!mockData) {
|
|
13302
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13303
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13304
|
+
message: "No mock data found"
|
|
13305
|
+
});
|
|
13306
|
+
throw new Error(`[PostgresInstrumentation] No matching mock found for cursor query: ${inputValue.query}`);
|
|
13307
|
+
}
|
|
13308
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for cursor query: ${JSON.stringify(mockData)}`);
|
|
13309
|
+
const processedResult = convertPostgresTypes(mockData.result);
|
|
13310
|
+
mockedData = Array.isArray(processedResult) ? processedResult : [];
|
|
13311
|
+
}
|
|
13312
|
+
if (currentIndex >= mockedData.length) {
|
|
13313
|
+
if (spanInfo) SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13314
|
+
return {
|
|
13315
|
+
done: true,
|
|
13316
|
+
value: void 0
|
|
13317
|
+
};
|
|
13318
|
+
}
|
|
13319
|
+
const batch = mockedData.slice(currentIndex, currentIndex + cursorBatchSize);
|
|
13320
|
+
currentIndex += batch.length;
|
|
13321
|
+
logger.debug(`[PostgresInstrumentation] Cursor replay returning batch of ${batch.length} rows`);
|
|
13322
|
+
return {
|
|
13323
|
+
done: false,
|
|
13324
|
+
value: batch
|
|
13325
|
+
};
|
|
13326
|
+
});
|
|
13327
|
+
},
|
|
13328
|
+
async return() {
|
|
13329
|
+
if (spanInfo) SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13330
|
+
return {
|
|
13331
|
+
done: true,
|
|
13332
|
+
value: void 0
|
|
13333
|
+
};
|
|
13334
|
+
}
|
|
13335
|
+
};
|
|
13336
|
+
} };
|
|
13337
|
+
}
|
|
13338
|
+
_handleForEachRecord({ originalForEach, inputValue, creationContext, userCallback }) {
|
|
13339
|
+
const self = this;
|
|
13340
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13341
|
+
return handleRecordMode({
|
|
13342
|
+
originalFunctionCall: () => originalForEach(userCallback),
|
|
13343
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
13344
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalForEach(userCallback), {
|
|
13345
|
+
name: "postgres.query",
|
|
13346
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13347
|
+
submodule: "query",
|
|
13348
|
+
packageType: PackageType.PG,
|
|
13349
|
+
packageName: "postgres",
|
|
13350
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13351
|
+
inputValue,
|
|
13352
|
+
isPreAppStart
|
|
13353
|
+
}, async (spanInfo) => {
|
|
13354
|
+
const allRows = [];
|
|
13355
|
+
const wrappedCallback = (row, result) => {
|
|
13356
|
+
allRows.push(row);
|
|
13357
|
+
return userCallback(row, result);
|
|
13358
|
+
};
|
|
13359
|
+
try {
|
|
13360
|
+
const result = await originalForEach(wrappedCallback);
|
|
13361
|
+
try {
|
|
13362
|
+
self._endCursorSpan(spanInfo, allRows, result, "forEach");
|
|
13363
|
+
} catch (error) {
|
|
13364
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13365
|
+
}
|
|
13366
|
+
return result;
|
|
13367
|
+
} catch (error) {
|
|
13368
|
+
try {
|
|
13369
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13370
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13371
|
+
message: error.message
|
|
13372
|
+
});
|
|
13373
|
+
} catch (error$1) {
|
|
13374
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error$1);
|
|
13375
|
+
}
|
|
13376
|
+
throw error;
|
|
13377
|
+
}
|
|
13378
|
+
});
|
|
13379
|
+
},
|
|
13380
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
13381
|
+
});
|
|
13382
|
+
});
|
|
13383
|
+
}
|
|
13384
|
+
_handleForEachReplay({ inputValue, creationContext, userCallback }) {
|
|
13385
|
+
const self = this;
|
|
13386
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13387
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13388
|
+
return handleReplayMode({
|
|
13389
|
+
noOpRequestHandler: () => Promise.resolve(Object.assign([], {
|
|
13390
|
+
count: 0,
|
|
13391
|
+
command: null
|
|
13392
|
+
})),
|
|
13393
|
+
isServerRequest: false,
|
|
13394
|
+
replayModeHandler: () => {
|
|
13395
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => Promise.resolve(Object.assign([], {
|
|
13396
|
+
count: 0,
|
|
13397
|
+
command: null
|
|
13398
|
+
})), {
|
|
13399
|
+
name: "postgres.query",
|
|
13400
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13401
|
+
submodule: "query",
|
|
13402
|
+
packageType: PackageType.PG,
|
|
13403
|
+
packageName: "postgres",
|
|
13404
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13405
|
+
inputValue,
|
|
13406
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
13407
|
+
}, async (spanInfo) => {
|
|
13408
|
+
try {
|
|
13409
|
+
const mockedResult = await self._handleReplayQueryOperation({
|
|
13410
|
+
inputValue,
|
|
13411
|
+
spanInfo,
|
|
13412
|
+
submodule: "query",
|
|
13413
|
+
name: "postgres.query",
|
|
13414
|
+
stackTrace,
|
|
13415
|
+
operationType: "forEach"
|
|
13416
|
+
});
|
|
13417
|
+
const mockedRows = Array.isArray(mockedResult) ? mockedResult : [];
|
|
13418
|
+
logger.debug(`[PostgresInstrumentation] forEach replay: calling callback with ${mockedRows.length} mocked rows`);
|
|
13419
|
+
for (const row of mockedRows) userCallback(row, mockedResult);
|
|
13420
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13421
|
+
return Object.assign([], {
|
|
13422
|
+
count: mockedRows.length,
|
|
13423
|
+
command: null
|
|
13424
|
+
});
|
|
13425
|
+
} catch (error) {
|
|
13426
|
+
logger.debug(`[PostgresInstrumentation] forEach replay error: ${error.message}`);
|
|
13427
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13428
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13429
|
+
message: error.message
|
|
13430
|
+
});
|
|
13431
|
+
throw error;
|
|
13432
|
+
}
|
|
13433
|
+
});
|
|
13434
|
+
}
|
|
13435
|
+
});
|
|
13436
|
+
});
|
|
13437
|
+
}
|
|
13438
|
+
/**
|
|
13439
|
+
* Wraps a query's .then() method to add instrumentation.
|
|
13440
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13441
|
+
*/
|
|
13442
|
+
_wrapThenMethod(query, originalThen, inputValue, creationContext, spanConfig) {
|
|
13443
|
+
const self = this;
|
|
13444
|
+
query.then = function(onFulfilled, onRejected) {
|
|
13445
|
+
if (query._forEachCalled) return originalThen(onFulfilled, onRejected);
|
|
13446
|
+
if (query._tuskRecorded) return originalThen(onFulfilled, onRejected);
|
|
13447
|
+
query._tuskRecorded = true;
|
|
13448
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13449
|
+
if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
13450
|
+
originalFunctionCall: () => originalThen(onFulfilled, onRejected),
|
|
13451
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
13452
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
13453
|
+
name: spanConfig.name,
|
|
13454
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13455
|
+
submodule: spanConfig.submodule,
|
|
13456
|
+
packageType: PackageType.PG,
|
|
13457
|
+
packageName: "postgres",
|
|
13458
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13459
|
+
inputValue,
|
|
13460
|
+
isPreAppStart
|
|
13461
|
+
}, (spanInfo) => {
|
|
13462
|
+
const wrappedOnFulfilled = (result) => {
|
|
13463
|
+
try {
|
|
13464
|
+
logger.debug(`[PostgresInstrumentation] Postgres ${spanConfig.operationType} query completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
13465
|
+
addOutputAttributesToSpan(spanInfo, result);
|
|
13466
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13467
|
+
} catch (error) {
|
|
13468
|
+
logger.error(`[PostgresInstrumentation] error processing ${spanConfig.operationType} query response:`, error);
|
|
13469
|
+
}
|
|
13470
|
+
return onFulfilled ? onFulfilled(result) : result;
|
|
13471
|
+
};
|
|
13472
|
+
const wrappedOnRejected = (error) => {
|
|
13473
|
+
try {
|
|
13474
|
+
logger.debug(`[PostgresInstrumentation] Postgres ${spanConfig.operationType} query error: ${error.message}`);
|
|
13475
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13476
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13477
|
+
message: error.message
|
|
13478
|
+
});
|
|
13479
|
+
} catch (spanError) {
|
|
13480
|
+
logger.error(`[PostgresInstrumentation] error ending span:`, spanError);
|
|
13481
|
+
}
|
|
13482
|
+
if (onRejected) return onRejected(error);
|
|
13483
|
+
throw error;
|
|
13484
|
+
};
|
|
13485
|
+
return originalThen(wrappedOnFulfilled, wrappedOnRejected);
|
|
13486
|
+
});
|
|
13487
|
+
},
|
|
13488
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
13489
|
+
});
|
|
13490
|
+
else if (self.mode === TuskDriftMode.REPLAY) {
|
|
13491
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13492
|
+
return handleReplayMode({
|
|
13493
|
+
noOpRequestHandler: () => Promise.resolve(Object.assign([], {
|
|
13494
|
+
count: 0,
|
|
13495
|
+
command: null
|
|
13496
|
+
})),
|
|
13497
|
+
isServerRequest: false,
|
|
13498
|
+
replayModeHandler: () => {
|
|
13499
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
13500
|
+
name: spanConfig.name,
|
|
13501
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13502
|
+
submodule: spanConfig.submodule,
|
|
13503
|
+
packageType: PackageType.PG,
|
|
13504
|
+
packageName: "postgres",
|
|
13505
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13506
|
+
inputValue,
|
|
13507
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
13508
|
+
}, async (spanInfo) => {
|
|
13509
|
+
const mockedResult = await self._handleReplayQueryOperation({
|
|
13510
|
+
inputValue,
|
|
13511
|
+
spanInfo,
|
|
13512
|
+
submodule: spanConfig.submodule,
|
|
13513
|
+
name: spanConfig.name,
|
|
13514
|
+
stackTrace,
|
|
13515
|
+
operationType: spanConfig.operationType
|
|
13516
|
+
});
|
|
13517
|
+
return onFulfilled ? onFulfilled(mockedResult) : mockedResult;
|
|
13518
|
+
});
|
|
13519
|
+
}
|
|
13520
|
+
});
|
|
13521
|
+
} else return originalThen(onFulfilled, onRejected);
|
|
13522
|
+
});
|
|
13523
|
+
};
|
|
13524
|
+
}
|
|
13525
|
+
/**
|
|
13526
|
+
* Wraps a query's .execute() method to prevent TCP calls in REPLAY mode.
|
|
13527
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13528
|
+
*/
|
|
13529
|
+
_wrapExecuteMethod(query) {
|
|
13530
|
+
const self = this;
|
|
13531
|
+
const originalExecute = query.execute ? query.execute.bind(query) : void 0;
|
|
13532
|
+
if (originalExecute) query.execute = function() {
|
|
13533
|
+
if (self.mode === TuskDriftMode.REPLAY) return this;
|
|
13534
|
+
else return originalExecute.call(this);
|
|
13535
|
+
};
|
|
12870
13536
|
}
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
|
|
12876
|
-
|
|
12877
|
-
const
|
|
12878
|
-
|
|
12879
|
-
|
|
12880
|
-
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
}
|
|
12884
|
-
|
|
12885
|
-
|
|
12886
|
-
|
|
12887
|
-
|
|
12888
|
-
|
|
12889
|
-
|
|
12890
|
-
|
|
13537
|
+
/**
|
|
13538
|
+
* Wraps a query's cursor() method to add instrumentation.
|
|
13539
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13540
|
+
*/
|
|
13541
|
+
_wrapCursorMethod(query, inputValue, creationContext) {
|
|
13542
|
+
if (typeof query.cursor !== "function") return;
|
|
13543
|
+
const self = this;
|
|
13544
|
+
const originalCursor = query.cursor.bind(query);
|
|
13545
|
+
query.cursor = function(rows, fn) {
|
|
13546
|
+
if (typeof rows === "function") {
|
|
13547
|
+
fn = rows;
|
|
13548
|
+
rows = 1;
|
|
13549
|
+
}
|
|
13550
|
+
if (!rows) rows = 1;
|
|
13551
|
+
if (typeof fn === "function") if (self.mode === TuskDriftMode.RECORD) return self._handleCursorCallbackRecord({
|
|
13552
|
+
originalCursor,
|
|
13553
|
+
rows,
|
|
13554
|
+
inputValue,
|
|
13555
|
+
creationContext,
|
|
13556
|
+
userCallback: fn
|
|
13557
|
+
});
|
|
13558
|
+
else if (self.mode === TuskDriftMode.REPLAY) return self._handleCursorCallbackReplay({
|
|
13559
|
+
inputValue,
|
|
13560
|
+
creationContext,
|
|
13561
|
+
cursorBatchSize: rows,
|
|
13562
|
+
userCallback: fn
|
|
13563
|
+
});
|
|
13564
|
+
else return originalCursor(rows, fn);
|
|
13565
|
+
if (self.mode === TuskDriftMode.RECORD) return self._handleCursorRecord({
|
|
13566
|
+
originalCursor,
|
|
13567
|
+
rows,
|
|
13568
|
+
inputValue,
|
|
13569
|
+
creationContext,
|
|
13570
|
+
queryObject: this
|
|
13571
|
+
});
|
|
13572
|
+
else if (self.mode === TuskDriftMode.REPLAY) return self._handleCursorReplay({
|
|
13573
|
+
inputValue,
|
|
13574
|
+
creationContext,
|
|
13575
|
+
cursorBatchSize: rows
|
|
13576
|
+
});
|
|
13577
|
+
else return originalCursor(rows);
|
|
13578
|
+
};
|
|
12891
13579
|
}
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
|
|
12896
|
-
|
|
12897
|
-
|
|
12898
|
-
|
|
12899
|
-
|
|
13580
|
+
/**
|
|
13581
|
+
* Wraps a query's forEach() method to add instrumentation.
|
|
13582
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13583
|
+
*/
|
|
13584
|
+
_wrapForEachMethod(query, inputValue, creationContext) {
|
|
13585
|
+
if (typeof query.forEach !== "function") return;
|
|
13586
|
+
const self = this;
|
|
13587
|
+
const originalForEach = query.forEach.bind(query);
|
|
13588
|
+
query.forEach = function(fn) {
|
|
13589
|
+
query._forEachCalled = true;
|
|
13590
|
+
if (self.mode === TuskDriftMode.RECORD) return self._handleForEachRecord({
|
|
13591
|
+
originalForEach,
|
|
13592
|
+
inputValue,
|
|
13593
|
+
creationContext,
|
|
13594
|
+
userCallback: fn
|
|
13595
|
+
});
|
|
13596
|
+
else if (self.mode === TuskDriftMode.REPLAY) return self._handleForEachReplay({
|
|
13597
|
+
inputValue,
|
|
13598
|
+
creationContext,
|
|
13599
|
+
userCallback: fn
|
|
13600
|
+
});
|
|
13601
|
+
else return originalForEach(fn);
|
|
12900
13602
|
};
|
|
12901
|
-
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
12902
13603
|
}
|
|
12903
13604
|
_wrap(target, propertyName, wrapper) {
|
|
12904
13605
|
wrap(target, propertyName, wrapper);
|
|
@@ -12921,8 +13622,9 @@ function isMysqlOkPacket(result) {
|
|
|
12921
13622
|
* Extends EventEmitter to properly handle all connection methods and events
|
|
12922
13623
|
*/
|
|
12923
13624
|
var TdMysqlConnectionMock = class extends events.EventEmitter {
|
|
12924
|
-
constructor(mysqlInstrumentation, clientType = "poolConnection", spanInfo) {
|
|
13625
|
+
constructor(mysqlInstrumentation, clientType = "poolConnection", spanInfo, pool) {
|
|
12925
13626
|
super();
|
|
13627
|
+
this._pool = null;
|
|
12926
13628
|
this.threadId = null;
|
|
12927
13629
|
this.config = {
|
|
12928
13630
|
host: "localhost",
|
|
@@ -12934,6 +13636,7 @@ var TdMysqlConnectionMock = class extends events.EventEmitter {
|
|
|
12934
13636
|
this.spanInfo = spanInfo;
|
|
12935
13637
|
this.clientType = clientType;
|
|
12936
13638
|
this.threadId = 1;
|
|
13639
|
+
this._pool = pool;
|
|
12937
13640
|
}
|
|
12938
13641
|
query(...args) {
|
|
12939
13642
|
logger.debug(`[TdMysqlConnectionMock] Mock connection query intercepted in REPLAY mode`);
|
|
@@ -12941,7 +13644,13 @@ var TdMysqlConnectionMock = class extends events.EventEmitter {
|
|
|
12941
13644
|
let values;
|
|
12942
13645
|
let callback;
|
|
12943
13646
|
let options = {};
|
|
12944
|
-
|
|
13647
|
+
const firstArg = args[0];
|
|
13648
|
+
if (firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function") {
|
|
13649
|
+
sql = firstArg.sql;
|
|
13650
|
+
values = firstArg.values;
|
|
13651
|
+
callback = firstArg._callback;
|
|
13652
|
+
options = { nestTables: firstArg.nestTables };
|
|
13653
|
+
} else if (typeof args[0] === "string") {
|
|
12945
13654
|
sql = args[0];
|
|
12946
13655
|
if (typeof args[1] === "function") callback = args[1];
|
|
12947
13656
|
else if (Array.isArray(args[1])) {
|
|
@@ -12993,6 +13702,7 @@ var TdMysqlConnectionMock = class extends events.EventEmitter {
|
|
|
12993
13702
|
}
|
|
12994
13703
|
}
|
|
12995
13704
|
release() {
|
|
13705
|
+
if (this._pool) this._pool.emit("release", this);
|
|
12996
13706
|
this.emit("end");
|
|
12997
13707
|
}
|
|
12998
13708
|
destroy() {
|
|
@@ -13017,19 +13727,22 @@ var TdMysqlConnectionMock = class extends events.EventEmitter {
|
|
|
13017
13727
|
return;
|
|
13018
13728
|
}
|
|
13019
13729
|
}
|
|
13020
|
-
beginTransaction(
|
|
13730
|
+
beginTransaction(optionsOrCallback, callbackArg) {
|
|
13731
|
+
const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : callbackArg;
|
|
13021
13732
|
if (callback) {
|
|
13022
13733
|
process.nextTick(() => callback(null));
|
|
13023
13734
|
return;
|
|
13024
13735
|
}
|
|
13025
13736
|
}
|
|
13026
|
-
commit(
|
|
13737
|
+
commit(optionsOrCallback, callbackArg) {
|
|
13738
|
+
const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : callbackArg;
|
|
13027
13739
|
if (callback) {
|
|
13028
13740
|
process.nextTick(() => callback(null));
|
|
13029
13741
|
return;
|
|
13030
13742
|
}
|
|
13031
13743
|
}
|
|
13032
|
-
rollback(
|
|
13744
|
+
rollback(optionsOrCallback, callbackArg) {
|
|
13745
|
+
const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : callbackArg;
|
|
13033
13746
|
if (callback) {
|
|
13034
13747
|
process.nextTick(() => callback(null));
|
|
13035
13748
|
return;
|
|
@@ -13225,6 +13938,11 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13225
13938
|
name: "mysql/lib/Pool.js",
|
|
13226
13939
|
supportedVersions: ["2.*"],
|
|
13227
13940
|
patch: (moduleExports) => this._patchPoolFile(moduleExports)
|
|
13941
|
+
}),
|
|
13942
|
+
new TdInstrumentationNodeModuleFile({
|
|
13943
|
+
name: "mysql/lib/PoolNamespace.js",
|
|
13944
|
+
supportedVersions: ["2.*"],
|
|
13945
|
+
patch: (moduleExports) => this._patchPoolNamespaceFile(moduleExports)
|
|
13228
13946
|
})
|
|
13229
13947
|
]
|
|
13230
13948
|
})];
|
|
@@ -13364,12 +14082,40 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13364
14082
|
return PoolClass;
|
|
13365
14083
|
}
|
|
13366
14084
|
/**
|
|
14085
|
+
* Patch PoolNamespace.prototype methods at the file level
|
|
14086
|
+
* This handles queries made via poolCluster.of("pattern").query()
|
|
14087
|
+
*/
|
|
14088
|
+
_patchPoolNamespaceFile(PoolNamespaceClass) {
|
|
14089
|
+
logger.debug(`[MysqlInstrumentation] Patching PoolNamespace class (file-based)`);
|
|
14090
|
+
if (this.isModulePatched(PoolNamespaceClass)) {
|
|
14091
|
+
logger.debug(`[MysqlInstrumentation] PoolNamespace class already patched, skipping`);
|
|
14092
|
+
return PoolNamespaceClass;
|
|
14093
|
+
}
|
|
14094
|
+
if (PoolNamespaceClass.prototype && PoolNamespaceClass.prototype.query) {
|
|
14095
|
+
if (!isWrapped$1(PoolNamespaceClass.prototype.query)) {
|
|
14096
|
+
this._wrap(PoolNamespaceClass.prototype, "query", this._getPoolNamespaceQueryPatchFn());
|
|
14097
|
+
logger.debug(`[MysqlInstrumentation] Wrapped PoolNamespace.prototype.query`);
|
|
14098
|
+
}
|
|
14099
|
+
}
|
|
14100
|
+
if (PoolNamespaceClass.prototype && PoolNamespaceClass.prototype.getConnection) {
|
|
14101
|
+
if (!isWrapped$1(PoolNamespaceClass.prototype.getConnection)) {
|
|
14102
|
+
this._wrap(PoolNamespaceClass.prototype, "getConnection", this._getPoolNamespaceGetConnectionPatchFn());
|
|
14103
|
+
logger.debug(`[MysqlInstrumentation] Wrapped PoolNamespace.prototype.getConnection`);
|
|
14104
|
+
}
|
|
14105
|
+
}
|
|
14106
|
+
this.markModuleAsPatched(PoolNamespaceClass);
|
|
14107
|
+
logger.debug(`[MysqlInstrumentation] PoolNamespace class patching complete`);
|
|
14108
|
+
return PoolNamespaceClass;
|
|
14109
|
+
}
|
|
14110
|
+
/**
|
|
13367
14111
|
* Get wrapper function for query method (prototype-level patching)
|
|
13368
14112
|
*/
|
|
13369
14113
|
_getQueryPatchFn() {
|
|
13370
14114
|
const self = this;
|
|
13371
14115
|
return (originalQuery) => {
|
|
13372
14116
|
return function query(...args) {
|
|
14117
|
+
const firstArg = args[0];
|
|
14118
|
+
const hasInternalCallback = firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function";
|
|
13373
14119
|
let sql;
|
|
13374
14120
|
let values;
|
|
13375
14121
|
let callback;
|
|
@@ -13380,6 +14126,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13380
14126
|
values = queryObj.values;
|
|
13381
14127
|
options = { nestTables: queryObj.nestTables };
|
|
13382
14128
|
callback = args.find((arg) => typeof arg === "function");
|
|
14129
|
+
if (!callback && hasInternalCallback) callback = firstArg._callback;
|
|
13383
14130
|
} catch (error) {
|
|
13384
14131
|
logger.debug(`[MysqlInstrumentation] Error using createQuery, falling back to manual parsing:`, error);
|
|
13385
14132
|
({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
@@ -13390,7 +14137,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13390
14137
|
values,
|
|
13391
14138
|
options: options.nestTables ? { nestTables: options.nestTables } : void 0
|
|
13392
14139
|
};
|
|
13393
|
-
const isEventEmitterMode = !callback;
|
|
14140
|
+
const isEventEmitterMode = !callback && !hasInternalCallback;
|
|
13394
14141
|
if (self.mode === TuskDriftMode.REPLAY) {
|
|
13395
14142
|
const stackTrace = captureStackTrace(["MysqlInstrumentation"]);
|
|
13396
14143
|
return handleReplayMode({
|
|
@@ -13486,11 +14233,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13486
14233
|
_getBeginTransactionPatchFn() {
|
|
13487
14234
|
const self = this;
|
|
13488
14235
|
return (originalBeginTransaction) => {
|
|
13489
|
-
return function beginTransaction(
|
|
14236
|
+
return function beginTransaction(optionsOrCallback, callbackArg) {
|
|
14237
|
+
let actualCallback;
|
|
14238
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14239
|
+
else actualCallback = callbackArg;
|
|
13490
14240
|
const inputValue = { query: "BEGIN" };
|
|
13491
14241
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13492
14242
|
noOpRequestHandler: () => {
|
|
13493
|
-
if (
|
|
14243
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13494
14244
|
},
|
|
13495
14245
|
isServerRequest: false,
|
|
13496
14246
|
replayModeHandler: () => {
|
|
@@ -13504,7 +14254,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13504
14254
|
inputValue,
|
|
13505
14255
|
isPreAppStart: false
|
|
13506
14256
|
}, (spanInfo) => {
|
|
13507
|
-
return self._handleReplayTransaction(inputValue,
|
|
14257
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13508
14258
|
});
|
|
13509
14259
|
}
|
|
13510
14260
|
});
|
|
@@ -13521,7 +14271,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13521
14271
|
inputValue,
|
|
13522
14272
|
isPreAppStart
|
|
13523
14273
|
}, (spanInfo) => {
|
|
13524
|
-
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, this, arguments,
|
|
14274
|
+
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, this, arguments, actualCallback);
|
|
13525
14275
|
});
|
|
13526
14276
|
},
|
|
13527
14277
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13536,11 +14286,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13536
14286
|
_getCommitPatchFn() {
|
|
13537
14287
|
const self = this;
|
|
13538
14288
|
return (originalCommit) => {
|
|
13539
|
-
return function commit(
|
|
14289
|
+
return function commit(optionsOrCallback, callbackArg) {
|
|
14290
|
+
let actualCallback;
|
|
14291
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14292
|
+
else actualCallback = callbackArg;
|
|
13540
14293
|
const inputValue = { query: "COMMIT" };
|
|
13541
14294
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13542
14295
|
noOpRequestHandler: () => {
|
|
13543
|
-
if (
|
|
14296
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13544
14297
|
},
|
|
13545
14298
|
isServerRequest: false,
|
|
13546
14299
|
replayModeHandler: () => {
|
|
@@ -13554,7 +14307,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13554
14307
|
inputValue,
|
|
13555
14308
|
isPreAppStart: false
|
|
13556
14309
|
}, (spanInfo) => {
|
|
13557
|
-
return self._handleReplayTransaction(inputValue,
|
|
14310
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13558
14311
|
});
|
|
13559
14312
|
}
|
|
13560
14313
|
});
|
|
@@ -13571,7 +14324,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13571
14324
|
inputValue,
|
|
13572
14325
|
isPreAppStart
|
|
13573
14326
|
}, (spanInfo) => {
|
|
13574
|
-
return self._handleRecordTransaction(spanInfo, originalCommit, this, arguments,
|
|
14327
|
+
return self._handleRecordTransaction(spanInfo, originalCommit, this, arguments, actualCallback);
|
|
13575
14328
|
});
|
|
13576
14329
|
},
|
|
13577
14330
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13586,11 +14339,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13586
14339
|
_getRollbackPatchFn() {
|
|
13587
14340
|
const self = this;
|
|
13588
14341
|
return (originalRollback) => {
|
|
13589
|
-
return function rollback(
|
|
14342
|
+
return function rollback(optionsOrCallback, callbackArg) {
|
|
14343
|
+
let actualCallback;
|
|
14344
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14345
|
+
else actualCallback = callbackArg;
|
|
13590
14346
|
const inputValue = { query: "ROLLBACK" };
|
|
13591
14347
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13592
14348
|
noOpRequestHandler: () => {
|
|
13593
|
-
if (
|
|
14349
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13594
14350
|
},
|
|
13595
14351
|
isServerRequest: false,
|
|
13596
14352
|
replayModeHandler: () => {
|
|
@@ -13604,7 +14360,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13604
14360
|
inputValue,
|
|
13605
14361
|
isPreAppStart: false
|
|
13606
14362
|
}, (spanInfo) => {
|
|
13607
|
-
return self._handleReplayTransaction(inputValue,
|
|
14363
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13608
14364
|
});
|
|
13609
14365
|
}
|
|
13610
14366
|
});
|
|
@@ -13621,7 +14377,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13621
14377
|
inputValue,
|
|
13622
14378
|
isPreAppStart
|
|
13623
14379
|
}, (spanInfo) => {
|
|
13624
|
-
return self._handleRecordTransaction(spanInfo, originalRollback, this, arguments,
|
|
14380
|
+
return self._handleRecordTransaction(spanInfo, originalRollback, this, arguments, actualCallback);
|
|
13625
14381
|
});
|
|
13626
14382
|
},
|
|
13627
14383
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13789,9 +14545,10 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13789
14545
|
return (originalGetConnection) => {
|
|
13790
14546
|
return function getConnection(callback) {
|
|
13791
14547
|
const inputValue = { clientType: "pool" };
|
|
14548
|
+
const pool = this;
|
|
13792
14549
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13793
14550
|
noOpRequestHandler: () => {
|
|
13794
|
-
return self._handleNoOpReplayGetConnection(callback);
|
|
14551
|
+
return self._handleNoOpReplayGetConnection(pool, callback);
|
|
13795
14552
|
},
|
|
13796
14553
|
isServerRequest: false,
|
|
13797
14554
|
replayModeHandler: () => {
|
|
@@ -13805,7 +14562,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13805
14562
|
inputValue,
|
|
13806
14563
|
isPreAppStart: false
|
|
13807
14564
|
}, (spanInfo) => {
|
|
13808
|
-
return self._handleReplayPoolGetConnection(spanInfo, callback);
|
|
14565
|
+
return self._handleReplayPoolGetConnection(pool, spanInfo, callback);
|
|
13809
14566
|
});
|
|
13810
14567
|
}
|
|
13811
14568
|
});
|
|
@@ -13835,6 +14592,8 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13835
14592
|
const self = this;
|
|
13836
14593
|
return (originalQuery) => {
|
|
13837
14594
|
return function query(...args) {
|
|
14595
|
+
const firstArg = args[0];
|
|
14596
|
+
const hasInternalCallback = firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function";
|
|
13838
14597
|
let sql;
|
|
13839
14598
|
let values;
|
|
13840
14599
|
let callback;
|
|
@@ -13845,6 +14604,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13845
14604
|
values = queryObj.values;
|
|
13846
14605
|
options = { nestTables: queryObj.nestTables };
|
|
13847
14606
|
callback = args.find((arg) => typeof arg === "function");
|
|
14607
|
+
if (!callback && hasInternalCallback) callback = firstArg._callback;
|
|
13848
14608
|
} catch (error) {
|
|
13849
14609
|
logger.debug(`[MysqlInstrumentation] Error using createQuery, falling back to manual parsing:`, error);
|
|
13850
14610
|
({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
@@ -13855,7 +14615,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13855
14615
|
values,
|
|
13856
14616
|
options: options.nestTables ? { nestTables: options.nestTables } : void 0
|
|
13857
14617
|
};
|
|
13858
|
-
const isEventEmitterMode = !callback;
|
|
14618
|
+
const isEventEmitterMode = !callback && !hasInternalCallback;
|
|
13859
14619
|
if (self.mode === TuskDriftMode.REPLAY) {
|
|
13860
14620
|
const stackTrace = captureStackTrace(["MysqlInstrumentation"]);
|
|
13861
14621
|
return handleReplayMode({
|
|
@@ -13957,6 +14717,33 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13957
14717
|
});
|
|
13958
14718
|
return queryEmitter;
|
|
13959
14719
|
} else {
|
|
14720
|
+
const queryObject = args[0];
|
|
14721
|
+
if (queryObject && typeof queryObject === "object" && typeof queryObject._callback === "function") {
|
|
14722
|
+
const originalCallback$1 = queryObject._callback;
|
|
14723
|
+
queryObject._callback = function(err, results, fields) {
|
|
14724
|
+
if (err) try {
|
|
14725
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
14726
|
+
code: import_src$23.SpanStatusCode.ERROR,
|
|
14727
|
+
message: err.message
|
|
14728
|
+
});
|
|
14729
|
+
} catch (error) {
|
|
14730
|
+
logger.error(`[MysqlInstrumentation] error ending span:`, error);
|
|
14731
|
+
}
|
|
14732
|
+
else try {
|
|
14733
|
+
const outputValue = {
|
|
14734
|
+
results,
|
|
14735
|
+
fields
|
|
14736
|
+
};
|
|
14737
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
14738
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$23.SpanStatusCode.OK });
|
|
14739
|
+
} catch (error) {
|
|
14740
|
+
logger.error(`[MysqlInstrumentation] error ending span:`, error);
|
|
14741
|
+
}
|
|
14742
|
+
logger.debug(`[MysqlInstrumentation] Query completed`);
|
|
14743
|
+
originalCallback$1.call(this, err, results, fields);
|
|
14744
|
+
};
|
|
14745
|
+
return originalQuery.apply(connection, args);
|
|
14746
|
+
}
|
|
13960
14747
|
const originalCallback = callback;
|
|
13961
14748
|
const callbackIndex = args.findIndex((arg) => typeof arg === "function");
|
|
13962
14749
|
args[callbackIndex] = function(err, results, fields) {
|
|
@@ -14011,11 +14798,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14011
14798
|
_patchBeginTransaction(connection) {
|
|
14012
14799
|
const self = this;
|
|
14013
14800
|
return (originalBeginTransaction) => {
|
|
14014
|
-
return function beginTransaction(
|
|
14801
|
+
return function beginTransaction(optionsOrCallback, callbackArg) {
|
|
14802
|
+
let actualCallback;
|
|
14803
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14804
|
+
else actualCallback = callbackArg;
|
|
14015
14805
|
const inputValue = { query: "BEGIN" };
|
|
14016
14806
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
14017
14807
|
noOpRequestHandler: () => {
|
|
14018
|
-
if (
|
|
14808
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
14019
14809
|
},
|
|
14020
14810
|
isServerRequest: false,
|
|
14021
14811
|
replayModeHandler: () => {
|
|
@@ -14029,7 +14819,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14029
14819
|
inputValue,
|
|
14030
14820
|
isPreAppStart: false
|
|
14031
14821
|
}, (spanInfo) => {
|
|
14032
|
-
return self._handleReplayTransaction(inputValue,
|
|
14822
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
14033
14823
|
});
|
|
14034
14824
|
}
|
|
14035
14825
|
});
|
|
@@ -14046,7 +14836,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14046
14836
|
inputValue,
|
|
14047
14837
|
isPreAppStart
|
|
14048
14838
|
}, (spanInfo) => {
|
|
14049
|
-
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, connection, arguments,
|
|
14839
|
+
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, connection, arguments, actualCallback);
|
|
14050
14840
|
});
|
|
14051
14841
|
},
|
|
14052
14842
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -14058,11 +14848,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14058
14848
|
_patchCommit(connection) {
|
|
14059
14849
|
const self = this;
|
|
14060
14850
|
return (originalCommit) => {
|
|
14061
|
-
return function commit(
|
|
14851
|
+
return function commit(optionsOrCallback, callbackArg) {
|
|
14852
|
+
let actualCallback;
|
|
14853
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14854
|
+
else actualCallback = callbackArg;
|
|
14062
14855
|
const inputValue = { query: "COMMIT" };
|
|
14063
14856
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
14064
14857
|
noOpRequestHandler: () => {
|
|
14065
|
-
if (
|
|
14858
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
14066
14859
|
},
|
|
14067
14860
|
isServerRequest: false,
|
|
14068
14861
|
replayModeHandler: () => {
|
|
@@ -14076,7 +14869,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14076
14869
|
inputValue,
|
|
14077
14870
|
isPreAppStart: false
|
|
14078
14871
|
}, (spanInfo) => {
|
|
14079
|
-
return self._handleReplayTransaction(inputValue,
|
|
14872
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
14080
14873
|
});
|
|
14081
14874
|
}
|
|
14082
14875
|
});
|
|
@@ -14093,7 +14886,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14093
14886
|
inputValue,
|
|
14094
14887
|
isPreAppStart
|
|
14095
14888
|
}, (spanInfo) => {
|
|
14096
|
-
return self._handleRecordTransaction(spanInfo, originalCommit, connection, arguments,
|
|
14889
|
+
return self._handleRecordTransaction(spanInfo, originalCommit, connection, arguments, actualCallback);
|
|
14097
14890
|
});
|
|
14098
14891
|
},
|
|
14099
14892
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -14105,11 +14898,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14105
14898
|
_patchRollback(connection) {
|
|
14106
14899
|
const self = this;
|
|
14107
14900
|
return (originalRollback) => {
|
|
14108
|
-
return function rollback(
|
|
14901
|
+
return function rollback(optionsOrCallback, callbackArg) {
|
|
14902
|
+
let actualCallback;
|
|
14903
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14904
|
+
else actualCallback = callbackArg;
|
|
14109
14905
|
const inputValue = { query: "ROLLBACK" };
|
|
14110
14906
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
14111
14907
|
noOpRequestHandler: () => {
|
|
14112
|
-
if (
|
|
14908
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
14113
14909
|
},
|
|
14114
14910
|
isServerRequest: false,
|
|
14115
14911
|
replayModeHandler: () => {
|
|
@@ -14123,7 +14919,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14123
14919
|
inputValue,
|
|
14124
14920
|
isPreAppStart: false
|
|
14125
14921
|
}, (spanInfo) => {
|
|
14126
|
-
return self._handleReplayTransaction(inputValue,
|
|
14922
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
14127
14923
|
});
|
|
14128
14924
|
}
|
|
14129
14925
|
});
|
|
@@ -14140,7 +14936,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14140
14936
|
inputValue,
|
|
14141
14937
|
isPreAppStart
|
|
14142
14938
|
}, (spanInfo) => {
|
|
14143
|
-
return self._handleRecordTransaction(spanInfo, originalRollback, connection, arguments,
|
|
14939
|
+
return self._handleRecordTransaction(spanInfo, originalRollback, connection, arguments, actualCallback);
|
|
14144
14940
|
});
|
|
14145
14941
|
},
|
|
14146
14942
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -14173,7 +14969,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14173
14969
|
const argsArray = Array.from(args);
|
|
14174
14970
|
const callbackIndex = argsArray.findIndex((arg) => typeof arg === "function");
|
|
14175
14971
|
if (callbackIndex !== -1) {
|
|
14176
|
-
const originalCallback =
|
|
14972
|
+
const originalCallback = argsArray[callbackIndex];
|
|
14177
14973
|
argsArray[callbackIndex] = function(err) {
|
|
14178
14974
|
if (err) try {
|
|
14179
14975
|
SpanUtils.endSpan(spanInfo.span, {
|
|
@@ -14202,7 +14998,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14202
14998
|
callback(null);
|
|
14203
14999
|
});
|
|
14204
15000
|
}
|
|
14205
|
-
_handleRecordPoolGetConnectionInSpan(spanInfo, originalGetConnection, callback,
|
|
15001
|
+
_handleRecordPoolGetConnectionInSpan(spanInfo, originalGetConnection, callback, poolContext) {
|
|
14206
15002
|
const self = this;
|
|
14207
15003
|
if (callback) {
|
|
14208
15004
|
const wrappedCallback = (error, connection) => {
|
|
@@ -14227,11 +15023,11 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14227
15023
|
} });
|
|
14228
15024
|
SpanUtils.endSpan(spanInfo.span, { code: import_src$23.SpanStatusCode.OK });
|
|
14229
15025
|
}
|
|
14230
|
-
return callback(error, connection);
|
|
15026
|
+
return import_src$23.context.bind(spanInfo.context, callback)(error, connection);
|
|
14231
15027
|
};
|
|
14232
|
-
return originalGetConnection.call(
|
|
15028
|
+
return originalGetConnection.call(poolContext, wrappedCallback);
|
|
14233
15029
|
} else try {
|
|
14234
|
-
const result = originalGetConnection.call(
|
|
15030
|
+
const result = originalGetConnection.call(poolContext);
|
|
14235
15031
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
14236
15032
|
connected: true,
|
|
14237
15033
|
hasConnection: true
|
|
@@ -14246,20 +15042,28 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14246
15042
|
throw error;
|
|
14247
15043
|
}
|
|
14248
15044
|
}
|
|
14249
|
-
_handleNoOpReplayGetConnection(callback) {
|
|
15045
|
+
_handleNoOpReplayGetConnection(pool, callback) {
|
|
14250
15046
|
logger.debug(`[MysqlInstrumentation] Background getConnection detected, returning mock connection`);
|
|
14251
|
-
const mockConnection = new TdMysqlConnectionMock(this, "pool");
|
|
15047
|
+
const mockConnection = new TdMysqlConnectionMock(this, "pool", void 0, pool);
|
|
14252
15048
|
if (callback) {
|
|
14253
|
-
process.nextTick(() =>
|
|
15049
|
+
process.nextTick(() => {
|
|
15050
|
+
pool.emit("connection", mockConnection);
|
|
15051
|
+
pool.emit("acquire", mockConnection);
|
|
15052
|
+
callback(null, mockConnection);
|
|
15053
|
+
});
|
|
14254
15054
|
return;
|
|
14255
15055
|
}
|
|
14256
15056
|
return mockConnection;
|
|
14257
15057
|
}
|
|
14258
|
-
_handleReplayPoolGetConnection(spanInfo, callback) {
|
|
15058
|
+
_handleReplayPoolGetConnection(pool, spanInfo, callback) {
|
|
14259
15059
|
logger.debug(`[MysqlInstrumentation] Replaying MySQL Pool getConnection`);
|
|
14260
|
-
const mockConnection = new TdMysqlConnectionMock(this, "pool", spanInfo);
|
|
15060
|
+
const mockConnection = new TdMysqlConnectionMock(this, "pool", spanInfo, pool);
|
|
14261
15061
|
if (callback) {
|
|
14262
|
-
process.nextTick(() =>
|
|
15062
|
+
process.nextTick(() => {
|
|
15063
|
+
pool.emit("connection", mockConnection);
|
|
15064
|
+
pool.emit("acquire", mockConnection);
|
|
15065
|
+
callback(null, mockConnection);
|
|
15066
|
+
});
|
|
14263
15067
|
return;
|
|
14264
15068
|
}
|
|
14265
15069
|
return mockConnection;
|
|
@@ -14492,6 +15296,122 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14492
15296
|
});
|
|
14493
15297
|
return readableStream;
|
|
14494
15298
|
}
|
|
15299
|
+
/**
|
|
15300
|
+
* Get wrapper function for PoolNamespace.query method
|
|
15301
|
+
* This handles queries made via poolCluster.of("pattern").query()
|
|
15302
|
+
*/
|
|
15303
|
+
_getPoolNamespaceQueryPatchFn() {
|
|
15304
|
+
const self = this;
|
|
15305
|
+
return (originalQuery) => {
|
|
15306
|
+
return function query(...args) {
|
|
15307
|
+
const firstArg = args[0];
|
|
15308
|
+
const hasInternalCallback = firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function";
|
|
15309
|
+
if (self.mode === TuskDriftMode.REPLAY) {
|
|
15310
|
+
let sql;
|
|
15311
|
+
let values;
|
|
15312
|
+
let callback;
|
|
15313
|
+
let options = {};
|
|
15314
|
+
if (self.createQuery) try {
|
|
15315
|
+
const queryObj = self.createQuery(...args);
|
|
15316
|
+
sql = queryObj.sql;
|
|
15317
|
+
values = queryObj.values;
|
|
15318
|
+
options = { nestTables: queryObj.nestTables };
|
|
15319
|
+
callback = args.find((arg) => typeof arg === "function");
|
|
15320
|
+
if (!callback && hasInternalCallback) callback = firstArg._callback;
|
|
15321
|
+
} catch (error) {
|
|
15322
|
+
({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
15323
|
+
}
|
|
15324
|
+
else ({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
15325
|
+
const inputValue = {
|
|
15326
|
+
sql,
|
|
15327
|
+
values,
|
|
15328
|
+
options: options.nestTables ? { nestTables: options.nestTables } : void 0
|
|
15329
|
+
};
|
|
15330
|
+
const stackTrace = captureStackTrace(["MysqlInstrumentation"]);
|
|
15331
|
+
return handleReplayMode({
|
|
15332
|
+
noOpRequestHandler: () => {
|
|
15333
|
+
return self.queryMock.handleNoOpReplayQuery({
|
|
15334
|
+
sql,
|
|
15335
|
+
values,
|
|
15336
|
+
callback,
|
|
15337
|
+
options
|
|
15338
|
+
});
|
|
15339
|
+
},
|
|
15340
|
+
isServerRequest: false,
|
|
15341
|
+
replayModeHandler: () => {
|
|
15342
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalQuery.apply(this, args), {
|
|
15343
|
+
name: "mysql.query",
|
|
15344
|
+
kind: import_src$23.SpanKind.CLIENT,
|
|
15345
|
+
submodule: "query",
|
|
15346
|
+
packageType: PackageType.MYSQL,
|
|
15347
|
+
packageName: "mysql",
|
|
15348
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
15349
|
+
inputValue,
|
|
15350
|
+
isPreAppStart: false
|
|
15351
|
+
}, (spanInfo) => {
|
|
15352
|
+
const queryEmitter = self.queryMock.handleReplayQuery({
|
|
15353
|
+
sql,
|
|
15354
|
+
values,
|
|
15355
|
+
callback,
|
|
15356
|
+
options
|
|
15357
|
+
}, inputValue, spanInfo, stackTrace);
|
|
15358
|
+
if (queryEmitter && typeof queryEmitter === "object") queryEmitter.stream = function(streamOptions) {
|
|
15359
|
+
return self._createReplayStreamForQuery(inputValue, spanInfo, stackTrace, queryEmitter, streamOptions);
|
|
15360
|
+
};
|
|
15361
|
+
return queryEmitter;
|
|
15362
|
+
});
|
|
15363
|
+
}
|
|
15364
|
+
});
|
|
15365
|
+
} else if (self.mode === TuskDriftMode.RECORD) return originalQuery.apply(this, args);
|
|
15366
|
+
else return originalQuery.apply(this, args);
|
|
15367
|
+
};
|
|
15368
|
+
};
|
|
15369
|
+
}
|
|
15370
|
+
/**
|
|
15371
|
+
* Get wrapper function for PoolNamespace.getConnection method
|
|
15372
|
+
* This handles connections obtained via poolCluster.of("pattern").getConnection()
|
|
15373
|
+
*/
|
|
15374
|
+
_getPoolNamespaceGetConnectionPatchFn() {
|
|
15375
|
+
const self = this;
|
|
15376
|
+
return (originalGetConnection) => {
|
|
15377
|
+
return function getConnection(callback) {
|
|
15378
|
+
const namespace = this;
|
|
15379
|
+
const inputValue = { clientType: "poolNamespace" };
|
|
15380
|
+
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
15381
|
+
noOpRequestHandler: () => {
|
|
15382
|
+
const mockConnection = new TdMysqlConnectionMock(self, "pool", void 0, void 0);
|
|
15383
|
+
if (callback) {
|
|
15384
|
+
process.nextTick(() => callback(null, mockConnection));
|
|
15385
|
+
return;
|
|
15386
|
+
}
|
|
15387
|
+
return mockConnection;
|
|
15388
|
+
},
|
|
15389
|
+
isServerRequest: false,
|
|
15390
|
+
replayModeHandler: () => {
|
|
15391
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalGetConnection.apply(namespace, [callback]), {
|
|
15392
|
+
name: `mysql.poolNamespace.getConnection`,
|
|
15393
|
+
kind: import_src$23.SpanKind.CLIENT,
|
|
15394
|
+
submodule: "getConnection",
|
|
15395
|
+
packageName: "mysql",
|
|
15396
|
+
packageType: PackageType.MYSQL,
|
|
15397
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
15398
|
+
inputValue,
|
|
15399
|
+
isPreAppStart: false
|
|
15400
|
+
}, (spanInfo) => {
|
|
15401
|
+
const mockConnection = new TdMysqlConnectionMock(self, "pool", spanInfo, void 0);
|
|
15402
|
+
if (callback) {
|
|
15403
|
+
process.nextTick(() => callback(null, mockConnection));
|
|
15404
|
+
return;
|
|
15405
|
+
}
|
|
15406
|
+
return mockConnection;
|
|
15407
|
+
});
|
|
15408
|
+
}
|
|
15409
|
+
});
|
|
15410
|
+
else if (self.mode === TuskDriftMode.RECORD) return originalGetConnection.apply(namespace, [callback]);
|
|
15411
|
+
else return originalGetConnection.apply(namespace, [callback]);
|
|
15412
|
+
};
|
|
15413
|
+
};
|
|
15414
|
+
}
|
|
14495
15415
|
_wrap(target, propertyName, wrapper) {
|
|
14496
15416
|
wrap(target, propertyName, wrapper);
|
|
14497
15417
|
}
|
|
@@ -19563,13 +20483,6 @@ var NextjsInstrumentation = class extends TdInstrumentationBase {
|
|
|
19563
20483
|
return originalHandleRequest.call(this, req, res, parsedUrl);
|
|
19564
20484
|
}
|
|
19565
20485
|
logger.debug(`[NextjsInstrumentation] Setting replay trace id`, replayTraceId);
|
|
19566
|
-
if (self.replayHooks.extractShouldFetchEnvVars(req)) try {
|
|
19567
|
-
const envVars = self.tuskDrift.requestEnvVarsSync(replayTraceId);
|
|
19568
|
-
EnvVarTracker.setEnvVars(replayTraceId, envVars);
|
|
19569
|
-
logger.debug(`[NextjsInstrumentation] Fetched env vars from CLI for trace ${replayTraceId}`);
|
|
19570
|
-
} catch (error) {
|
|
19571
|
-
logger.error(`[NextjsInstrumentation] Failed to fetch env vars from CLI:`, error);
|
|
19572
|
-
}
|
|
19573
20486
|
const ctxWithReplayTraceId = SpanUtils.setCurrentReplayTraceId(replayTraceId);
|
|
19574
20487
|
if (!ctxWithReplayTraceId) throw new Error("Error setting current replay trace id");
|
|
19575
20488
|
return import_src$11.context.with(ctxWithReplayTraceId, () => {
|
|
@@ -19724,10 +20637,8 @@ var NextjsInstrumentation = class extends TdInstrumentationBase {
|
|
|
19724
20637
|
decodedType: getDecodedType(outputValue.headers?.["content-type"] || "")
|
|
19725
20638
|
},
|
|
19726
20639
|
headers: { matchImportance: 0 }
|
|
19727
|
-
}
|
|
19728
|
-
metadata: { ENV_VARS: EnvVarTracker.getEnvVars(spanInfo.traceId) }
|
|
20640
|
+
}
|
|
19729
20641
|
});
|
|
19730
|
-
EnvVarTracker.clearEnvVars(spanInfo.traceId);
|
|
19731
20642
|
const status = (capturedStatusCode || 200) >= 400 ? {
|
|
19732
20643
|
code: import_src$11.SpanStatusCode.ERROR,
|
|
19733
20644
|
message: `HTTP ${capturedStatusCode}`
|
|
@@ -19765,6 +20676,7 @@ var NextjsInstrumentation = class extends TdInstrumentationBase {
|
|
|
19765
20676
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
19766
20677
|
submoduleName: completeInputValue.method,
|
|
19767
20678
|
inputValue: completeInputValue,
|
|
20679
|
+
environment: self.tuskDrift.getEnvironment(),
|
|
19768
20680
|
outputValue,
|
|
19769
20681
|
inputSchema,
|
|
19770
20682
|
outputSchema,
|
|
@@ -24254,7 +25166,7 @@ var SpanTransformer = class SpanTransformer {
|
|
|
24254
25166
|
* Return type is derived from protobuf schema but uses clean JSON.
|
|
24255
25167
|
* We use JSON because serialized protobuf is extremely verbose and not readable.
|
|
24256
25168
|
*/
|
|
24257
|
-
static transformSpanToCleanJSON(span) {
|
|
25169
|
+
static transformSpanToCleanJSON(span, environment) {
|
|
24258
25170
|
const isRootSpan = !span.parentSpanId || span.kind === import_src$9.SpanKind.SERVER;
|
|
24259
25171
|
const attributes = span.attributes;
|
|
24260
25172
|
const packageName = SpanTransformer.extractPackageName(attributes);
|
|
@@ -24298,6 +25210,7 @@ var SpanTransformer = class SpanTransformer {
|
|
|
24298
25210
|
instrumentationName,
|
|
24299
25211
|
submoduleName: submoduleName || "",
|
|
24300
25212
|
packageType: attributes[TdSpanAttributes.PACKAGE_TYPE] || void 0,
|
|
25213
|
+
environment,
|
|
24301
25214
|
inputValue: inputData,
|
|
24302
25215
|
outputValue: outputData,
|
|
24303
25216
|
inputSchema,
|
|
@@ -24761,7 +25674,7 @@ var ApiSpanAdapter = class {
|
|
|
24761
25674
|
const protoSpans = spans.map((span) => this.transformSpanToProtobuf(span));
|
|
24762
25675
|
const request = {
|
|
24763
25676
|
observableServiceId: this.observableServiceId,
|
|
24764
|
-
environment: this.environment,
|
|
25677
|
+
environment: this.environment || "",
|
|
24765
25678
|
sdkVersion: this.sdkVersion,
|
|
24766
25679
|
sdkInstanceId: this.sdkInstanceId,
|
|
24767
25680
|
spans: protoSpans
|
|
@@ -24788,6 +25701,7 @@ var ApiSpanAdapter = class {
|
|
|
24788
25701
|
instrumentationName: cleanSpan.instrumentationName,
|
|
24789
25702
|
submoduleName: cleanSpan.submoduleName,
|
|
24790
25703
|
packageType: cleanSpan.packageType || PackageType.UNSPECIFIED,
|
|
25704
|
+
environment: this.environment,
|
|
24791
25705
|
inputValue: toStruct(cleanSpan.inputValue),
|
|
24792
25706
|
outputValue: toStruct(cleanSpan.outputValue),
|
|
24793
25707
|
inputSchema: cleanSpan.inputSchema,
|
|
@@ -24813,12 +25727,12 @@ var ApiSpanAdapter = class {
|
|
|
24813
25727
|
}
|
|
24814
25728
|
mapSpanKind(kind) {
|
|
24815
25729
|
switch (kind) {
|
|
24816
|
-
case import_src$7.SpanKind.CLIENT: return SpanKind.CLIENT;
|
|
24817
|
-
case import_src$7.SpanKind.SERVER: return SpanKind.SERVER;
|
|
24818
|
-
case import_src$7.SpanKind.PRODUCER: return SpanKind.PRODUCER;
|
|
24819
|
-
case import_src$7.SpanKind.CONSUMER: return SpanKind.CONSUMER;
|
|
24820
|
-
case import_src$7.SpanKind.INTERNAL: return SpanKind.INTERNAL;
|
|
24821
|
-
default: return SpanKind.UNSPECIFIED;
|
|
25730
|
+
case import_src$7.SpanKind.CLIENT: return SpanKind$1.CLIENT;
|
|
25731
|
+
case import_src$7.SpanKind.SERVER: return SpanKind$1.SERVER;
|
|
25732
|
+
case import_src$7.SpanKind.PRODUCER: return SpanKind$1.PRODUCER;
|
|
25733
|
+
case import_src$7.SpanKind.CONSUMER: return SpanKind$1.CONSUMER;
|
|
25734
|
+
case import_src$7.SpanKind.INTERNAL: return SpanKind$1.INTERNAL;
|
|
25735
|
+
default: return SpanKind$1.UNSPECIFIED;
|
|
24822
25736
|
}
|
|
24823
25737
|
}
|
|
24824
25738
|
async shutdown() {
|
|
@@ -24833,6 +25747,7 @@ var TdSpanExporter = class {
|
|
|
24833
25747
|
constructor(config) {
|
|
24834
25748
|
this.adapters = [];
|
|
24835
25749
|
this.mode = config.mode;
|
|
25750
|
+
this.environment = config.environment;
|
|
24836
25751
|
this.setupDefaultAdapters(config);
|
|
24837
25752
|
logger.debug(`TdSpanExporter initialized with ${this.adapters.length} adapter(s)`);
|
|
24838
25753
|
}
|
|
@@ -24916,7 +25831,7 @@ var TdSpanExporter = class {
|
|
|
24916
25831
|
return true;
|
|
24917
25832
|
});
|
|
24918
25833
|
logger.debug(`Filtered ${filteredSpansBasedOnLibraryName.length - filteredBlockedSpans.length} blocked/oversized span(s), ${filteredBlockedSpans.length} remaining`);
|
|
24919
|
-
const cleanSpans = filteredBlockedSpans.map((span) => SpanTransformer.transformSpanToCleanJSON(span));
|
|
25834
|
+
const cleanSpans = filteredBlockedSpans.map((span) => SpanTransformer.transformSpanToCleanJSON(span, this.environment));
|
|
24920
25835
|
if (this.adapters.length === 0) {
|
|
24921
25836
|
logger.debug("No adapters configured");
|
|
24922
25837
|
resultCallback({ code: import_src$5.ExportResultCode.SUCCESS });
|
|
@@ -32067,7 +32982,7 @@ var require_src = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/sdk-
|
|
|
32067
32982
|
//#endregion
|
|
32068
32983
|
//#region package.json
|
|
32069
32984
|
var import_src$1 = /* @__PURE__ */ __toESM(require_src(), 1);
|
|
32070
|
-
var version = "0.1.
|
|
32985
|
+
var version = "0.1.19";
|
|
32071
32986
|
|
|
32072
32987
|
//#endregion
|
|
32073
32988
|
//#region src/version.ts
|
|
@@ -32075,7 +32990,7 @@ const SDK_VERSION = version;
|
|
|
32075
32990
|
const MIN_CLI_VERSION = "0.1.0";
|
|
32076
32991
|
|
|
32077
32992
|
//#endregion
|
|
32078
|
-
//#region node_modules/@use-tusk/drift-schemas/dist/communication-
|
|
32993
|
+
//#region node_modules/@use-tusk/drift-schemas/dist/communication-BY2KZhrg.js
|
|
32079
32994
|
var import_commonjs = /* @__PURE__ */ __toESM(require_commonjs$1(), 1);
|
|
32080
32995
|
var import_commonjs$1 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
|
|
32081
32996
|
/**
|
|
@@ -33219,12 +34134,6 @@ var ProtobufCommunicator = class ProtobufCommunicator {
|
|
|
33219
34134
|
});
|
|
33220
34135
|
await this.sendProtobufMessage(sdkMessage);
|
|
33221
34136
|
}
|
|
33222
|
-
getStackTrace() {
|
|
33223
|
-
Error.stackTraceLimit = 100;
|
|
33224
|
-
const s = (/* @__PURE__ */ new Error()).stack || "";
|
|
33225
|
-
Error.stackTraceLimit = 10;
|
|
33226
|
-
return s.split("\n").slice(2).filter((l) => !l.includes("ProtobufCommunicator")).join("\n");
|
|
33227
|
-
}
|
|
33228
34137
|
async requestMockAsync(mockRequest) {
|
|
33229
34138
|
const requestId = this.generateRequestId();
|
|
33230
34139
|
const cleanSpan = mockRequest.outboundSpan ? this.cleanSpan(mockRequest.outboundSpan) : void 0;
|
|
@@ -33257,7 +34166,7 @@ var ProtobufCommunicator = class ProtobufCommunicator {
|
|
|
33257
34166
|
/**
|
|
33258
34167
|
* Generic synchronous request handler that spawns a child process.
|
|
33259
34168
|
* @param sdkMessage The SDK message to send
|
|
33260
|
-
* @param filePrefix Prefix for temporary files (e.g., '
|
|
34169
|
+
* @param filePrefix Prefix for temporary files (e.g., 'mock')
|
|
33261
34170
|
* @param responseHandler Function to extract and return the desired response
|
|
33262
34171
|
*/
|
|
33263
34172
|
executeSyncRequest(sdkMessage, filePrefix, responseHandler) {
|
|
@@ -33326,35 +34235,6 @@ var ProtobufCommunicator = class ProtobufCommunicator {
|
|
|
33326
34235
|
}
|
|
33327
34236
|
}
|
|
33328
34237
|
/**
|
|
33329
|
-
* Request environment variables from CLI synchronously using a child process.
|
|
33330
|
-
* This blocks the main thread, so it should be used carefully.
|
|
33331
|
-
* Similar to requestMockSync but for environment variables.
|
|
33332
|
-
*/
|
|
33333
|
-
requestEnvVarsSync(traceTestServerSpanId) {
|
|
33334
|
-
const requestId = this.generateRequestId();
|
|
33335
|
-
const envVarRequest = EnvVarRequest.create({ traceTestServerSpanId });
|
|
33336
|
-
const sdkMessage = SDKMessage.create({
|
|
33337
|
-
type: MessageType$1.ENV_VAR_REQUEST,
|
|
33338
|
-
requestId,
|
|
33339
|
-
payload: {
|
|
33340
|
-
oneofKind: "envVarRequest",
|
|
33341
|
-
envVarRequest
|
|
33342
|
-
}
|
|
33343
|
-
});
|
|
33344
|
-
logger.debug(`[ProtobufCommunicator] Requesting env vars (sync) for trace: ${traceTestServerSpanId}`);
|
|
33345
|
-
return this.executeSyncRequest(sdkMessage, "envvar", (cliMessage) => {
|
|
33346
|
-
if (cliMessage.payload.oneofKind !== "envVarResponse") throw new Error(`Unexpected response type: ${cliMessage.type}`);
|
|
33347
|
-
const envVarResponse = cliMessage.payload.envVarResponse;
|
|
33348
|
-
if (!envVarResponse) throw new Error("No env var response received");
|
|
33349
|
-
const envVars = {};
|
|
33350
|
-
if (envVarResponse.envVars) Object.entries(envVarResponse.envVars).forEach(([key, value]) => {
|
|
33351
|
-
envVars[key] = value;
|
|
33352
|
-
});
|
|
33353
|
-
logger.debug(`[ProtobufCommunicator] Received env vars (sync), count: ${Object.keys(envVars).length}`);
|
|
33354
|
-
return envVars;
|
|
33355
|
-
});
|
|
33356
|
-
}
|
|
33357
|
-
/**
|
|
33358
34238
|
* This function uses a separate Node.js child process to communicate with the CLI over a socket.
|
|
33359
34239
|
* The child process creates its own connection and event loop, allowing proper async socket handling.
|
|
33360
34240
|
* The parent process blocks synchronously waiting for the child to complete.
|
|
@@ -33565,22 +34445,6 @@ var ProtobufCommunicator = class ProtobufCommunicator {
|
|
|
33565
34445
|
error: mockResponse.error || "Mock not found"
|
|
33566
34446
|
});
|
|
33567
34447
|
}
|
|
33568
|
-
if (message.payload.oneofKind === "envVarResponse") {
|
|
33569
|
-
const envVarResponse = message.payload.envVarResponse;
|
|
33570
|
-
logger.debug(`[ProtobufCommunicator] Received env var response for requestId: ${requestId}`);
|
|
33571
|
-
const pendingRequest = this.pendingRequests.get(requestId);
|
|
33572
|
-
if (!pendingRequest) {
|
|
33573
|
-
logger.warn("[ProtobufCommunicator] received env var response for unknown request:", requestId);
|
|
33574
|
-
return;
|
|
33575
|
-
}
|
|
33576
|
-
this.pendingRequests.delete(requestId);
|
|
33577
|
-
const envVars = {};
|
|
33578
|
-
if (envVarResponse?.envVars) Object.entries(envVarResponse.envVars).forEach(([key, value]) => {
|
|
33579
|
-
envVars[key] = value;
|
|
33580
|
-
});
|
|
33581
|
-
pendingRequest.resolve(envVars);
|
|
33582
|
-
return;
|
|
33583
|
-
}
|
|
33584
34448
|
}
|
|
33585
34449
|
/**
|
|
33586
34450
|
* Extract response data from MockResponse
|
|
@@ -33880,10 +34744,6 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
33880
34744
|
enabled: true,
|
|
33881
34745
|
mode: this.mode
|
|
33882
34746
|
});
|
|
33883
|
-
new EnvInstrumentation({
|
|
33884
|
-
enabled: this.config.recording?.enable_env_var_recording || false,
|
|
33885
|
-
mode: this.mode
|
|
33886
|
-
});
|
|
33887
34747
|
new PostgresInstrumentation({
|
|
33888
34748
|
enabled: true,
|
|
33889
34749
|
mode: this.mode
|
|
@@ -33931,7 +34791,7 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
33931
34791
|
observableServiceId: this.config.service?.id,
|
|
33932
34792
|
apiKey: this.initParams.apiKey,
|
|
33933
34793
|
tuskBackendBaseUrl: this.config.tusk_api?.url || "https://api.usetusk.ai",
|
|
33934
|
-
environment: this.initParams.env
|
|
34794
|
+
environment: this.initParams.env,
|
|
33935
34795
|
sdkVersion: SDK_VERSION,
|
|
33936
34796
|
sdkInstanceId: this.generateSdkInstanceId()
|
|
33937
34797
|
});
|
|
@@ -33949,6 +34809,34 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
33949
34809
|
generateSdkInstanceId() {
|
|
33950
34810
|
return `sdk-${OriginalGlobalUtils.getOriginalDate().getTime()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
33951
34811
|
}
|
|
34812
|
+
/**
|
|
34813
|
+
* Creates a pre-app-start span containing a snapshot of all environment variables.
|
|
34814
|
+
* Only runs in RECORD mode when env var recording is enabled.
|
|
34815
|
+
*/
|
|
34816
|
+
createEnvVarsSnapshot() {
|
|
34817
|
+
if (this.mode !== TuskDriftMode.RECORD || !this.config.recording?.enable_env_var_recording) return;
|
|
34818
|
+
try {
|
|
34819
|
+
const envVarsSnapshot = {};
|
|
34820
|
+
for (const key of Object.keys(process.env)) envVarsSnapshot[key] = process.env[key];
|
|
34821
|
+
logger.debug(`Creating env vars snapshot with ${Object.keys(envVarsSnapshot).length} variables`);
|
|
34822
|
+
SpanUtils.createAndExecuteSpan(this.mode, () => {}, {
|
|
34823
|
+
name: "ENV_VARS_SNAPSHOT",
|
|
34824
|
+
kind: import_src.SpanKind.INTERNAL,
|
|
34825
|
+
packageName: "process.env",
|
|
34826
|
+
packageType: PackageType.UNSPECIFIED,
|
|
34827
|
+
instrumentationName: "TuskDriftCore",
|
|
34828
|
+
submodule: "env",
|
|
34829
|
+
inputValue: {},
|
|
34830
|
+
outputValue: { ENV_VARS: envVarsSnapshot },
|
|
34831
|
+
isPreAppStart: true
|
|
34832
|
+
}, (spanInfo) => {
|
|
34833
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src.SpanStatusCode.OK });
|
|
34834
|
+
logger.debug(`Env vars snapshot span created: ${spanInfo.spanId}`);
|
|
34835
|
+
});
|
|
34836
|
+
} catch (error) {
|
|
34837
|
+
logger.error("Failed to create env vars snapshot:", error);
|
|
34838
|
+
}
|
|
34839
|
+
}
|
|
33952
34840
|
initialize(initParams) {
|
|
33953
34841
|
initializeGlobalLogger({
|
|
33954
34842
|
logLevel: initParams.logLevel || "info",
|
|
@@ -34025,6 +34913,7 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
34025
34913
|
logger.debug(`Base directory: ${baseDirectory}`);
|
|
34026
34914
|
this.registerDefaultInstrumentations();
|
|
34027
34915
|
this.initializeTracing({ baseDirectory });
|
|
34916
|
+
this.createEnvVarsSnapshot();
|
|
34028
34917
|
this.initialized = true;
|
|
34029
34918
|
logger.info("SDK initialized successfully");
|
|
34030
34919
|
}
|
|
@@ -34088,30 +34977,6 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
34088
34977
|
};
|
|
34089
34978
|
}
|
|
34090
34979
|
}
|
|
34091
|
-
/**
|
|
34092
|
-
* Request environment variables from CLI for a specific trace (synchronously).
|
|
34093
|
-
* This blocks the main thread, so it should be used carefully.
|
|
34094
|
-
*/
|
|
34095
|
-
requestEnvVarsSync(traceTestServerSpanId) {
|
|
34096
|
-
if (!this.isConnectedWithCLI) {
|
|
34097
|
-
logger.error("Requesting sync env vars but CLI is not ready yet");
|
|
34098
|
-
throw new Error("Requesting sync env vars but CLI is not ready yet");
|
|
34099
|
-
}
|
|
34100
|
-
if (!this.communicator || this.mode !== TuskDriftMode.REPLAY) {
|
|
34101
|
-
logger.debug("Cannot request env vars: not in replay mode or no CLI connection");
|
|
34102
|
-
return {};
|
|
34103
|
-
}
|
|
34104
|
-
try {
|
|
34105
|
-
logger.debug(`Requesting env vars (sync) for trace: ${traceTestServerSpanId}`);
|
|
34106
|
-
const envVars = this.communicator.requestEnvVarsSync(traceTestServerSpanId);
|
|
34107
|
-
logger.debug(`Received env vars from CLI, count: ${Object.keys(envVars).length}`);
|
|
34108
|
-
logger.debug(`First 10 env vars: ${JSON.stringify(Object.keys(envVars).slice(0, 10), null, 2)}`);
|
|
34109
|
-
return envVars;
|
|
34110
|
-
} catch (error) {
|
|
34111
|
-
logger.error(`[TuskDrift] Error requesting env vars from CLI:`, error);
|
|
34112
|
-
return {};
|
|
34113
|
-
}
|
|
34114
|
-
}
|
|
34115
34980
|
requestMockSync(mockRequest) {
|
|
34116
34981
|
if (!this.isConnectedWithCLI) {
|
|
34117
34982
|
logger.error("Requesting sync mock but CLI is not ready yet");
|
|
@@ -34163,6 +35028,9 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
34163
35028
|
getInitParams() {
|
|
34164
35029
|
return this.initParams;
|
|
34165
35030
|
}
|
|
35031
|
+
getEnvironment() {
|
|
35032
|
+
return this.initParams.env;
|
|
35033
|
+
}
|
|
34166
35034
|
getTracer() {
|
|
34167
35035
|
return import_src.trace.getTracer(TD_INSTRUMENTATION_LIBRARY_NAME);
|
|
34168
35036
|
}
|