@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.js
CHANGED
|
@@ -4978,31 +4978,31 @@ var require_SamplingResult = /* @__PURE__ */ __commonJS({ "node_modules/@opentel
|
|
|
4978
4978
|
var require_span_kind = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/api/build/src/trace/span_kind.js": ((exports) => {
|
|
4979
4979
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4980
4980
|
exports.SpanKind = void 0;
|
|
4981
|
-
(function(SpanKind$
|
|
4981
|
+
(function(SpanKind$26) {
|
|
4982
4982
|
/** Default value. Indicates that the span is used internally. */
|
|
4983
|
-
SpanKind$
|
|
4983
|
+
SpanKind$26[SpanKind$26["INTERNAL"] = 0] = "INTERNAL";
|
|
4984
4984
|
/**
|
|
4985
4985
|
* Indicates that the span covers server-side handling of an RPC or other
|
|
4986
4986
|
* remote request.
|
|
4987
4987
|
*/
|
|
4988
|
-
SpanKind$
|
|
4988
|
+
SpanKind$26[SpanKind$26["SERVER"] = 1] = "SERVER";
|
|
4989
4989
|
/**
|
|
4990
4990
|
* Indicates that the span covers the client-side wrapper around an RPC or
|
|
4991
4991
|
* other remote request.
|
|
4992
4992
|
*/
|
|
4993
|
-
SpanKind$
|
|
4993
|
+
SpanKind$26[SpanKind$26["CLIENT"] = 2] = "CLIENT";
|
|
4994
4994
|
/**
|
|
4995
4995
|
* Indicates that the span describes producer sending a message to a
|
|
4996
4996
|
* broker. Unlike client and server, there is no direct critical path latency
|
|
4997
4997
|
* relationship between producer and consumer spans.
|
|
4998
4998
|
*/
|
|
4999
|
-
SpanKind$
|
|
4999
|
+
SpanKind$26[SpanKind$26["PRODUCER"] = 3] = "PRODUCER";
|
|
5000
5000
|
/**
|
|
5001
5001
|
* Indicates that the span describes consumer receiving a message from a
|
|
5002
5002
|
* broker. Unlike client and server, there is no direct critical path latency
|
|
5003
5003
|
* relationship between producer and consumer spans.
|
|
5004
5004
|
*/
|
|
5005
|
-
SpanKind$
|
|
5005
|
+
SpanKind$26[SpanKind$26["CONSUMER"] = 4] = "CONSUMER";
|
|
5006
5006
|
})(exports.SpanKind || (exports.SpanKind = {}));
|
|
5007
5007
|
}) });
|
|
5008
5008
|
|
|
@@ -5011,20 +5011,20 @@ var require_span_kind = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetr
|
|
|
5011
5011
|
var require_status = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/api/build/src/trace/status.js": ((exports) => {
|
|
5012
5012
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5013
5013
|
exports.SpanStatusCode = void 0;
|
|
5014
|
-
(function(SpanStatusCode$
|
|
5014
|
+
(function(SpanStatusCode$15) {
|
|
5015
5015
|
/**
|
|
5016
5016
|
* The default status.
|
|
5017
5017
|
*/
|
|
5018
|
-
SpanStatusCode$
|
|
5018
|
+
SpanStatusCode$15[SpanStatusCode$15["UNSET"] = 0] = "UNSET";
|
|
5019
5019
|
/**
|
|
5020
5020
|
* The operation has been validated by an Application developer or
|
|
5021
5021
|
* Operator to have completed successfully.
|
|
5022
5022
|
*/
|
|
5023
|
-
SpanStatusCode$
|
|
5023
|
+
SpanStatusCode$15[SpanStatusCode$15["OK"] = 1] = "OK";
|
|
5024
5024
|
/**
|
|
5025
5025
|
* The operation contains an error.
|
|
5026
5026
|
*/
|
|
5027
|
-
SpanStatusCode$
|
|
5027
|
+
SpanStatusCode$15[SpanStatusCode$15["ERROR"] = 2] = "ERROR";
|
|
5028
5028
|
})(exports.SpanStatusCode || (exports.SpanStatusCode = {}));
|
|
5029
5029
|
}) });
|
|
5030
5030
|
|
|
@@ -5673,7 +5673,7 @@ var require_src$7 = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/ap
|
|
|
5673
5673
|
|
|
5674
5674
|
//#endregion
|
|
5675
5675
|
//#region node_modules/@use-tusk/drift-schemas/dist/duration-B3fwb4jB.js
|
|
5676
|
-
var import_src$
|
|
5676
|
+
var import_src$35 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
5677
5677
|
var import_commonjs$9 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
|
|
5678
5678
|
var Duration$Type = class extends import_commonjs$9.MessageType {
|
|
5679
5679
|
constructor() {
|
|
@@ -6198,7 +6198,7 @@ var JsonSchema$Type = class extends import_commonjs$7.MessageType {
|
|
|
6198
6198
|
const JsonSchema = new JsonSchema$Type();
|
|
6199
6199
|
|
|
6200
6200
|
//#endregion
|
|
6201
|
-
//#region node_modules/@use-tusk/drift-schemas/dist/span-
|
|
6201
|
+
//#region node_modules/@use-tusk/drift-schemas/dist/span-CsBrzhI_.js
|
|
6202
6202
|
var import_commonjs$6 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
|
|
6203
6203
|
/**
|
|
6204
6204
|
* Package type classification enum
|
|
@@ -6284,7 +6284,7 @@ let PackageType = /* @__PURE__ */ function(PackageType$1) {
|
|
|
6284
6284
|
*
|
|
6285
6285
|
* @generated from protobuf enum tusk.drift.core.v1.SpanKind
|
|
6286
6286
|
*/
|
|
6287
|
-
let SpanKind = /* @__PURE__ */ function(SpanKind$1$1) {
|
|
6287
|
+
let SpanKind$1 = /* @__PURE__ */ function(SpanKind$1$1) {
|
|
6288
6288
|
/**
|
|
6289
6289
|
* @generated from protobuf enum value: SPAN_KIND_UNSPECIFIED = 0;
|
|
6290
6290
|
*/
|
|
@@ -6454,7 +6454,7 @@ var Span$Type = class extends import_commonjs$6.MessageType {
|
|
|
6454
6454
|
kind: "enum",
|
|
6455
6455
|
T: () => [
|
|
6456
6456
|
"tusk.drift.core.v1.SpanKind",
|
|
6457
|
-
SpanKind,
|
|
6457
|
+
SpanKind$1,
|
|
6458
6458
|
"SPAN_KIND_"
|
|
6459
6459
|
]
|
|
6460
6460
|
},
|
|
@@ -6493,6 +6493,13 @@ var Span$Type = class extends import_commonjs$6.MessageType {
|
|
|
6493
6493
|
name: "metadata",
|
|
6494
6494
|
kind: "message",
|
|
6495
6495
|
T: () => Struct
|
|
6496
|
+
},
|
|
6497
|
+
{
|
|
6498
|
+
no: 24,
|
|
6499
|
+
name: "environment",
|
|
6500
|
+
kind: "scalar",
|
|
6501
|
+
opt: true,
|
|
6502
|
+
T: 9
|
|
6496
6503
|
}
|
|
6497
6504
|
]);
|
|
6498
6505
|
}
|
|
@@ -6590,6 +6597,9 @@ var Span$Type = class extends import_commonjs$6.MessageType {
|
|
|
6590
6597
|
case 23:
|
|
6591
6598
|
message.metadata = Struct.internalBinaryRead(reader, reader.uint32(), options, message.metadata);
|
|
6592
6599
|
break;
|
|
6600
|
+
case 24:
|
|
6601
|
+
message.environment = reader.string();
|
|
6602
|
+
break;
|
|
6593
6603
|
default:
|
|
6594
6604
|
let u = options.readUnknownField;
|
|
6595
6605
|
if (u === "throw") throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
|
@@ -6623,6 +6633,7 @@ var Span$Type = class extends import_commonjs$6.MessageType {
|
|
|
6623
6633
|
if (message.duration) Duration.internalBinaryWrite(message.duration, writer.tag(21, import_commonjs$6.WireType.LengthDelimited).fork(), options).join();
|
|
6624
6634
|
if (message.isRootSpan !== false) writer.tag(22, import_commonjs$6.WireType.Varint).bool(message.isRootSpan);
|
|
6625
6635
|
if (message.metadata) Struct.internalBinaryWrite(message.metadata, writer.tag(23, import_commonjs$6.WireType.LengthDelimited).fork(), options).join();
|
|
6636
|
+
if (message.environment !== void 0) writer.tag(24, import_commonjs$6.WireType.LengthDelimited).string(message.environment);
|
|
6626
6637
|
let u = options.writeUnknownFields;
|
|
6627
6638
|
if (u !== false) (u == true ? import_commonjs$6.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
6628
6639
|
return writer;
|
|
@@ -6986,12 +6997,12 @@ const Trace = new Trace$Type();
|
|
|
6986
6997
|
const toStruct = (obj) => obj ? objectToProtobufStruct(obj) : void 0;
|
|
6987
6998
|
const mapOtToPb = (k) => {
|
|
6988
6999
|
switch (k) {
|
|
6989
|
-
case import_src$
|
|
6990
|
-
case import_src$
|
|
6991
|
-
case import_src$
|
|
6992
|
-
case import_src$
|
|
6993
|
-
case import_src$
|
|
6994
|
-
default: return SpanKind.UNSPECIFIED;
|
|
7000
|
+
case import_src$35.SpanKind.INTERNAL: return SpanKind$1.INTERNAL;
|
|
7001
|
+
case import_src$35.SpanKind.SERVER: return SpanKind$1.SERVER;
|
|
7002
|
+
case import_src$35.SpanKind.CLIENT: return SpanKind$1.CLIENT;
|
|
7003
|
+
case import_src$35.SpanKind.PRODUCER: return SpanKind$1.PRODUCER;
|
|
7004
|
+
case import_src$35.SpanKind.CONSUMER: return SpanKind$1.CONSUMER;
|
|
7005
|
+
default: return SpanKind$1.UNSPECIFIED;
|
|
6995
7006
|
}
|
|
6996
7007
|
};
|
|
6997
7008
|
/**
|
|
@@ -7394,13 +7405,13 @@ var TdInstrumentationNodeModule = class {
|
|
|
7394
7405
|
|
|
7395
7406
|
//#endregion
|
|
7396
7407
|
//#region src/core/types.ts
|
|
7397
|
-
var import_src$
|
|
7408
|
+
var import_src$34 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
7398
7409
|
const TD_INSTRUMENTATION_LIBRARY_NAME = "tusk-drift-sdk";
|
|
7399
|
-
const REPLAY_TRACE_ID_CONTEXT_KEY = (0, import_src$
|
|
7400
|
-
const SPAN_KIND_CONTEXT_KEY = (0, import_src$
|
|
7401
|
-
const IS_PRE_APP_START_CONTEXT_KEY = (0, import_src$
|
|
7402
|
-
const STOP_RECORDING_CHILD_SPANS_CONTEXT_KEY = (0, import_src$
|
|
7403
|
-
const CALLING_LIBRARY_CONTEXT_KEY = (0, import_src$
|
|
7410
|
+
const REPLAY_TRACE_ID_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.replayTraceId");
|
|
7411
|
+
const SPAN_KIND_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.spanKind");
|
|
7412
|
+
const IS_PRE_APP_START_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.isPreAppStart");
|
|
7413
|
+
const STOP_RECORDING_CHILD_SPANS_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.stopRecordingChildSpans");
|
|
7414
|
+
const CALLING_LIBRARY_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.callingLibrary");
|
|
7404
7415
|
let TdSpanAttributes = /* @__PURE__ */ function(TdSpanAttributes$1) {
|
|
7405
7416
|
/**
|
|
7406
7417
|
* Presentational information:
|
|
@@ -7512,7 +7523,7 @@ TraceBlockingManager.instance = null;
|
|
|
7512
7523
|
|
|
7513
7524
|
//#endregion
|
|
7514
7525
|
//#region src/core/tracing/SpanUtils.ts
|
|
7515
|
-
var import_src$
|
|
7526
|
+
var import_src$33 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
7516
7527
|
var SpanUtils = class SpanUtils {
|
|
7517
7528
|
/**
|
|
7518
7529
|
* Creates a new span and returns span info including trace ID and span ID
|
|
@@ -7520,8 +7531,8 @@ var SpanUtils = class SpanUtils {
|
|
|
7520
7531
|
static createSpan(options) {
|
|
7521
7532
|
try {
|
|
7522
7533
|
const tracer = TuskDriftCore.getInstance().getTracer();
|
|
7523
|
-
const parentContext = options.parentContext || import_src$
|
|
7524
|
-
const activeSpan = import_src$
|
|
7534
|
+
const parentContext = options.parentContext || import_src$33.context.active();
|
|
7535
|
+
const activeSpan = import_src$33.trace.getSpan(parentContext);
|
|
7525
7536
|
if (activeSpan) {
|
|
7526
7537
|
const parentTraceId = activeSpan.spanContext().traceId;
|
|
7527
7538
|
if (TraceBlockingManager.getInstance().isTraceBlocked(parentTraceId)) {
|
|
@@ -7530,11 +7541,11 @@ var SpanUtils = class SpanUtils {
|
|
|
7530
7541
|
}
|
|
7531
7542
|
}
|
|
7532
7543
|
const span = tracer.startSpan(options.name, {
|
|
7533
|
-
kind: options.kind || import_src$
|
|
7544
|
+
kind: options.kind || import_src$33.SpanKind.CLIENT,
|
|
7534
7545
|
attributes: options.attributes || {}
|
|
7535
7546
|
}, parentContext);
|
|
7536
7547
|
const spanContext = span.spanContext();
|
|
7537
|
-
const newContext = import_src$
|
|
7548
|
+
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);
|
|
7538
7549
|
return {
|
|
7539
7550
|
traceId: spanContext.traceId,
|
|
7540
7551
|
spanId: spanContext.spanId,
|
|
@@ -7551,7 +7562,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7551
7562
|
* Executes a function within a span context
|
|
7552
7563
|
*/
|
|
7553
7564
|
static withSpan(spanInfo, fn) {
|
|
7554
|
-
return import_src$
|
|
7565
|
+
return import_src$33.context.with(spanInfo.context, fn);
|
|
7555
7566
|
}
|
|
7556
7567
|
/**
|
|
7557
7568
|
* Execute a function within a properly configured span
|
|
@@ -7568,14 +7579,14 @@ var SpanUtils = class SpanUtils {
|
|
|
7568
7579
|
* @returns The result of the function execution
|
|
7569
7580
|
*/
|
|
7570
7581
|
static createAndExecuteSpan(mode, originalFunctionCall, options, fn) {
|
|
7571
|
-
const spanContext = import_src$
|
|
7582
|
+
const spanContext = import_src$33.trace.getActiveSpan()?.spanContext();
|
|
7572
7583
|
if (spanContext) {
|
|
7573
|
-
if (import_src$
|
|
7584
|
+
if (import_src$33.context.active().getValue(STOP_RECORDING_CHILD_SPANS_CONTEXT_KEY)) {
|
|
7574
7585
|
logger.debug(`[SpanUtils] Stopping recording of child spans for span ${spanContext.spanId}, packageName: ${options.packageName}, instrumentationName: ${options.instrumentationName}`);
|
|
7575
7586
|
return originalFunctionCall();
|
|
7576
7587
|
}
|
|
7577
7588
|
}
|
|
7578
|
-
const { name, kind, packageName, instrumentationName, packageType, submodule, inputValue, inputSchemaMerges, isPreAppStart, metadata, stopRecordingChildSpans } = options;
|
|
7589
|
+
const { name, kind, packageName, instrumentationName, packageType, submodule, inputValue, outputValue, inputSchemaMerges, isPreAppStart, metadata, stopRecordingChildSpans } = options;
|
|
7579
7590
|
let spanInfo = null;
|
|
7580
7591
|
try {
|
|
7581
7592
|
spanInfo = SpanUtils.createSpan({
|
|
@@ -7589,6 +7600,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7589
7600
|
[TdSpanAttributes.INSTRUMENTATION_NAME]: instrumentationName,
|
|
7590
7601
|
[TdSpanAttributes.PACKAGE_TYPE]: packageType,
|
|
7591
7602
|
[TdSpanAttributes.INPUT_VALUE]: createSpanInputValue(inputValue),
|
|
7603
|
+
...outputValue && { [TdSpanAttributes.OUTPUT_VALUE]: JSON.stringify(outputValue) },
|
|
7592
7604
|
[TdSpanAttributes.IS_PRE_APP_START]: isPreAppStart,
|
|
7593
7605
|
...inputSchemaMerges && { [TdSpanAttributes.INPUT_SCHEMA_MERGES]: JSON.stringify(inputSchemaMerges) },
|
|
7594
7606
|
...metadata && { [TdSpanAttributes.METADATA]: JSON.stringify(metadata) }
|
|
@@ -7608,15 +7620,15 @@ var SpanUtils = class SpanUtils {
|
|
|
7608
7620
|
*/
|
|
7609
7621
|
static getCurrentSpanInfo() {
|
|
7610
7622
|
try {
|
|
7611
|
-
const activeSpan = import_src$
|
|
7623
|
+
const activeSpan = import_src$33.trace.getActiveSpan();
|
|
7612
7624
|
if (!activeSpan) return null;
|
|
7613
7625
|
const spanContext = activeSpan.spanContext();
|
|
7614
7626
|
return {
|
|
7615
7627
|
traceId: spanContext.traceId,
|
|
7616
7628
|
spanId: spanContext.spanId,
|
|
7617
7629
|
span: activeSpan,
|
|
7618
|
-
context: import_src$
|
|
7619
|
-
isPreAppStart: import_src$
|
|
7630
|
+
context: import_src$33.context.active(),
|
|
7631
|
+
isPreAppStart: import_src$33.context.active().getValue(IS_PRE_APP_START_CONTEXT_KEY)
|
|
7620
7632
|
};
|
|
7621
7633
|
} catch (error) {
|
|
7622
7634
|
logger.error("SpanUtils error getting current span info:", error);
|
|
@@ -7680,7 +7692,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7680
7692
|
}
|
|
7681
7693
|
static setCurrentReplayTraceId(replayTraceId) {
|
|
7682
7694
|
try {
|
|
7683
|
-
return import_src$
|
|
7695
|
+
return import_src$33.context.active().setValue(REPLAY_TRACE_ID_CONTEXT_KEY, replayTraceId);
|
|
7684
7696
|
} catch (error) {
|
|
7685
7697
|
logger.error("SpanUtils error setting current replay trace id:", error);
|
|
7686
7698
|
return null;
|
|
@@ -7691,7 +7703,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7691
7703
|
*/
|
|
7692
7704
|
static getCurrentReplayTraceId() {
|
|
7693
7705
|
try {
|
|
7694
|
-
return import_src$
|
|
7706
|
+
return import_src$33.context.active().getValue(REPLAY_TRACE_ID_CONTEXT_KEY);
|
|
7695
7707
|
} catch (error) {
|
|
7696
7708
|
logger.error("SpanUtils error getting current replay trace id:", error);
|
|
7697
7709
|
return null;
|
|
@@ -7955,30 +7967,6 @@ var TdHttpMockSocket = class extends EventEmitter {
|
|
|
7955
7967
|
}
|
|
7956
7968
|
};
|
|
7957
7969
|
|
|
7958
|
-
//#endregion
|
|
7959
|
-
//#region src/instrumentation/core/trackers/EnvVarTracker.ts
|
|
7960
|
-
var EnvVarTracker = class {
|
|
7961
|
-
static setEnvVar({ traceId, key, value }) {
|
|
7962
|
-
this.envVars.set(traceId, {
|
|
7963
|
-
...this.envVars.get(traceId) || {},
|
|
7964
|
-
[key]: value
|
|
7965
|
-
});
|
|
7966
|
-
}
|
|
7967
|
-
static setEnvVars(traceId, envVars) {
|
|
7968
|
-
this.envVars.set(traceId, envVars);
|
|
7969
|
-
}
|
|
7970
|
-
static getEnvVar(traceId, key) {
|
|
7971
|
-
return this.envVars.get(traceId)?.[key];
|
|
7972
|
-
}
|
|
7973
|
-
static getEnvVars(traceId) {
|
|
7974
|
-
return this.envVars.get(traceId);
|
|
7975
|
-
}
|
|
7976
|
-
static clearEnvVars(traceId) {
|
|
7977
|
-
this.envVars.delete(traceId);
|
|
7978
|
-
}
|
|
7979
|
-
};
|
|
7980
|
-
EnvVarTracker.envVars = /* @__PURE__ */ new Map();
|
|
7981
|
-
|
|
7982
7970
|
//#endregion
|
|
7983
7971
|
//#region src/instrumentation/core/trackers/DateTracker.ts
|
|
7984
7972
|
/**
|
|
@@ -8279,6 +8267,7 @@ function convertMockRequestDataToCleanSpanData(mockRequestData, tuskDrift, input
|
|
|
8279
8267
|
return {
|
|
8280
8268
|
...mockRequestData,
|
|
8281
8269
|
parentSpanId: "",
|
|
8270
|
+
environment: tuskDrift.getEnvironment(),
|
|
8282
8271
|
inputValueHash,
|
|
8283
8272
|
inputSchema,
|
|
8284
8273
|
inputSchemaHash,
|
|
@@ -8363,7 +8352,7 @@ function findMockResponseSync({ mockRequestData, tuskDrift, inputValueSchemaMerg
|
|
|
8363
8352
|
|
|
8364
8353
|
//#endregion
|
|
8365
8354
|
//#region src/instrumentation/libraries/http/mocks/TdMockClientRequest.ts
|
|
8366
|
-
var import_src$
|
|
8355
|
+
var import_src$32 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
8367
8356
|
let ClientRequest;
|
|
8368
8357
|
/**
|
|
8369
8358
|
* Mock ClientRequest implementation for Tusk Drift HTTP replay
|
|
@@ -8534,7 +8523,7 @@ var TdMockClientRequest = class TdMockClientRequest extends EventEmitter {
|
|
|
8534
8523
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
8535
8524
|
submoduleName: rawInputValue.method,
|
|
8536
8525
|
inputValue,
|
|
8537
|
-
kind: import_src$
|
|
8526
|
+
kind: import_src$32.SpanKind.CLIENT,
|
|
8538
8527
|
stackTrace: this.stackTrace
|
|
8539
8528
|
},
|
|
8540
8529
|
tuskDrift: this.tuskDrift,
|
|
@@ -8675,13 +8664,6 @@ var HttpReplayHooks = class {
|
|
|
8675
8664
|
return traceIdHeader ? String(traceIdHeader) : null;
|
|
8676
8665
|
}
|
|
8677
8666
|
/**
|
|
8678
|
-
* Check if we should fetch env vars from CLI
|
|
8679
|
-
*/
|
|
8680
|
-
extractShouldFetchEnvVars(req) {
|
|
8681
|
-
const fetchHeader = req.headers["x-td-fetch-env-vars"] || req.headers["X-TD-FETCH-ENV-VARS"];
|
|
8682
|
-
return fetchHeader === "true" || fetchHeader === true;
|
|
8683
|
-
}
|
|
8684
|
-
/**
|
|
8685
8667
|
* Handle outbound HTTP requests in replay mode
|
|
8686
8668
|
* Uses TdMockClientRequest for simplified mocking approach
|
|
8687
8669
|
*/
|
|
@@ -8711,7 +8693,7 @@ var HttpReplayHooks = class {
|
|
|
8711
8693
|
|
|
8712
8694
|
//#endregion
|
|
8713
8695
|
//#region src/instrumentation/core/utils/modeUtils.ts
|
|
8714
|
-
var import_src$
|
|
8696
|
+
var import_src$31 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
8715
8697
|
/**
|
|
8716
8698
|
* Utility function that abstracts the common record mode pattern of checking for current span context
|
|
8717
8699
|
* and deciding whether to execute record mode logic or just call the original function.
|
|
@@ -8732,7 +8714,7 @@ function handleRecordMode({ originalFunctionCall, recordModeHandler, spanKind })
|
|
|
8732
8714
|
return originalFunctionCall();
|
|
8733
8715
|
}
|
|
8734
8716
|
if (!isAppReady) return recordModeHandler({ isPreAppStart: true });
|
|
8735
|
-
if (!currentSpanInfo && spanKind !== import_src$
|
|
8717
|
+
if (!currentSpanInfo && spanKind !== import_src$31.SpanKind.SERVER || currentSpanInfo?.isPreAppStart) return originalFunctionCall();
|
|
8736
8718
|
else return recordModeHandler({ isPreAppStart: false });
|
|
8737
8719
|
}
|
|
8738
8720
|
/**
|
|
@@ -9970,7 +9952,7 @@ var require_commonjs$1 = /* @__PURE__ */ __commonJS({ "node_modules/@protobuf-ts
|
|
|
9970
9952
|
}) });
|
|
9971
9953
|
|
|
9972
9954
|
//#endregion
|
|
9973
|
-
//#region node_modules/@use-tusk/drift-schemas/dist/span_export_service-
|
|
9955
|
+
//#region node_modules/@use-tusk/drift-schemas/dist/span_export_service-CmkFvTqD.js
|
|
9974
9956
|
var import_commonjs$4 = /* @__PURE__ */ __toESM(require_commonjs$1(), 1);
|
|
9975
9957
|
var import_commonjs$5 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
|
|
9976
9958
|
var ExportSpansRequest$Type = class extends import_commonjs$5.MessageType {
|
|
@@ -10212,7 +10194,7 @@ function captureStackTrace(excludeClassNames = []) {
|
|
|
10212
10194
|
|
|
10213
10195
|
//#endregion
|
|
10214
10196
|
//#region src/instrumentation/libraries/http/HttpTransformEngine.ts
|
|
10215
|
-
var import_src$
|
|
10197
|
+
var import_src$30 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
10216
10198
|
/**
|
|
10217
10199
|
* Creates an empty HttpClientInputValue object for dropped spans
|
|
10218
10200
|
*/
|
|
@@ -10265,7 +10247,7 @@ var HttpTransformEngine = class {
|
|
|
10265
10247
|
const testSpan = {
|
|
10266
10248
|
traceId: "",
|
|
10267
10249
|
spanId: "",
|
|
10268
|
-
kind: import_src$
|
|
10250
|
+
kind: import_src$30.SpanKind.SERVER,
|
|
10269
10251
|
protocol: "http",
|
|
10270
10252
|
inputValue: {
|
|
10271
10253
|
method,
|
|
@@ -10288,7 +10270,7 @@ var HttpTransformEngine = class {
|
|
|
10288
10270
|
const testSpan = {
|
|
10289
10271
|
traceId: "",
|
|
10290
10272
|
spanId: "",
|
|
10291
|
-
kind: import_src$
|
|
10273
|
+
kind: import_src$30.SpanKind.CLIENT,
|
|
10292
10274
|
protocol: inputValue.protocol || "http",
|
|
10293
10275
|
inputValue: clonedInputValue
|
|
10294
10276
|
};
|
|
@@ -10315,8 +10297,8 @@ var HttpTransformEngine = class {
|
|
|
10315
10297
|
const matcherFunction = this.compileMatcher(matcher);
|
|
10316
10298
|
if (action.type === "drop") return (span) => {
|
|
10317
10299
|
if (!matcherFunction(span)) return;
|
|
10318
|
-
if (span.inputValue) span.inputValue = span.kind === import_src$
|
|
10319
|
-
if (span.outputValue) span.outputValue = span.kind === import_src$
|
|
10300
|
+
if (span.inputValue) span.inputValue = span.kind === import_src$30.SpanKind.CLIENT ? createEmptyClientInputValue(span.protocol) : createEmptyServerInputValue();
|
|
10301
|
+
if (span.outputValue) span.outputValue = span.kind === import_src$30.SpanKind.CLIENT ? createEmptyClientOutputValue() : createEmptyServerOutputValue();
|
|
10320
10302
|
return {
|
|
10321
10303
|
type: "drop",
|
|
10322
10304
|
field: "entire_span",
|
|
@@ -10346,8 +10328,8 @@ var HttpTransformEngine = class {
|
|
|
10346
10328
|
}
|
|
10347
10329
|
compileMatcher(matcher) {
|
|
10348
10330
|
const checks = [];
|
|
10349
|
-
if (matcher.direction === "outbound") checks.push((span) => span.kind === import_src$
|
|
10350
|
-
else if (matcher.direction === "inbound") checks.push((span) => span.kind === import_src$
|
|
10331
|
+
if (matcher.direction === "outbound") checks.push((span) => span.kind === import_src$30.SpanKind.CLIENT);
|
|
10332
|
+
else if (matcher.direction === "inbound") checks.push((span) => span.kind === import_src$30.SpanKind.SERVER);
|
|
10351
10333
|
if (matcher.method) if (matcher.method.length === 0) {} else {
|
|
10352
10334
|
const methods = matcher.method.map((method) => method.toUpperCase());
|
|
10353
10335
|
checks.push((span) => {
|
|
@@ -10575,7 +10557,7 @@ var HttpTransformEngine = class {
|
|
|
10575
10557
|
|
|
10576
10558
|
//#endregion
|
|
10577
10559
|
//#region src/instrumentation/libraries/http/Instrumentation.ts
|
|
10578
|
-
var import_src$
|
|
10560
|
+
var import_src$29 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
10579
10561
|
var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
10580
10562
|
constructor(config) {
|
|
10581
10563
|
super("http", config);
|
|
@@ -10660,19 +10642,12 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10660
10642
|
return originalHandler.call(this);
|
|
10661
10643
|
}
|
|
10662
10644
|
logger.debug(`[HttpInstrumentation] Setting replay trace id`, replayTraceId);
|
|
10663
|
-
if (this.replayHooks.extractShouldFetchEnvVars(req)) try {
|
|
10664
|
-
const envVars = this.tuskDrift.requestEnvVarsSync(replayTraceId);
|
|
10665
|
-
EnvVarTracker.setEnvVars(replayTraceId, envVars);
|
|
10666
|
-
logger.debug(`[HttpInstrumentation] Fetched env vars from CLI for trace ${replayTraceId}`);
|
|
10667
|
-
} catch (error) {
|
|
10668
|
-
logger.error(`[HttpInstrumentation] Failed to fetch env vars from CLI:`, error);
|
|
10669
|
-
}
|
|
10670
10645
|
const ctxWithReplayTraceId = SpanUtils.setCurrentReplayTraceId(replayTraceId);
|
|
10671
10646
|
if (!ctxWithReplayTraceId) throw new Error("Error setting current replay trace id");
|
|
10672
|
-
return import_src$
|
|
10647
|
+
return import_src$29.context.with(ctxWithReplayTraceId, () => {
|
|
10673
10648
|
return SpanUtils.createAndExecuteSpan(this.mode, () => originalHandler.call(this), {
|
|
10674
10649
|
name: `${target}`,
|
|
10675
|
-
kind: import_src$
|
|
10650
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10676
10651
|
packageName: spanProtocol,
|
|
10677
10652
|
submodule: method,
|
|
10678
10653
|
packageType: PackageType.HTTP,
|
|
@@ -10717,7 +10692,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10717
10692
|
logger.debug(`[HttpInstrumentation] Http inbound request arriving, inputValue: ${JSON.stringify(inputValue)}`);
|
|
10718
10693
|
return SpanUtils.createAndExecuteSpan(this.mode, () => originalHandler.call(this), {
|
|
10719
10694
|
name: `${target}`,
|
|
10720
|
-
kind: import_src$
|
|
10695
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10721
10696
|
packageName: spanProtocol,
|
|
10722
10697
|
packageType: PackageType.HTTP,
|
|
10723
10698
|
submodule: method,
|
|
@@ -10737,7 +10712,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10737
10712
|
});
|
|
10738
10713
|
});
|
|
10739
10714
|
},
|
|
10740
|
-
spanKind: import_src$
|
|
10715
|
+
spanKind: import_src$29.SpanKind.SERVER
|
|
10741
10716
|
});
|
|
10742
10717
|
} else return originalHandler.call(this);
|
|
10743
10718
|
}
|
|
@@ -10754,8 +10729,8 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10754
10729
|
_handleInboundRequestInSpan({ req, res, originalHandler, spanInfo, inputValue, schemaMerges, protocol }) {
|
|
10755
10730
|
const self = this;
|
|
10756
10731
|
const spanProtocol = this._normalizeProtocol(protocol, "http");
|
|
10757
|
-
import_src$
|
|
10758
|
-
import_src$
|
|
10732
|
+
import_src$29.context.bind(spanInfo.context, req);
|
|
10733
|
+
import_src$29.context.bind(spanInfo.context, res);
|
|
10759
10734
|
let completeInputValue = inputValue;
|
|
10760
10735
|
this._captureServerRequestBody(req, spanInfo, inputValue, schemaMerges, (updatedInputValue) => {
|
|
10761
10736
|
completeInputValue = updatedInputValue;
|
|
@@ -10793,7 +10768,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10793
10768
|
const spanData = {
|
|
10794
10769
|
traceId: spanInfo.traceId,
|
|
10795
10770
|
spanId: spanInfo.spanId,
|
|
10796
|
-
kind: import_src$
|
|
10771
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10797
10772
|
protocol: spanProtocol,
|
|
10798
10773
|
inputValue: completeInputValue,
|
|
10799
10774
|
outputValue
|
|
@@ -10809,14 +10784,12 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10809
10784
|
},
|
|
10810
10785
|
headers: { matchImportance: 0 }
|
|
10811
10786
|
},
|
|
10812
|
-
metadata: { ENV_VARS: EnvVarTracker.getEnvVars(spanInfo.traceId) },
|
|
10813
10787
|
...spanData.transformMetadata && { transformMetadata: spanData.transformMetadata }
|
|
10814
10788
|
});
|
|
10815
|
-
EnvVarTracker.clearEnvVars(spanInfo.traceId);
|
|
10816
10789
|
const status = statusCode >= 400 ? {
|
|
10817
|
-
code: import_src$
|
|
10790
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
10818
10791
|
message: `HTTP ${statusCode}`
|
|
10819
|
-
} : { code: import_src$
|
|
10792
|
+
} : { code: import_src$29.SpanStatusCode.OK };
|
|
10820
10793
|
SpanUtils.setStatus(spanInfo.span, status);
|
|
10821
10794
|
const decodedType = getDecodedType(outputValue.headers?.["content-type"] || "");
|
|
10822
10795
|
if (decodedType && !ACCEPTABLE_CONTENT_TYPES.has(decodedType)) {
|
|
@@ -10858,6 +10831,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10858
10831
|
instrumentationName: "HttpInstrumentation",
|
|
10859
10832
|
submoduleName: completeInputValue.method || inputValue.method,
|
|
10860
10833
|
inputValue: completeInputValue,
|
|
10834
|
+
environment: self.tuskDrift.getEnvironment(),
|
|
10861
10835
|
outputValue,
|
|
10862
10836
|
inputSchema,
|
|
10863
10837
|
outputSchema,
|
|
@@ -10865,7 +10839,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10865
10839
|
outputSchemaHash: JsonSchemaHelper.generateDeterministicHash(outputSchema),
|
|
10866
10840
|
inputValueHash,
|
|
10867
10841
|
outputValueHash,
|
|
10868
|
-
kind: import_src$
|
|
10842
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10869
10843
|
packageType: PackageType.HTTP,
|
|
10870
10844
|
status: {
|
|
10871
10845
|
code: statusCode >= 400 ? StatusCode.ERROR : StatusCode.OK,
|
|
@@ -10894,7 +10868,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10894
10868
|
try {
|
|
10895
10869
|
logger.debug(`[HttpInstrumentation] Server request error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
10896
10870
|
SpanUtils.endSpan(spanInfo.span, {
|
|
10897
|
-
code: import_src$
|
|
10871
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
10898
10872
|
message: error.message
|
|
10899
10873
|
});
|
|
10900
10874
|
} catch (error$1) {
|
|
@@ -10905,7 +10879,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10905
10879
|
try {
|
|
10906
10880
|
logger.debug(`[HttpInstrumentation] Server response 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) {
|
|
@@ -11110,7 +11084,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11110
11084
|
inputValue: completeInputValue
|
|
11111
11085
|
});
|
|
11112
11086
|
SpanUtils.endSpan(spanInfo.span, {
|
|
11113
|
-
code: import_src$
|
|
11087
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
11114
11088
|
message: error.message
|
|
11115
11089
|
});
|
|
11116
11090
|
} catch (error$1) {
|
|
@@ -11127,7 +11101,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11127
11101
|
const spanData = {
|
|
11128
11102
|
traceId: spanInfo.traceId,
|
|
11129
11103
|
spanId: spanInfo.spanId,
|
|
11130
|
-
kind: import_src$
|
|
11104
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11131
11105
|
protocol: normalizedProtocol,
|
|
11132
11106
|
inputValue,
|
|
11133
11107
|
outputValue
|
|
@@ -11140,9 +11114,9 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11140
11114
|
transformMetadata: spanData.transformMetadata ? spanData.transformMetadata : void 0
|
|
11141
11115
|
});
|
|
11142
11116
|
const status = statusCode >= 400 ? {
|
|
11143
|
-
code: import_src$
|
|
11117
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
11144
11118
|
message: `HTTP ${statusCode}`
|
|
11145
|
-
} : { code: import_src$
|
|
11119
|
+
} : { code: import_src$29.SpanStatusCode.OK };
|
|
11146
11120
|
SpanUtils.endSpan(spanInfo.span, status);
|
|
11147
11121
|
}
|
|
11148
11122
|
_captureHeadersFromRawHeaders(rawHeaders) {
|
|
@@ -11196,7 +11170,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11196
11170
|
};
|
|
11197
11171
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalRequest.apply(this, args), {
|
|
11198
11172
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11199
|
-
kind: import_src$
|
|
11173
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11200
11174
|
packageName: requestProtocol,
|
|
11201
11175
|
packageType: PackageType.HTTP,
|
|
11202
11176
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11231,7 +11205,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11231
11205
|
};
|
|
11232
11206
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalRequest.apply(this, args), {
|
|
11233
11207
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11234
|
-
kind: import_src$
|
|
11208
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11235
11209
|
packageName: requestProtocol,
|
|
11236
11210
|
packageType: PackageType.HTTP,
|
|
11237
11211
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11243,7 +11217,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11243
11217
|
return self._handleOutboundRequestInSpan(originalRequest, args, spanInfo, inputValue, { headers: { matchImportance: 0 } });
|
|
11244
11218
|
});
|
|
11245
11219
|
},
|
|
11246
|
-
spanKind: import_src$
|
|
11220
|
+
spanKind: import_src$29.SpanKind.CLIENT
|
|
11247
11221
|
});
|
|
11248
11222
|
else return originalRequest.apply(this, args);
|
|
11249
11223
|
};
|
|
@@ -11289,7 +11263,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11289
11263
|
};
|
|
11290
11264
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalGet.apply(this, args), {
|
|
11291
11265
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11292
|
-
kind: import_src$
|
|
11266
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11293
11267
|
packageName: requestProtocol,
|
|
11294
11268
|
packageType: PackageType.HTTP,
|
|
11295
11269
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11323,7 +11297,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11323
11297
|
};
|
|
11324
11298
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalGet.apply(this, args), {
|
|
11325
11299
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11326
|
-
kind: import_src$
|
|
11300
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11327
11301
|
packageName: requestProtocol,
|
|
11328
11302
|
packageType: PackageType.HTTP,
|
|
11329
11303
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11335,7 +11309,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11335
11309
|
return self._handleOutboundRequestInSpan(originalGet, args, spanInfo, inputValue, { headers: { matchImportance: 0 } });
|
|
11336
11310
|
});
|
|
11337
11311
|
},
|
|
11338
|
-
spanKind: import_src$
|
|
11312
|
+
spanKind: import_src$29.SpanKind.CLIENT
|
|
11339
11313
|
});
|
|
11340
11314
|
else return originalGet.apply(this, args);
|
|
11341
11315
|
};
|
|
@@ -11378,99 +11352,9 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11378
11352
|
}
|
|
11379
11353
|
};
|
|
11380
11354
|
|
|
11381
|
-
//#endregion
|
|
11382
|
-
//#region src/instrumentation/libraries/env/Instrumentation.ts
|
|
11383
|
-
/**
|
|
11384
|
-
* Environment variable instrumentation that records and replays process.env access.
|
|
11385
|
-
* In record mode, captures environment variable values.
|
|
11386
|
-
* In replay mode, returns previously recorded values for deterministic behavior.
|
|
11387
|
-
*/
|
|
11388
|
-
var EnvInstrumentation = class extends TdInstrumentationBase {
|
|
11389
|
-
constructor(config = {}) {
|
|
11390
|
-
super("env", config);
|
|
11391
|
-
this.isInPatchedCall = false;
|
|
11392
|
-
this.mode = config.mode || TuskDriftMode.DISABLED;
|
|
11393
|
-
}
|
|
11394
|
-
init() {
|
|
11395
|
-
this.patchProcessEnv();
|
|
11396
|
-
return [];
|
|
11397
|
-
}
|
|
11398
|
-
patchProcessEnv() {
|
|
11399
|
-
if (this.mode === TuskDriftMode.DISABLED || !this._config.enabled) return;
|
|
11400
|
-
this.originalProcessEnv = process.env;
|
|
11401
|
-
const envProxy = new Proxy(this.originalProcessEnv, {
|
|
11402
|
-
get: (target, property, receiver) => {
|
|
11403
|
-
return this._handleEnvAccess(target, property);
|
|
11404
|
-
},
|
|
11405
|
-
set: (target, property, value, receiver) => {
|
|
11406
|
-
target[property] = value;
|
|
11407
|
-
return true;
|
|
11408
|
-
},
|
|
11409
|
-
deleteProperty: (target, property) => {
|
|
11410
|
-
delete target[property];
|
|
11411
|
-
return true;
|
|
11412
|
-
},
|
|
11413
|
-
ownKeys: (target) => {
|
|
11414
|
-
return Reflect.ownKeys(target);
|
|
11415
|
-
},
|
|
11416
|
-
getOwnPropertyDescriptor: (target, property) => {
|
|
11417
|
-
return Reflect.getOwnPropertyDescriptor(target, property);
|
|
11418
|
-
},
|
|
11419
|
-
has: (target, property) => {
|
|
11420
|
-
return Reflect.has(target, property);
|
|
11421
|
-
}
|
|
11422
|
-
});
|
|
11423
|
-
process.env = envProxy;
|
|
11424
|
-
}
|
|
11425
|
-
_handleEnvAccess(target, key) {
|
|
11426
|
-
if (this.isInPatchedCall) return target[key];
|
|
11427
|
-
if (!TuskDriftCore.getInstance().isAppReady()) return target[key];
|
|
11428
|
-
this.isInPatchedCall = true;
|
|
11429
|
-
try {
|
|
11430
|
-
return this._handleEnvAccessInMode(target, key);
|
|
11431
|
-
} finally {
|
|
11432
|
-
this.isInPatchedCall = false;
|
|
11433
|
-
}
|
|
11434
|
-
}
|
|
11435
|
-
_handleEnvAccessInMode(target, key) {
|
|
11436
|
-
let currentSpanInfo = null;
|
|
11437
|
-
try {
|
|
11438
|
-
currentSpanInfo = SpanUtils.getCurrentSpanInfo();
|
|
11439
|
-
} catch (error) {
|
|
11440
|
-
logger.error(`EnvInstrumentation error getting current span info:`, error);
|
|
11441
|
-
}
|
|
11442
|
-
if (!currentSpanInfo) return target[key];
|
|
11443
|
-
if (this.mode === TuskDriftMode.REPLAY) return this._handleReplayMode(target, key);
|
|
11444
|
-
else if (this.mode === TuskDriftMode.RECORD) return this._handleRecordMode(currentSpanInfo, target, key);
|
|
11445
|
-
else return target[key];
|
|
11446
|
-
}
|
|
11447
|
-
_handleReplayMode(target, key) {
|
|
11448
|
-
const replayTraceId = SpanUtils.getCurrentReplayTraceId();
|
|
11449
|
-
if (!replayTraceId) return target[key];
|
|
11450
|
-
const envVar = EnvVarTracker.getEnvVar(replayTraceId, key);
|
|
11451
|
-
if (envVar) {
|
|
11452
|
-
logger.debug(`Returning env var ${key} for trace ${replayTraceId}: ${envVar}`);
|
|
11453
|
-
return envVar;
|
|
11454
|
-
}
|
|
11455
|
-
return target[key];
|
|
11456
|
-
}
|
|
11457
|
-
_handleRecordMode(spanInfo, target, key) {
|
|
11458
|
-
try {
|
|
11459
|
-
EnvVarTracker.setEnvVar({
|
|
11460
|
-
traceId: spanInfo.traceId,
|
|
11461
|
-
key,
|
|
11462
|
-
value: target[key] || void 0
|
|
11463
|
-
});
|
|
11464
|
-
} catch (error) {
|
|
11465
|
-
logger.error(`EnvInstrumentation error storing env var:`, error);
|
|
11466
|
-
}
|
|
11467
|
-
return target[key];
|
|
11468
|
-
}
|
|
11469
|
-
};
|
|
11470
|
-
|
|
11471
11355
|
//#endregion
|
|
11472
11356
|
//#region src/instrumentation/libraries/date/Instrumentation.ts
|
|
11473
|
-
var import_src$
|
|
11357
|
+
var import_src$28 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
11474
11358
|
/**
|
|
11475
11359
|
* Date instrumentation that provides consistent dates in replay mode.
|
|
11476
11360
|
* In replay mode, new Date() calls return the latest mock response timestamp.
|
|
@@ -11509,7 +11393,7 @@ var DateInstrumentation = class DateInstrumentation extends TdInstrumentationBas
|
|
|
11509
11393
|
if (this.mode !== TuskDriftMode.REPLAY) return this._callOriginalDate(args, isConstructorCall);
|
|
11510
11394
|
const currentSpanInfo = SpanUtils.getCurrentSpanInfo();
|
|
11511
11395
|
if (!currentSpanInfo) return this._callOriginalDate(args, isConstructorCall);
|
|
11512
|
-
if (currentSpanInfo.context.getValue(SPAN_KIND_CONTEXT_KEY) !== import_src$
|
|
11396
|
+
if (currentSpanInfo.context.getValue(SPAN_KIND_CONTEXT_KEY) !== import_src$28.SpanKind.SERVER) return this._callOriginalDate(args, isConstructorCall);
|
|
11513
11397
|
this.isInPatchedCall = true;
|
|
11514
11398
|
try {
|
|
11515
11399
|
return this._handleReplayDate(args, isConstructorCall);
|
|
@@ -11755,7 +11639,7 @@ var TdPgClientMock = class extends EventEmitter {
|
|
|
11755
11639
|
|
|
11756
11640
|
//#endregion
|
|
11757
11641
|
//#region src/instrumentation/libraries/pg/Instrumentation.ts
|
|
11758
|
-
var import_src$
|
|
11642
|
+
var import_src$27 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
11759
11643
|
var PgInstrumentation = class extends TdInstrumentationBase {
|
|
11760
11644
|
constructor(config = {}) {
|
|
11761
11645
|
super("pg", config);
|
|
@@ -11796,6 +11680,10 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11796
11680
|
const self = this;
|
|
11797
11681
|
return (originalQuery) => {
|
|
11798
11682
|
return function query(...args) {
|
|
11683
|
+
if (self.isSubmittable(args[0])) {
|
|
11684
|
+
logger.debug(`[PgInstrumentation] Submittable query detected, passing through uninstrumented`);
|
|
11685
|
+
return originalQuery.apply(this, args);
|
|
11686
|
+
}
|
|
11799
11687
|
let queryConfig = null;
|
|
11800
11688
|
try {
|
|
11801
11689
|
queryConfig = self.parseQueryArgs(args);
|
|
@@ -11824,7 +11712,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11824
11712
|
const spanName = inputValue.clientType === "pool" ? "pg-pool.query" : "pg.query";
|
|
11825
11713
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalQuery.apply(this, args), {
|
|
11826
11714
|
name: spanName,
|
|
11827
|
-
kind: import_src$
|
|
11715
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11828
11716
|
submodule: "query",
|
|
11829
11717
|
packageType: PackageType.PG,
|
|
11830
11718
|
packageName,
|
|
@@ -11843,7 +11731,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11843
11731
|
const spanName = inputValue.clientType === "pool" ? "pg-pool.query" : "pg.query";
|
|
11844
11732
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalQuery.apply(this, args), {
|
|
11845
11733
|
name: spanName,
|
|
11846
|
-
kind: import_src$
|
|
11734
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11847
11735
|
submodule: "query",
|
|
11848
11736
|
packageType: PackageType.PG,
|
|
11849
11737
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11854,7 +11742,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11854
11742
|
return self._handleRecordQueryInSpan(spanInfo, originalQuery, queryConfig, args, this);
|
|
11855
11743
|
});
|
|
11856
11744
|
},
|
|
11857
|
-
spanKind: import_src$
|
|
11745
|
+
spanKind: import_src$27.SpanKind.CLIENT
|
|
11858
11746
|
});
|
|
11859
11747
|
else return originalQuery.apply(this, args);
|
|
11860
11748
|
};
|
|
@@ -11876,7 +11764,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11876
11764
|
replayModeHandler: () => {
|
|
11877
11765
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
11878
11766
|
name: `pg.connect`,
|
|
11879
|
-
kind: import_src$
|
|
11767
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11880
11768
|
submodule: "connect",
|
|
11881
11769
|
packageName: "pg",
|
|
11882
11770
|
packageType: PackageType.PG,
|
|
@@ -11893,7 +11781,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11893
11781
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
11894
11782
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
11895
11783
|
name: `pg.connect`,
|
|
11896
|
-
kind: import_src$
|
|
11784
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11897
11785
|
submodule: "connect",
|
|
11898
11786
|
packageName: "pg",
|
|
11899
11787
|
packageType: PackageType.PG,
|
|
@@ -11904,12 +11792,19 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11904
11792
|
return self._handleRecordConnectInSpan(spanInfo, originalConnect, callback, this);
|
|
11905
11793
|
});
|
|
11906
11794
|
},
|
|
11907
|
-
spanKind: import_src$
|
|
11795
|
+
spanKind: import_src$27.SpanKind.CLIENT
|
|
11908
11796
|
});
|
|
11909
11797
|
else return originalConnect.apply(this, [callback]);
|
|
11910
11798
|
};
|
|
11911
11799
|
};
|
|
11912
11800
|
}
|
|
11801
|
+
/**
|
|
11802
|
+
* Check if an object is a Submittable (Query object with submit method).
|
|
11803
|
+
* This is the same check pg uses internally: typeof config.submit === 'function'
|
|
11804
|
+
*/
|
|
11805
|
+
isSubmittable(arg) {
|
|
11806
|
+
return arg && typeof arg.submit === "function";
|
|
11807
|
+
}
|
|
11913
11808
|
parseQueryArgs(args) {
|
|
11914
11809
|
if (args.length === 0) return null;
|
|
11915
11810
|
const firstArg = args[0];
|
|
@@ -11937,7 +11832,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11937
11832
|
logger.debug(`[PgInstrumentation] PG query error (hasCallback): ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
11938
11833
|
try {
|
|
11939
11834
|
SpanUtils.endSpan(spanInfo.span, {
|
|
11940
|
-
code: import_src$
|
|
11835
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
11941
11836
|
message: error.message
|
|
11942
11837
|
});
|
|
11943
11838
|
} catch (error$1) {
|
|
@@ -11947,7 +11842,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11947
11842
|
logger.debug(`[PgInstrumentation] PG query completed successfully (hasCallback) (${SpanUtils.getTraceInfo()})`);
|
|
11948
11843
|
try {
|
|
11949
11844
|
this._addOutputAttributesToSpan(spanInfo, result);
|
|
11950
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
11845
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
11951
11846
|
} catch (error$1) {
|
|
11952
11847
|
logger.error(`[PgInstrumentation] error processing response:`, error$1);
|
|
11953
11848
|
}
|
|
@@ -11974,7 +11869,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11974
11869
|
logger.debug(`[PgInstrumentation] PG query completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
11975
11870
|
try {
|
|
11976
11871
|
this._addOutputAttributesToSpan(spanInfo, result);
|
|
11977
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
11872
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
11978
11873
|
} catch (error) {
|
|
11979
11874
|
logger.error(`[PgInstrumentation] error processing response:`, error);
|
|
11980
11875
|
}
|
|
@@ -11983,7 +11878,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11983
11878
|
logger.debug(`[PgInstrumentation] PG query error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
11984
11879
|
try {
|
|
11985
11880
|
SpanUtils.endSpan(spanInfo.span, {
|
|
11986
|
-
code: import_src$
|
|
11881
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
11987
11882
|
message: error.message
|
|
11988
11883
|
});
|
|
11989
11884
|
} catch (error$1) {
|
|
@@ -12015,7 +11910,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12015
11910
|
packageName,
|
|
12016
11911
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12017
11912
|
submoduleName: "query",
|
|
12018
|
-
kind: import_src$
|
|
11913
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
12019
11914
|
stackTrace
|
|
12020
11915
|
},
|
|
12021
11916
|
tuskDrift: this.tuskDrift
|
|
@@ -12059,6 +11954,8 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12059
11954
|
* Reference for data type IDs: https://jdbc.postgresql.org/documentation/publicapi/constant-values.html
|
|
12060
11955
|
*/
|
|
12061
11956
|
convertPostgresTypes(result, rowMode) {
|
|
11957
|
+
if (result && result.isMultiStatement && Array.isArray(result.results)) return result.results.map((singleResult) => this.convertPostgresTypes(singleResult, rowMode));
|
|
11958
|
+
if (Array.isArray(result)) return result.map((singleResult) => this.convertPostgresTypes(singleResult, rowMode));
|
|
12062
11959
|
if (!result || !result.fields || !result.rows) return result;
|
|
12063
11960
|
if (rowMode === "array") {
|
|
12064
11961
|
const convertedRows$1 = result.rows.map((row) => {
|
|
@@ -12099,7 +11996,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12099
11996
|
logger.debug(`[PgInstrumentation] PG connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12100
11997
|
try {
|
|
12101
11998
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12102
|
-
code: import_src$
|
|
11999
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12103
12000
|
message: error.message
|
|
12104
12001
|
});
|
|
12105
12002
|
} catch (error$1) {
|
|
@@ -12109,7 +12006,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12109
12006
|
logger.debug(`[PgInstrumentation] PG connect completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12110
12007
|
try {
|
|
12111
12008
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { connected: true } });
|
|
12112
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12009
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12113
12010
|
} catch (error$1) {
|
|
12114
12011
|
logger.error(`[PgInstrumentation] error processing connect response:`, error$1);
|
|
12115
12012
|
}
|
|
@@ -12121,7 +12018,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12121
12018
|
logger.debug(`[PgInstrumentation] PG connect completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12122
12019
|
try {
|
|
12123
12020
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { connected: true } });
|
|
12124
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12021
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12125
12022
|
} catch (error) {
|
|
12126
12023
|
logger.error(`[PgInstrumentation] error processing connect response:`, error);
|
|
12127
12024
|
}
|
|
@@ -12130,7 +12027,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12130
12027
|
logger.debug(`[PgInstrumentation] PG connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12131
12028
|
try {
|
|
12132
12029
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12133
|
-
code: import_src$
|
|
12030
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12134
12031
|
message: error.message
|
|
12135
12032
|
});
|
|
12136
12033
|
} catch (error$1) {
|
|
@@ -12148,7 +12045,18 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12148
12045
|
}
|
|
12149
12046
|
_addOutputAttributesToSpan(spanInfo, result) {
|
|
12150
12047
|
if (!result) return;
|
|
12151
|
-
|
|
12048
|
+
let outputValue;
|
|
12049
|
+
if (Array.isArray(result)) outputValue = {
|
|
12050
|
+
isMultiStatement: true,
|
|
12051
|
+
results: result.map((r) => ({
|
|
12052
|
+
command: r.command,
|
|
12053
|
+
rowCount: r.rowCount,
|
|
12054
|
+
oid: r.oid,
|
|
12055
|
+
rows: r.rows || [],
|
|
12056
|
+
fields: r.fields || []
|
|
12057
|
+
}))
|
|
12058
|
+
};
|
|
12059
|
+
else outputValue = {
|
|
12152
12060
|
command: result.command,
|
|
12153
12061
|
rowCount: result.rowCount,
|
|
12154
12062
|
oid: result.oid,
|
|
@@ -12191,7 +12099,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12191
12099
|
replayModeHandler: () => {
|
|
12192
12100
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
12193
12101
|
name: `pg-pool.connect`,
|
|
12194
|
-
kind: import_src$
|
|
12102
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
12195
12103
|
submodule: "connect",
|
|
12196
12104
|
packageName: "pg-pool",
|
|
12197
12105
|
packageType: PackageType.PG,
|
|
@@ -12208,7 +12116,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12208
12116
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
12209
12117
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
12210
12118
|
name: `pg-pool.connect`,
|
|
12211
|
-
kind: import_src$
|
|
12119
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
12212
12120
|
submodule: "connect",
|
|
12213
12121
|
packageName: "pg-pool",
|
|
12214
12122
|
packageType: PackageType.PG,
|
|
@@ -12219,7 +12127,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12219
12127
|
return self._handleRecordPoolConnectInSpan(spanInfo, originalConnect, callback, this);
|
|
12220
12128
|
});
|
|
12221
12129
|
},
|
|
12222
|
-
spanKind: import_src$
|
|
12130
|
+
spanKind: import_src$27.SpanKind.CLIENT
|
|
12223
12131
|
});
|
|
12224
12132
|
else return originalConnect.apply(this, [callback]);
|
|
12225
12133
|
};
|
|
@@ -12232,7 +12140,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12232
12140
|
logger.debug(`[PgInstrumentation] PG Pool connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12233
12141
|
try {
|
|
12234
12142
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12235
|
-
code: import_src$
|
|
12143
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12236
12144
|
message: error.message
|
|
12237
12145
|
});
|
|
12238
12146
|
} catch (error$1) {
|
|
@@ -12245,7 +12153,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12245
12153
|
connected: true,
|
|
12246
12154
|
hasClient: !!client
|
|
12247
12155
|
} });
|
|
12248
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12156
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12249
12157
|
} catch (error$1) {
|
|
12250
12158
|
logger.error(`[PgInstrumentation] error processing pool connect response:`, error$1);
|
|
12251
12159
|
}
|
|
@@ -12260,7 +12168,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12260
12168
|
connected: true,
|
|
12261
12169
|
hasClient: !!client
|
|
12262
12170
|
} });
|
|
12263
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12171
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12264
12172
|
} catch (error) {
|
|
12265
12173
|
logger.error(`[PgInstrumentation] error processing pool connect response:`, error);
|
|
12266
12174
|
}
|
|
@@ -12269,7 +12177,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12269
12177
|
logger.debug(`[PgInstrumentation] PG Pool connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12270
12178
|
try {
|
|
12271
12179
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12272
|
-
code: import_src$
|
|
12180
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12273
12181
|
message: error.message
|
|
12274
12182
|
});
|
|
12275
12183
|
} catch (error$1) {
|
|
@@ -12298,68 +12206,114 @@ function isPostgresOutputValueType(value) {
|
|
|
12298
12206
|
}
|
|
12299
12207
|
|
|
12300
12208
|
//#endregion
|
|
12301
|
-
//#region src/instrumentation/libraries/postgres/
|
|
12302
|
-
|
|
12303
|
-
|
|
12304
|
-
|
|
12305
|
-
|
|
12306
|
-
|
|
12307
|
-
|
|
12308
|
-
|
|
12209
|
+
//#region src/instrumentation/libraries/postgres/utils/typeConversion.ts
|
|
12210
|
+
/**
|
|
12211
|
+
* Convert PostgreSQL string values back to appropriate JavaScript types
|
|
12212
|
+
* based on field metadata from the recorded response.
|
|
12213
|
+
*/
|
|
12214
|
+
function convertPostgresTypes(result) {
|
|
12215
|
+
if (!isPostgresOutputValueType(result)) {
|
|
12216
|
+
logger.error(`[PostgresInstrumentation] output value is not of type PostgresOutputValueType`, result);
|
|
12217
|
+
return;
|
|
12309
12218
|
}
|
|
12310
|
-
|
|
12311
|
-
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12315
|
-
|
|
12219
|
+
const { rows, count, command, columns, state, statement } = result;
|
|
12220
|
+
const resultArray = Array.from((rows || []).map((row) => reconstructBuffers(row)));
|
|
12221
|
+
if (count !== void 0) Object.defineProperty(resultArray, "count", {
|
|
12222
|
+
value: count,
|
|
12223
|
+
writable: true,
|
|
12224
|
+
enumerable: false
|
|
12225
|
+
});
|
|
12226
|
+
if (command !== void 0) Object.defineProperty(resultArray, "command", {
|
|
12227
|
+
value: command,
|
|
12228
|
+
writable: true,
|
|
12229
|
+
enumerable: false
|
|
12230
|
+
});
|
|
12231
|
+
if (columns !== void 0) Object.defineProperty(resultArray, "columns", {
|
|
12232
|
+
value: columns,
|
|
12233
|
+
writable: true,
|
|
12234
|
+
enumerable: false
|
|
12235
|
+
});
|
|
12236
|
+
if (state !== void 0) Object.defineProperty(resultArray, "state", {
|
|
12237
|
+
value: state,
|
|
12238
|
+
writable: true,
|
|
12239
|
+
enumerable: false
|
|
12240
|
+
});
|
|
12241
|
+
if (statement !== void 0) Object.defineProperty(resultArray, "statement", {
|
|
12242
|
+
value: statement,
|
|
12243
|
+
writable: true,
|
|
12244
|
+
enumerable: false
|
|
12245
|
+
});
|
|
12246
|
+
return resultArray;
|
|
12247
|
+
}
|
|
12248
|
+
/**
|
|
12249
|
+
* Recursively reconstructs Buffer objects from their JSON-serialized format.
|
|
12250
|
+
* When Buffers are JSON.stringify'd, they become { type: "Buffer", data: [...] }.
|
|
12251
|
+
* This method converts them back to actual Buffer instances.
|
|
12252
|
+
*/
|
|
12253
|
+
function reconstructBuffers(value) {
|
|
12254
|
+
if (value === null || value === void 0) return value;
|
|
12255
|
+
if (typeof value === "object" && value.type === "Buffer" && Array.isArray(value.data)) return Buffer.from(value.data);
|
|
12256
|
+
if (Array.isArray(value)) return value.map((item) => reconstructBuffers(item));
|
|
12257
|
+
if (typeof value === "object") {
|
|
12258
|
+
const result = {};
|
|
12259
|
+
for (const key of Object.keys(value)) result[key] = reconstructBuffers(value[key]);
|
|
12260
|
+
return result;
|
|
12316
12261
|
}
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12320
|
-
|
|
12321
|
-
|
|
12322
|
-
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
12327
|
-
|
|
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
|
-
logger.debug(`[PostgresInstrumentation] Postgres module patching complete`);
|
|
12355
|
-
return postgresModule;
|
|
12262
|
+
return value;
|
|
12263
|
+
}
|
|
12264
|
+
/**
|
|
12265
|
+
* Add output attributes to span for PostgreSQL results.
|
|
12266
|
+
*/
|
|
12267
|
+
function addOutputAttributesToSpan(spanInfo, result) {
|
|
12268
|
+
if (!result) return;
|
|
12269
|
+
const isArray$1 = Array.isArray(result);
|
|
12270
|
+
logger.debug(`[PostgresInstrumentation] Adding output attributes to span for ${isArray$1 ? "array" : "object"} result`);
|
|
12271
|
+
const normalizeValue = (val) => {
|
|
12272
|
+
if (Buffer.isBuffer(val)) return val.toString("utf8");
|
|
12273
|
+
else if (Array.isArray(val)) return val.map(normalizeValue);
|
|
12274
|
+
else if (val && typeof val === "object" && val.type === "Buffer" && Array.isArray(val.data)) return Buffer.from(val.data).toString("utf8");
|
|
12275
|
+
return val;
|
|
12276
|
+
};
|
|
12277
|
+
const outputValue = {
|
|
12278
|
+
rows: isArray$1 ? Array.from(result).map(normalizeValue) : (result.rows || []).map(normalizeValue),
|
|
12279
|
+
count: result.count !== void 0 && result.count !== null ? result.count : void 0,
|
|
12280
|
+
command: result.command || void 0,
|
|
12281
|
+
columns: result.columns || void 0,
|
|
12282
|
+
state: result.state || void 0,
|
|
12283
|
+
statement: result.statement || void 0
|
|
12284
|
+
};
|
|
12285
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
12286
|
+
}
|
|
12287
|
+
|
|
12288
|
+
//#endregion
|
|
12289
|
+
//#region src/instrumentation/libraries/postgres/utils/queryUtils.ts
|
|
12290
|
+
/**
|
|
12291
|
+
* Reconstruct a parameterized query string from template strings array and values.
|
|
12292
|
+
* Converts values to $1, $2, etc. placeholders.
|
|
12293
|
+
*/
|
|
12294
|
+
function reconstructQueryString(strings, values) {
|
|
12295
|
+
let queryString = "";
|
|
12296
|
+
for (let i = 0; i < strings.length; i++) {
|
|
12297
|
+
queryString += strings[i];
|
|
12298
|
+
if (i < values.length) queryString += `$${i + 1}`;
|
|
12356
12299
|
}
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12300
|
+
return queryString;
|
|
12301
|
+
}
|
|
12302
|
+
|
|
12303
|
+
//#endregion
|
|
12304
|
+
//#region src/instrumentation/libraries/postgres/handlers/ConnectionHandler.ts
|
|
12305
|
+
var import_src$26 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
12306
|
+
var ConnectionHandler = class {
|
|
12307
|
+
constructor(mode, instrumentationName, isAppReady, wrapSqlInstance) {
|
|
12308
|
+
this.mode = mode;
|
|
12309
|
+
this.instrumentationName = instrumentationName;
|
|
12310
|
+
this.isAppReady = isAppReady;
|
|
12311
|
+
this.wrapSqlInstance = wrapSqlInstance;
|
|
12312
|
+
}
|
|
12313
|
+
handlePostgresConnection(originalFunction, args) {
|
|
12360
12314
|
const inputValue = {
|
|
12361
|
-
connectionString:
|
|
12362
|
-
options:
|
|
12315
|
+
connectionString: typeof args[0] === "string" ? args[0] : void 0,
|
|
12316
|
+
options: typeof args[0] === "string" ? args[1] : args[0]
|
|
12363
12317
|
};
|
|
12364
12318
|
if (this.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
12365
12319
|
noOpRequestHandler: () => {
|
|
@@ -12373,96 +12327,148 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12373
12327
|
}));
|
|
12374
12328
|
mockSql.begin = () => Promise.resolve();
|
|
12375
12329
|
mockSql.end = () => Promise.resolve();
|
|
12330
|
+
mockSql.file = () => Promise.resolve(Object.assign([], {
|
|
12331
|
+
count: 0,
|
|
12332
|
+
command: null
|
|
12333
|
+
}));
|
|
12334
|
+
mockSql.reserve = () => Promise.resolve(mockSql);
|
|
12335
|
+
mockSql.listen = () => Promise.resolve({
|
|
12336
|
+
state: { state: "I" },
|
|
12337
|
+
unlisten: async () => {}
|
|
12338
|
+
});
|
|
12339
|
+
mockSql.notify = () => Promise.resolve();
|
|
12376
12340
|
return mockSql;
|
|
12377
12341
|
},
|
|
12378
12342
|
isServerRequest: false,
|
|
12379
12343
|
replayModeHandler: () => {
|
|
12380
12344
|
return SpanUtils.createAndExecuteSpan(this.mode, () => {
|
|
12381
12345
|
const sqlInstance = originalFunction(...args);
|
|
12382
|
-
return this.
|
|
12346
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12383
12347
|
}, {
|
|
12384
12348
|
name: "postgres.connect",
|
|
12385
|
-
kind: import_src$
|
|
12349
|
+
kind: import_src$26.SpanKind.CLIENT,
|
|
12386
12350
|
submodule: "connect",
|
|
12387
12351
|
packageType: PackageType.PG,
|
|
12388
12352
|
packageName: "postgres",
|
|
12389
|
-
instrumentationName: this.
|
|
12353
|
+
instrumentationName: this.instrumentationName,
|
|
12390
12354
|
inputValue,
|
|
12391
|
-
isPreAppStart: false
|
|
12355
|
+
isPreAppStart: this.isAppReady() ? false : true
|
|
12392
12356
|
}, (spanInfo) => {
|
|
12393
|
-
return this.
|
|
12357
|
+
return this.handleReplayConnect(originalFunction, args);
|
|
12394
12358
|
});
|
|
12395
12359
|
}
|
|
12396
12360
|
});
|
|
12397
12361
|
else if (this.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
12398
12362
|
originalFunctionCall: () => {
|
|
12399
12363
|
const sqlInstance = originalFunction(...args);
|
|
12400
|
-
return this.
|
|
12364
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12401
12365
|
},
|
|
12402
12366
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
12403
12367
|
return SpanUtils.createAndExecuteSpan(this.mode, () => {
|
|
12404
12368
|
const sqlInstance = originalFunction(...args);
|
|
12405
|
-
return this.
|
|
12369
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12406
12370
|
}, {
|
|
12407
12371
|
name: "postgres.connect",
|
|
12408
|
-
kind: import_src$
|
|
12372
|
+
kind: import_src$26.SpanKind.CLIENT,
|
|
12409
12373
|
submodule: "connect",
|
|
12410
12374
|
packageType: PackageType.PG,
|
|
12411
12375
|
packageName: "postgres",
|
|
12412
|
-
instrumentationName: this.
|
|
12376
|
+
instrumentationName: this.instrumentationName,
|
|
12413
12377
|
inputValue,
|
|
12414
12378
|
isPreAppStart
|
|
12415
12379
|
}, (spanInfo) => {
|
|
12416
|
-
return this.
|
|
12380
|
+
return this.handleRecordConnect(spanInfo, originalFunction, args);
|
|
12417
12381
|
});
|
|
12418
12382
|
},
|
|
12419
|
-
spanKind: import_src$
|
|
12383
|
+
spanKind: import_src$26.SpanKind.CLIENT
|
|
12420
12384
|
});
|
|
12421
12385
|
else return originalFunction(...args);
|
|
12422
12386
|
}
|
|
12423
|
-
|
|
12424
|
-
try {
|
|
12425
|
-
const url = new URL(connectionString);
|
|
12426
|
-
if (url.password) url.password = "***";
|
|
12427
|
-
return url.toString();
|
|
12428
|
-
} catch {
|
|
12429
|
-
return "[INVALID_URL]";
|
|
12430
|
-
}
|
|
12431
|
-
}
|
|
12432
|
-
_sanitizeConnectionOptions(options) {
|
|
12433
|
-
if (!options || typeof options !== "object") return options;
|
|
12434
|
-
const sanitized = { ...options };
|
|
12435
|
-
if (sanitized.password) sanitized.password = "***";
|
|
12436
|
-
if (sanitized.ssl && typeof sanitized.ssl === "object") {
|
|
12437
|
-
sanitized.ssl = { ...sanitized.ssl };
|
|
12438
|
-
if (sanitized.ssl.key) sanitized.ssl.key = "***";
|
|
12439
|
-
if (sanitized.ssl.cert) sanitized.ssl.cert = "***";
|
|
12440
|
-
if (sanitized.ssl.ca) sanitized.ssl.ca = "***";
|
|
12441
|
-
}
|
|
12442
|
-
return sanitized;
|
|
12443
|
-
}
|
|
12444
|
-
_handleRecordConnect(spanInfo, originalFunction, args) {
|
|
12387
|
+
handleRecordConnect(spanInfo, originalFunction, args) {
|
|
12445
12388
|
const sqlInstance = originalFunction(...args);
|
|
12446
|
-
const wrappedInstance = this.
|
|
12389
|
+
const wrappedInstance = this.wrapSqlInstance(sqlInstance);
|
|
12447
12390
|
try {
|
|
12448
12391
|
logger.debug(`[PostgresInstrumentation] Postgres connection created successfully (${SpanUtils.getTraceInfo()})`);
|
|
12449
12392
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { connected: true } });
|
|
12450
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12393
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$26.SpanStatusCode.OK });
|
|
12451
12394
|
} catch (error) {
|
|
12452
12395
|
logger.error(`[PostgresInstrumentation] error adding span attributes:`, error);
|
|
12453
12396
|
}
|
|
12454
12397
|
return wrappedInstance;
|
|
12455
12398
|
}
|
|
12456
|
-
|
|
12399
|
+
handleReplayConnect(originalFunction, args) {
|
|
12457
12400
|
logger.debug(`[PostgresInstrumentation] Replaying Postgres connection`);
|
|
12458
12401
|
try {
|
|
12459
12402
|
const sqlInstance = originalFunction(...args);
|
|
12460
|
-
return this.
|
|
12403
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12461
12404
|
} catch (error) {
|
|
12462
12405
|
logger.debug(`[PostgresInstrumentation] Postgres connection error in replay: ${error.message}`);
|
|
12463
12406
|
throw error;
|
|
12464
12407
|
}
|
|
12465
12408
|
}
|
|
12409
|
+
};
|
|
12410
|
+
|
|
12411
|
+
//#endregion
|
|
12412
|
+
//#region src/instrumentation/libraries/postgres/Instrumentation.ts
|
|
12413
|
+
var import_src$25 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
12414
|
+
var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
12415
|
+
constructor(config = {}) {
|
|
12416
|
+
super("postgres", config);
|
|
12417
|
+
this.INSTRUMENTATION_NAME = "PostgresInstrumentation";
|
|
12418
|
+
this.mode = config.mode || TuskDriftMode.DISABLED;
|
|
12419
|
+
this.tuskDrift = TuskDriftCore.getInstance();
|
|
12420
|
+
this.connectionHandler = new ConnectionHandler(this.mode, this.INSTRUMENTATION_NAME, () => this.tuskDrift.isAppReady(), (sqlInstance) => this._wrapSqlInstance(sqlInstance));
|
|
12421
|
+
}
|
|
12422
|
+
init() {
|
|
12423
|
+
return [new TdInstrumentationNodeModule({
|
|
12424
|
+
name: "postgres",
|
|
12425
|
+
supportedVersions: ["3.*"],
|
|
12426
|
+
patch: (moduleExports) => this._patchPostgresModule(moduleExports)
|
|
12427
|
+
})];
|
|
12428
|
+
}
|
|
12429
|
+
_patchPostgresModule(postgresModule) {
|
|
12430
|
+
logger.debug(`[PostgresInstrumentation] Patching Postgres module in ${this.mode} mode`);
|
|
12431
|
+
if (this.isModulePatched(postgresModule)) {
|
|
12432
|
+
logger.debug(`[PostgresInstrumentation] Postgres module already patched, skipping`);
|
|
12433
|
+
return postgresModule;
|
|
12434
|
+
}
|
|
12435
|
+
const self = this;
|
|
12436
|
+
if (isEsm(postgresModule)) {
|
|
12437
|
+
logger.debug(`[PostgresInstrumentation] Wrapping ESM default export`);
|
|
12438
|
+
this._wrap(postgresModule, "default", (originalFunction) => {
|
|
12439
|
+
return function(...args) {
|
|
12440
|
+
return self._handlePostgresConnection(originalFunction, args);
|
|
12441
|
+
};
|
|
12442
|
+
});
|
|
12443
|
+
} else {
|
|
12444
|
+
logger.debug(`[PostgresInstrumentation] Module is a function (CJS style)`);
|
|
12445
|
+
const originalFunction = postgresModule;
|
|
12446
|
+
const wrappedFunction = function(...args) {
|
|
12447
|
+
logger.debug(`[PostgresInstrumentation] Wrapped postgres() (CJS) called with args:`, args);
|
|
12448
|
+
return self._handlePostgresConnection(originalFunction, args);
|
|
12449
|
+
};
|
|
12450
|
+
Object.setPrototypeOf(wrappedFunction, Object.getPrototypeOf(originalFunction));
|
|
12451
|
+
Object.defineProperty(wrappedFunction, "name", { value: originalFunction.name });
|
|
12452
|
+
for (const key in originalFunction) if (originalFunction.hasOwnProperty(key)) wrappedFunction[key] = originalFunction[key];
|
|
12453
|
+
Object.getOwnPropertyNames(originalFunction).forEach((key) => {
|
|
12454
|
+
if (key !== "prototype" && key !== "length" && key !== "name") {
|
|
12455
|
+
const descriptor = Object.getOwnPropertyDescriptor(originalFunction, key);
|
|
12456
|
+
if (descriptor) Object.defineProperty(wrappedFunction, key, descriptor);
|
|
12457
|
+
}
|
|
12458
|
+
});
|
|
12459
|
+
postgresModule = wrappedFunction;
|
|
12460
|
+
}
|
|
12461
|
+
if (postgresModule.sql && typeof postgresModule.sql === "function") {
|
|
12462
|
+
this._wrap(postgresModule, "sql", this._getSqlPatchFn());
|
|
12463
|
+
logger.debug(`[PostgresInstrumentation] Wrapped sql function`);
|
|
12464
|
+
}
|
|
12465
|
+
this.markModuleAsPatched(postgresModule);
|
|
12466
|
+
logger.debug(`[PostgresInstrumentation] Postgres module patching complete`);
|
|
12467
|
+
return postgresModule;
|
|
12468
|
+
}
|
|
12469
|
+
_handlePostgresConnection(originalFunction, args) {
|
|
12470
|
+
return this.connectionHandler.handlePostgresConnection(originalFunction, args);
|
|
12471
|
+
}
|
|
12466
12472
|
_wrapSqlInstance(sqlInstance) {
|
|
12467
12473
|
if (!sqlInstance || typeof sqlInstance !== "function") return sqlInstance;
|
|
12468
12474
|
const self = this;
|
|
@@ -12478,11 +12484,34 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12478
12484
|
logger.debug(`[PostgresInstrumentation] Wrapped unsafe method on sql instance`);
|
|
12479
12485
|
}
|
|
12480
12486
|
if (typeof originalSql.begin === "function") {
|
|
12481
|
-
|
|
12482
|
-
|
|
12487
|
+
const wrappedBegin = self._wrapBeginMethod(originalSql);
|
|
12488
|
+
originalSql.begin = wrappedBegin;
|
|
12489
|
+
wrappedSql.begin = wrappedBegin;
|
|
12490
|
+
}
|
|
12491
|
+
if (typeof originalSql.file === "function") {
|
|
12492
|
+
wrappedSql.file = self._wrapFileMethod(originalSql);
|
|
12493
|
+
logger.debug(`[PostgresInstrumentation] Wrapped file method on sql instance`);
|
|
12494
|
+
}
|
|
12495
|
+
if (typeof originalSql.reserve === "function") {
|
|
12496
|
+
wrappedSql.reserve = self._wrapReserveMethod(originalSql);
|
|
12497
|
+
logger.debug(`[PostgresInstrumentation] Wrapped reserve method on sql instance`);
|
|
12498
|
+
}
|
|
12499
|
+
if (typeof originalSql.listen === "function") {
|
|
12500
|
+
wrappedSql.listen = self._wrapListenMethod(originalSql);
|
|
12501
|
+
logger.debug(`[PostgresInstrumentation] Wrapped listen method on sql instance`);
|
|
12502
|
+
}
|
|
12503
|
+
if (typeof originalSql.notify === "function") {
|
|
12504
|
+
wrappedSql.notify = self._wrapNotifyMethod(wrappedSql);
|
|
12505
|
+
logger.debug(`[PostgresInstrumentation] Wrapped notify method on sql instance`);
|
|
12483
12506
|
}
|
|
12484
12507
|
return wrappedSql;
|
|
12485
12508
|
}
|
|
12509
|
+
_wrapNotifyMethod(wrappedSqlInstance) {
|
|
12510
|
+
return async function notify(channel, payload) {
|
|
12511
|
+
logger.debug(`[PostgresInstrumentation] notify() called for channel ${channel}`);
|
|
12512
|
+
return wrappedSqlInstance`select pg_notify(${channel}, ${String(payload)})`;
|
|
12513
|
+
};
|
|
12514
|
+
}
|
|
12486
12515
|
_wrapUnsafeMethod(sqlInstance) {
|
|
12487
12516
|
const self = this;
|
|
12488
12517
|
const originalUnsafe = sqlInstance.unsafe;
|
|
@@ -12499,9 +12528,178 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12499
12528
|
return self._handleBeginTransaction(sqlInstance, originalBegin, options, transactionCallback);
|
|
12500
12529
|
};
|
|
12501
12530
|
}
|
|
12502
|
-
|
|
12531
|
+
_wrapFileMethod(sqlInstance) {
|
|
12503
12532
|
const self = this;
|
|
12504
|
-
|
|
12533
|
+
const originalFile = sqlInstance.file;
|
|
12534
|
+
return function file(path$2, parameters, queryOptions) {
|
|
12535
|
+
return self._handleFileQuery(sqlInstance, originalFile, path$2, parameters, queryOptions);
|
|
12536
|
+
};
|
|
12537
|
+
}
|
|
12538
|
+
_wrapReserveMethod(sqlInstance) {
|
|
12539
|
+
const self = this;
|
|
12540
|
+
const originalReserve = sqlInstance.reserve;
|
|
12541
|
+
return async function reserve() {
|
|
12542
|
+
if (self.mode === TuskDriftMode.REPLAY) {
|
|
12543
|
+
logger.debug(`[PostgresInstrumentation] REPLAY mode: Creating mock reserved connection without TCP`);
|
|
12544
|
+
const mockReservedSql = self._wrapSqlInstance(sqlInstance);
|
|
12545
|
+
if (typeof mockReservedSql === "function") mockReservedSql.release = function() {
|
|
12546
|
+
logger.debug(`[PostgresInstrumentation] Mock reserved connection released`);
|
|
12547
|
+
};
|
|
12548
|
+
return mockReservedSql;
|
|
12549
|
+
}
|
|
12550
|
+
const reservedSql = await originalReserve.call(sqlInstance);
|
|
12551
|
+
const wrappedReservedSql = self._wrapSqlInstance(reservedSql);
|
|
12552
|
+
logger.debug(`[PostgresInstrumentation] Reserved connection obtained and wrapped`);
|
|
12553
|
+
return wrappedReservedSql;
|
|
12554
|
+
};
|
|
12555
|
+
}
|
|
12556
|
+
_wrapListenMethod(sqlInstance) {
|
|
12557
|
+
const self = this;
|
|
12558
|
+
const originalListen = sqlInstance.listen;
|
|
12559
|
+
return async function listen(channelName, callback, onlisten) {
|
|
12560
|
+
return self._handleListenMethod(sqlInstance, originalListen, channelName, callback, onlisten);
|
|
12561
|
+
};
|
|
12562
|
+
}
|
|
12563
|
+
async _handleListenMethod(sqlInstance, originalListen, channelName, callback, onlisten) {
|
|
12564
|
+
const inputValue = {
|
|
12565
|
+
operation: "listen",
|
|
12566
|
+
channel: channelName
|
|
12567
|
+
};
|
|
12568
|
+
if (this.mode === TuskDriftMode.REPLAY) return this._handleReplayListen(channelName, callback, onlisten, inputValue);
|
|
12569
|
+
else if (this.mode === TuskDriftMode.RECORD) return this._handleRecordListen(sqlInstance, originalListen, channelName, callback, onlisten, inputValue);
|
|
12570
|
+
else return originalListen.call(sqlInstance, channelName, callback, onlisten);
|
|
12571
|
+
}
|
|
12572
|
+
async _handleRecordListen(sqlInstance, originalListen, channelName, callback, onlisten, inputValue) {
|
|
12573
|
+
const receivedPayloads = [];
|
|
12574
|
+
const wrappedCallback = (payload) => {
|
|
12575
|
+
logger.debug(`[PostgresInstrumentation] RECORD: Captured notification payload on channel ${channelName}: ${payload}`);
|
|
12576
|
+
receivedPayloads.push(payload);
|
|
12577
|
+
callback(payload);
|
|
12578
|
+
};
|
|
12579
|
+
return handleRecordMode({
|
|
12580
|
+
originalFunctionCall: () => originalListen.call(sqlInstance, channelName, callback, onlisten),
|
|
12581
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
12582
|
+
return SpanUtils.createAndExecuteSpan(this.mode, () => originalListen.call(sqlInstance, channelName, callback, onlisten), {
|
|
12583
|
+
name: "postgres.listen",
|
|
12584
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
12585
|
+
submodule: "listen",
|
|
12586
|
+
packageType: PackageType.PG,
|
|
12587
|
+
packageName: "postgres",
|
|
12588
|
+
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12589
|
+
inputValue,
|
|
12590
|
+
isPreAppStart
|
|
12591
|
+
}, async (spanInfo) => {
|
|
12592
|
+
try {
|
|
12593
|
+
const result = await originalListen.call(sqlInstance, channelName, wrappedCallback, onlisten);
|
|
12594
|
+
try {
|
|
12595
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12596
|
+
channel: channelName,
|
|
12597
|
+
state: result.state
|
|
12598
|
+
} });
|
|
12599
|
+
} catch (error) {
|
|
12600
|
+
logger.error(`[PostgresInstrumentation] error adding span attributes:`, error);
|
|
12601
|
+
}
|
|
12602
|
+
const originalUnlisten = result.unlisten;
|
|
12603
|
+
const wrappedUnlisten = async () => {
|
|
12604
|
+
logger.debug(`[PostgresInstrumentation] RECORD: Unlisten called, captured ${receivedPayloads.length} payloads`);
|
|
12605
|
+
try {
|
|
12606
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12607
|
+
channel: channelName,
|
|
12608
|
+
state: result.state,
|
|
12609
|
+
payloads: receivedPayloads
|
|
12610
|
+
} });
|
|
12611
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12612
|
+
} catch (error) {
|
|
12613
|
+
logger.error(`[PostgresInstrumentation] error adding span attributes:`, error);
|
|
12614
|
+
}
|
|
12615
|
+
return originalUnlisten();
|
|
12616
|
+
};
|
|
12617
|
+
return {
|
|
12618
|
+
state: result.state,
|
|
12619
|
+
unlisten: wrappedUnlisten
|
|
12620
|
+
};
|
|
12621
|
+
} catch (error) {
|
|
12622
|
+
logger.error(`[PostgresInstrumentation] RECORD listen error: ${error.message}`);
|
|
12623
|
+
try {
|
|
12624
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
12625
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
12626
|
+
message: error.message
|
|
12627
|
+
});
|
|
12628
|
+
} catch (error$1) {
|
|
12629
|
+
logger.error(`[PostgresInstrumentation] error ending span:`, error$1);
|
|
12630
|
+
}
|
|
12631
|
+
throw error;
|
|
12632
|
+
}
|
|
12633
|
+
});
|
|
12634
|
+
},
|
|
12635
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
12636
|
+
});
|
|
12637
|
+
}
|
|
12638
|
+
async _handleReplayListen(channelName, callback, onlisten, inputValue) {
|
|
12639
|
+
logger.debug(`[PostgresInstrumentation] REPLAY: Mocking listen for channel ${channelName} without TCP`);
|
|
12640
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
12641
|
+
return handleReplayMode({
|
|
12642
|
+
noOpRequestHandler: () => Promise.resolve({
|
|
12643
|
+
state: { state: "I" },
|
|
12644
|
+
unlisten: async () => {}
|
|
12645
|
+
}),
|
|
12646
|
+
isServerRequest: false,
|
|
12647
|
+
replayModeHandler: () => {
|
|
12648
|
+
return SpanUtils.createAndExecuteSpan(this.mode, () => Promise.resolve({
|
|
12649
|
+
state: { state: "I" },
|
|
12650
|
+
unlisten: async () => {}
|
|
12651
|
+
}), {
|
|
12652
|
+
name: "postgres.listen",
|
|
12653
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
12654
|
+
submodule: "listen",
|
|
12655
|
+
packageType: PackageType.PG,
|
|
12656
|
+
packageName: "postgres",
|
|
12657
|
+
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12658
|
+
inputValue,
|
|
12659
|
+
isPreAppStart: this.tuskDrift.isAppReady() ? false : true
|
|
12660
|
+
}, async (spanInfo) => {
|
|
12661
|
+
try {
|
|
12662
|
+
const mockData = await this._findMockData({
|
|
12663
|
+
spanInfo,
|
|
12664
|
+
name: "postgres.listen",
|
|
12665
|
+
inputValue,
|
|
12666
|
+
submoduleName: "listen",
|
|
12667
|
+
stackTrace
|
|
12668
|
+
});
|
|
12669
|
+
if (!mockData) {
|
|
12670
|
+
logger.warn(`[PostgresInstrumentation] No mock data found for listen channel: ${channelName}`);
|
|
12671
|
+
throw new Error(`No mock data found for listen channel: ${channelName}`);
|
|
12672
|
+
}
|
|
12673
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for listen: ${JSON.stringify(mockData)}`);
|
|
12674
|
+
const recordedPayloads = mockData.result?.payloads || [];
|
|
12675
|
+
const recordedState = mockData.result?.state || { state: "I" };
|
|
12676
|
+
if (onlisten) onlisten();
|
|
12677
|
+
for (const payload of recordedPayloads) {
|
|
12678
|
+
logger.debug(`[PostgresInstrumentation] REPLAY: Invoking callback with recorded payload: ${payload}`);
|
|
12679
|
+
callback(payload);
|
|
12680
|
+
}
|
|
12681
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12682
|
+
return {
|
|
12683
|
+
state: recordedState,
|
|
12684
|
+
unlisten: async () => {
|
|
12685
|
+
logger.debug(`[PostgresInstrumentation] REPLAY: Mock unlisten called`);
|
|
12686
|
+
}
|
|
12687
|
+
};
|
|
12688
|
+
} catch (error) {
|
|
12689
|
+
logger.error(`[PostgresInstrumentation] REPLAY listen error: ${error.message}`);
|
|
12690
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
12691
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
12692
|
+
message: error.message
|
|
12693
|
+
});
|
|
12694
|
+
throw error;
|
|
12695
|
+
}
|
|
12696
|
+
});
|
|
12697
|
+
}
|
|
12698
|
+
});
|
|
12699
|
+
}
|
|
12700
|
+
_getSqlPatchFn() {
|
|
12701
|
+
const self = this;
|
|
12702
|
+
return (originalSql) => {
|
|
12505
12703
|
return function sql(strings, ...values) {
|
|
12506
12704
|
return self._handleSqlQuery(originalSql, strings, values);
|
|
12507
12705
|
};
|
|
@@ -12511,93 +12709,19 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12511
12709
|
if (!strings || !Array.isArray(strings.raw)) return originalSql.call(this, strings, ...values);
|
|
12512
12710
|
const creationContext = import_src$25.context.active();
|
|
12513
12711
|
const query = originalSql.call(this, strings, ...values);
|
|
12514
|
-
const
|
|
12515
|
-
|
|
12516
|
-
|
|
12517
|
-
let queryString = "";
|
|
12518
|
-
for (let i = 0; i < strings.length; i++) {
|
|
12519
|
-
queryString += strings[i];
|
|
12520
|
-
if (i < values.length) queryString += `$${i + 1}`;
|
|
12521
|
-
}
|
|
12522
|
-
const inputValue = {
|
|
12523
|
-
query: queryString.trim(),
|
|
12524
|
-
parameters: values
|
|
12525
|
-
};
|
|
12526
|
-
return import_src$25.context.with(creationContext, () => {
|
|
12527
|
-
if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
12528
|
-
originalFunctionCall: () => originalThen(onFulfilled, onRejected),
|
|
12529
|
-
recordModeHandler: ({ isPreAppStart }) => {
|
|
12530
|
-
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12531
|
-
name: "postgres.query",
|
|
12532
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12533
|
-
submodule: "query",
|
|
12534
|
-
packageType: PackageType.PG,
|
|
12535
|
-
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
12536
|
-
packageName: "postgres",
|
|
12537
|
-
inputValue,
|
|
12538
|
-
isPreAppStart
|
|
12539
|
-
}, (spanInfo) => {
|
|
12540
|
-
const wrappedOnFulfilled = (result) => {
|
|
12541
|
-
try {
|
|
12542
|
-
logger.debug(`[PostgresInstrumentation] Postgres query completed successfully`, result);
|
|
12543
|
-
self._addOutputAttributesToSpan(spanInfo, result);
|
|
12544
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12545
|
-
} catch (error) {
|
|
12546
|
-
logger.error(`[PostgresInstrumentation] error processing query response:`, error);
|
|
12547
|
-
}
|
|
12548
|
-
return onFulfilled ? onFulfilled(result) : result;
|
|
12549
|
-
};
|
|
12550
|
-
const wrappedOnRejected = (error) => {
|
|
12551
|
-
try {
|
|
12552
|
-
logger.debug(`[PostgresInstrumentation] Postgres query error`, error);
|
|
12553
|
-
SpanUtils.endSpan(spanInfo.span, {
|
|
12554
|
-
code: import_src$25.SpanStatusCode.ERROR,
|
|
12555
|
-
message: error.message
|
|
12556
|
-
});
|
|
12557
|
-
} catch (spanError) {
|
|
12558
|
-
logger.error(`[PostgresInstrumentation] error ending span:`, spanError);
|
|
12559
|
-
}
|
|
12560
|
-
if (onRejected) return onRejected(error);
|
|
12561
|
-
throw error;
|
|
12562
|
-
};
|
|
12563
|
-
return originalThen(wrappedOnFulfilled, wrappedOnRejected);
|
|
12564
|
-
});
|
|
12565
|
-
},
|
|
12566
|
-
spanKind: import_src$25.SpanKind.CLIENT
|
|
12567
|
-
});
|
|
12568
|
-
else if (self.mode === TuskDriftMode.REPLAY) {
|
|
12569
|
-
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
12570
|
-
return handleReplayMode({
|
|
12571
|
-
noOpRequestHandler: () => Promise.resolve(Object.assign([], {
|
|
12572
|
-
count: 0,
|
|
12573
|
-
command: null
|
|
12574
|
-
})),
|
|
12575
|
-
isServerRequest: false,
|
|
12576
|
-
replayModeHandler: () => {
|
|
12577
|
-
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12578
|
-
name: "postgres.query",
|
|
12579
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12580
|
-
submodule: "query",
|
|
12581
|
-
packageType: PackageType.PG,
|
|
12582
|
-
packageName: "postgres",
|
|
12583
|
-
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
12584
|
-
inputValue,
|
|
12585
|
-
isPreAppStart: false
|
|
12586
|
-
}, async (spanInfo) => {
|
|
12587
|
-
const mockedResult = await self.handleReplaySqlQuery({
|
|
12588
|
-
inputValue,
|
|
12589
|
-
spanInfo,
|
|
12590
|
-
submodule: "query",
|
|
12591
|
-
name: "postgres.query",
|
|
12592
|
-
stackTrace
|
|
12593
|
-
});
|
|
12594
|
-
return onFulfilled ? onFulfilled(mockedResult) : mockedResult;
|
|
12595
|
-
});
|
|
12596
|
-
}
|
|
12597
|
-
});
|
|
12598
|
-
} else return originalThen(onFulfilled, onRejected);
|
|
12599
|
-
});
|
|
12712
|
+
const inputValue = {
|
|
12713
|
+
query: reconstructQueryString(strings, values).trim(),
|
|
12714
|
+
parameters: values
|
|
12600
12715
|
};
|
|
12716
|
+
const originalThen = query.then.bind(query);
|
|
12717
|
+
this._wrapThenMethod(query, originalThen, inputValue, creationContext, {
|
|
12718
|
+
name: "postgres.query",
|
|
12719
|
+
submodule: "query",
|
|
12720
|
+
operationType: "sql"
|
|
12721
|
+
});
|
|
12722
|
+
this._wrapExecuteMethod(query);
|
|
12723
|
+
this._wrapCursorMethod(query, inputValue, creationContext);
|
|
12724
|
+
this._wrapForEachMethod(query, inputValue, creationContext);
|
|
12601
12725
|
return query;
|
|
12602
12726
|
}
|
|
12603
12727
|
_handleUnsafeQuery(sqlInstance, originalUnsafe, query, parameters, queryOptions) {
|
|
@@ -12608,21 +12732,46 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12608
12732
|
})();
|
|
12609
12733
|
const creationContext = import_src$25.context.active();
|
|
12610
12734
|
const originalThen = unsafeQuery.then.bind(unsafeQuery);
|
|
12611
|
-
const self = this;
|
|
12612
12735
|
const inputValue = {
|
|
12613
12736
|
query: query.trim(),
|
|
12614
12737
|
parameters: parameters || [],
|
|
12615
12738
|
options: queryOptions
|
|
12616
12739
|
};
|
|
12617
|
-
unsafeQuery
|
|
12740
|
+
this._wrapThenMethod(unsafeQuery, originalThen, inputValue, creationContext, {
|
|
12741
|
+
name: "postgres.unsafe",
|
|
12742
|
+
submodule: "unsafe",
|
|
12743
|
+
operationType: "unsafe"
|
|
12744
|
+
});
|
|
12745
|
+
this._wrapExecuteMethod(unsafeQuery);
|
|
12746
|
+
this._wrapCursorMethod(unsafeQuery, inputValue, creationContext);
|
|
12747
|
+
this._wrapForEachMethod(unsafeQuery, inputValue, creationContext);
|
|
12748
|
+
return unsafeQuery;
|
|
12749
|
+
}
|
|
12750
|
+
_handleFileQuery(sqlInstance, originalFile, path$2, parameters, queryOptions) {
|
|
12751
|
+
const fileQuery = (() => {
|
|
12752
|
+
if (queryOptions !== void 0) return originalFile.call(sqlInstance, path$2, parameters, queryOptions);
|
|
12753
|
+
else if (parameters !== void 0) return originalFile.call(sqlInstance, path$2, parameters);
|
|
12754
|
+
else return originalFile.call(sqlInstance, path$2);
|
|
12755
|
+
})();
|
|
12756
|
+
const creationContext = import_src$25.context.active();
|
|
12757
|
+
const originalThen = fileQuery.then.bind(fileQuery);
|
|
12758
|
+
const self = this;
|
|
12759
|
+
const inputValue = {
|
|
12760
|
+
query: path$2,
|
|
12761
|
+
parameters: parameters || [],
|
|
12762
|
+
options: queryOptions
|
|
12763
|
+
};
|
|
12764
|
+
fileQuery.then = function(onFulfilled, onRejected) {
|
|
12765
|
+
if (fileQuery._tuskRecorded) return originalThen(onFulfilled, onRejected);
|
|
12766
|
+
fileQuery._tuskRecorded = true;
|
|
12618
12767
|
return import_src$25.context.with(creationContext, () => {
|
|
12619
12768
|
if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
12620
12769
|
originalFunctionCall: () => originalThen(onFulfilled, onRejected),
|
|
12621
12770
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
12622
12771
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12623
|
-
name: "postgres.
|
|
12772
|
+
name: "postgres.file",
|
|
12624
12773
|
kind: import_src$25.SpanKind.CLIENT,
|
|
12625
|
-
submodule: "
|
|
12774
|
+
submodule: "file",
|
|
12626
12775
|
packageType: PackageType.PG,
|
|
12627
12776
|
packageName: "postgres",
|
|
12628
12777
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -12631,17 +12780,17 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12631
12780
|
}, (spanInfo) => {
|
|
12632
12781
|
const wrappedOnFulfilled = (result) => {
|
|
12633
12782
|
try {
|
|
12634
|
-
logger.debug(`[PostgresInstrumentation] Postgres
|
|
12635
|
-
|
|
12783
|
+
logger.debug(`[PostgresInstrumentation] Postgres file query completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12784
|
+
addOutputAttributesToSpan(spanInfo, result);
|
|
12636
12785
|
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12637
12786
|
} catch (error) {
|
|
12638
|
-
logger.error(`[PostgresInstrumentation] error processing
|
|
12787
|
+
logger.error(`[PostgresInstrumentation] error processing file query response:`, error);
|
|
12639
12788
|
}
|
|
12640
12789
|
return onFulfilled ? onFulfilled(result) : result;
|
|
12641
12790
|
};
|
|
12642
12791
|
const wrappedOnRejected = (error) => {
|
|
12643
12792
|
try {
|
|
12644
|
-
logger.debug(`[PostgresInstrumentation] Postgres
|
|
12793
|
+
logger.debug(`[PostgresInstrumentation] Postgres file query error: ${error.message}`);
|
|
12645
12794
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12646
12795
|
code: import_src$25.SpanStatusCode.ERROR,
|
|
12647
12796
|
message: error.message
|
|
@@ -12667,22 +12816,24 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12667
12816
|
isServerRequest: false,
|
|
12668
12817
|
replayModeHandler: () => {
|
|
12669
12818
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12670
|
-
name: "postgres.
|
|
12819
|
+
name: "postgres.file",
|
|
12671
12820
|
kind: import_src$25.SpanKind.CLIENT,
|
|
12672
|
-
submodule: "
|
|
12821
|
+
submodule: "file",
|
|
12673
12822
|
packageType: PackageType.PG,
|
|
12674
12823
|
packageName: "postgres",
|
|
12675
12824
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
12676
12825
|
inputValue,
|
|
12677
|
-
isPreAppStart: false
|
|
12826
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
12678
12827
|
}, async (spanInfo) => {
|
|
12679
|
-
const mockedResult = await self.
|
|
12828
|
+
const mockedResult = await self._handleReplayQueryOperation({
|
|
12680
12829
|
inputValue,
|
|
12681
12830
|
spanInfo,
|
|
12682
|
-
submodule: "
|
|
12683
|
-
name: "postgres.
|
|
12684
|
-
stackTrace
|
|
12831
|
+
submodule: "file",
|
|
12832
|
+
name: "postgres.file",
|
|
12833
|
+
stackTrace,
|
|
12834
|
+
operationType: "file"
|
|
12685
12835
|
});
|
|
12836
|
+
if (!mockedResult) throw new Error(`No mock data found for Postgres file query: ${inputValue.query}`);
|
|
12686
12837
|
return onFulfilled ? onFulfilled(mockedResult) : mockedResult;
|
|
12687
12838
|
});
|
|
12688
12839
|
}
|
|
@@ -12690,16 +12841,45 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12690
12841
|
} else return originalThen(onFulfilled, onRejected);
|
|
12691
12842
|
});
|
|
12692
12843
|
};
|
|
12693
|
-
|
|
12844
|
+
const originalExecute = fileQuery.execute ? fileQuery.execute.bind(fileQuery) : void 0;
|
|
12845
|
+
if (originalExecute) fileQuery.execute = function() {
|
|
12846
|
+
if (self.mode === TuskDriftMode.REPLAY) return this;
|
|
12847
|
+
else return originalExecute.call(this);
|
|
12848
|
+
};
|
|
12849
|
+
return fileQuery;
|
|
12850
|
+
}
|
|
12851
|
+
/**
|
|
12852
|
+
* Wraps a transaction callback to ensure the inner SQL instance is instrumented.
|
|
12853
|
+
* This is necessary because postgres.js creates a new SQL instance inside begin()
|
|
12854
|
+
* that would otherwise bypass instrumentation.
|
|
12855
|
+
*/
|
|
12856
|
+
_wrapTransactionCallback(transactionCallback) {
|
|
12857
|
+
const self = this;
|
|
12858
|
+
return (transactionSql) => {
|
|
12859
|
+
const wrappedSql = self._wrapSqlInstance(transactionSql);
|
|
12860
|
+
if (typeof transactionSql.savepoint === "function") {
|
|
12861
|
+
const originalSavepoint = transactionSql.savepoint;
|
|
12862
|
+
wrappedSql.savepoint = function(nameOrFn, fn) {
|
|
12863
|
+
const savepointCallback = typeof nameOrFn === "function" ? nameOrFn : fn;
|
|
12864
|
+
const savepointName = typeof nameOrFn === "string" ? nameOrFn : void 0;
|
|
12865
|
+
const wrappedSavepointCallback = self._wrapTransactionCallback(savepointCallback);
|
|
12866
|
+
if (savepointName) return originalSavepoint.call(transactionSql, savepointName, wrappedSavepointCallback);
|
|
12867
|
+
else return originalSavepoint.call(transactionSql, wrappedSavepointCallback);
|
|
12868
|
+
};
|
|
12869
|
+
}
|
|
12870
|
+
if (typeof transactionSql.prepare === "function") wrappedSql.prepare = transactionSql.prepare.bind(transactionSql);
|
|
12871
|
+
return transactionCallback(wrappedSql);
|
|
12872
|
+
};
|
|
12694
12873
|
}
|
|
12695
12874
|
_handleBeginTransaction(sqlInstance, originalBegin, options, transactionCallback) {
|
|
12696
12875
|
const inputValue = {
|
|
12697
12876
|
query: "BEGIN",
|
|
12698
12877
|
options: options ? { transactionOptions: options } : void 0
|
|
12699
12878
|
};
|
|
12879
|
+
const wrappedCallback = transactionCallback ? this._wrapTransactionCallback(transactionCallback) : void 0;
|
|
12700
12880
|
const executeBegin = () => {
|
|
12701
|
-
if (options &&
|
|
12702
|
-
else if (
|
|
12881
|
+
if (options && wrappedCallback) return originalBegin.call(sqlInstance, options, wrappedCallback);
|
|
12882
|
+
else if (wrappedCallback) return originalBegin.call(sqlInstance, wrappedCallback);
|
|
12703
12883
|
else return originalBegin.call(sqlInstance, options || void 0);
|
|
12704
12884
|
};
|
|
12705
12885
|
if (this.mode === TuskDriftMode.REPLAY) {
|
|
@@ -12716,9 +12896,9 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12716
12896
|
packageName: "postgres",
|
|
12717
12897
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12718
12898
|
inputValue,
|
|
12719
|
-
isPreAppStart: false
|
|
12899
|
+
isPreAppStart: this.tuskDrift.isAppReady() ? false : true
|
|
12720
12900
|
}, (spanInfo) => {
|
|
12721
|
-
return this._handleReplayBeginTransaction(spanInfo, options, stackTrace);
|
|
12901
|
+
return this._handleReplayBeginTransaction(spanInfo, options, stackTrace, wrappedCallback);
|
|
12722
12902
|
});
|
|
12723
12903
|
}
|
|
12724
12904
|
});
|
|
@@ -12743,55 +12923,47 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12743
12923
|
else return executeBegin();
|
|
12744
12924
|
}
|
|
12745
12925
|
_handleRecordBeginTransaction(spanInfo, executeBegin) {
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12750
|
-
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12773
|
-
});
|
|
12926
|
+
return executeBegin().then((result) => {
|
|
12927
|
+
logger.debug(`[PostgresInstrumentation] Postgres transaction completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12928
|
+
try {
|
|
12929
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12930
|
+
status: "committed",
|
|
12931
|
+
result
|
|
12932
|
+
} });
|
|
12933
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12934
|
+
} catch (error) {
|
|
12935
|
+
logger.error(`[PostgresInstrumentation] error processing transaction response:`, error);
|
|
12936
|
+
}
|
|
12937
|
+
return result;
|
|
12938
|
+
}).catch((error) => {
|
|
12939
|
+
logger.debug(`[PostgresInstrumentation] Postgres transaction error (rolled back): ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12940
|
+
try {
|
|
12941
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12942
|
+
status: "rolled_back",
|
|
12943
|
+
error: error.message
|
|
12944
|
+
} });
|
|
12945
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
12946
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
12947
|
+
message: error.message
|
|
12948
|
+
});
|
|
12949
|
+
} catch (spanError) {
|
|
12950
|
+
logger.error(`[PostgresInstrumentation] error ending span:`, spanError);
|
|
12951
|
+
}
|
|
12952
|
+
throw error;
|
|
12774
12953
|
});
|
|
12775
|
-
return promise;
|
|
12776
12954
|
}
|
|
12777
|
-
async _handleReplayBeginTransaction(spanInfo, options, stackTrace) {
|
|
12955
|
+
async _handleReplayBeginTransaction(spanInfo, options, stackTrace, wrappedCallback) {
|
|
12778
12956
|
logger.debug(`[PostgresInstrumentation] Replaying Postgres transaction`);
|
|
12779
|
-
const
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
12784
|
-
|
|
12785
|
-
|
|
12786
|
-
|
|
12787
|
-
|
|
12788
|
-
|
|
12789
|
-
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12790
|
-
submoduleName: "transaction",
|
|
12791
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12792
|
-
stackTrace
|
|
12793
|
-
},
|
|
12794
|
-
tuskDrift: this.tuskDrift
|
|
12957
|
+
const transactionInputValue = {
|
|
12958
|
+
query: "BEGIN",
|
|
12959
|
+
options: options ? { transactionOptions: options } : void 0
|
|
12960
|
+
};
|
|
12961
|
+
const mockData = await this._findMockData({
|
|
12962
|
+
spanInfo,
|
|
12963
|
+
name: "postgres.begin",
|
|
12964
|
+
inputValue: transactionInputValue,
|
|
12965
|
+
submoduleName: "transaction",
|
|
12966
|
+
stackTrace
|
|
12795
12967
|
});
|
|
12796
12968
|
if (!mockData) {
|
|
12797
12969
|
logger.warn(`[PostgresInstrumentation] No mock data found for transaction BEGIN`);
|
|
@@ -12799,15 +12971,49 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12799
12971
|
}
|
|
12800
12972
|
logger.debug(`[PostgresInstrumentation] Found mock data for transaction: ${JSON.stringify(mockData)}`);
|
|
12801
12973
|
const transactionResult = mockData.result;
|
|
12802
|
-
|
|
12974
|
+
const wasCommitted = transactionResult && typeof transactionResult === "object" && "status" in transactionResult && transactionResult.status === "committed";
|
|
12975
|
+
if (!wrappedCallback) if (wasCommitted) return transactionResult.result;
|
|
12803
12976
|
else {
|
|
12804
12977
|
const errorMessage = transactionResult && typeof transactionResult === "object" && "error" in transactionResult && transactionResult.error ? transactionResult.error : "Transaction rolled back";
|
|
12805
12978
|
throw new Error(errorMessage);
|
|
12806
12979
|
}
|
|
12980
|
+
try {
|
|
12981
|
+
const result = await wrappedCallback(this._createMockTransactionSql());
|
|
12982
|
+
logger.debug(`[PostgresInstrumentation] Replay transaction callback completed with result`);
|
|
12983
|
+
return result;
|
|
12984
|
+
} catch (error) {
|
|
12985
|
+
if (!wasCommitted) throw error;
|
|
12986
|
+
logger.error(`[PostgresInstrumentation] Unexpected error during transaction replay: ${error.message}`);
|
|
12987
|
+
throw error;
|
|
12988
|
+
}
|
|
12807
12989
|
}
|
|
12808
|
-
|
|
12809
|
-
|
|
12810
|
-
|
|
12990
|
+
/**
|
|
12991
|
+
* Creates a minimal mock SQL instance for transaction replay.
|
|
12992
|
+
* _wrapSqlInstance will wrap this and handle all the actual REPLAY logic.
|
|
12993
|
+
* The mock just needs to return objects with .then() methods that can be wrapped.
|
|
12994
|
+
*/
|
|
12995
|
+
_createMockTransactionSql() {
|
|
12996
|
+
const self = this;
|
|
12997
|
+
const createThenable = () => ({ then: (onFulfilled, onRejected) => Promise.resolve([]).then(onFulfilled, onRejected) });
|
|
12998
|
+
const mockSql = function() {
|
|
12999
|
+
return createThenable();
|
|
13000
|
+
};
|
|
13001
|
+
mockSql.unsafe = function() {
|
|
13002
|
+
return createThenable();
|
|
13003
|
+
};
|
|
13004
|
+
mockSql.savepoint = function(nameOrFn, fn) {
|
|
13005
|
+
const callback = typeof nameOrFn === "function" ? nameOrFn : fn;
|
|
13006
|
+
const nestedMockSql = self._createMockTransactionSql();
|
|
13007
|
+
return Promise.resolve(callback(nestedMockSql));
|
|
13008
|
+
};
|
|
13009
|
+
return mockSql;
|
|
13010
|
+
}
|
|
13011
|
+
/**
|
|
13012
|
+
* Generic helper to find mock data for replay operations.
|
|
13013
|
+
* Consolidates the common findMockResponseAsync pattern used across multiple handlers.
|
|
13014
|
+
*/
|
|
13015
|
+
async _findMockData({ spanInfo, name, inputValue, submoduleName, stackTrace }) {
|
|
13016
|
+
return findMockResponseAsync({
|
|
12811
13017
|
mockRequestData: {
|
|
12812
13018
|
traceId: spanInfo.traceId,
|
|
12813
13019
|
spanId: spanInfo.spanId,
|
|
@@ -12815,79 +13021,574 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12815
13021
|
inputValue: createMockInputValue(inputValue),
|
|
12816
13022
|
packageName: "postgres",
|
|
12817
13023
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12818
|
-
submoduleName
|
|
13024
|
+
submoduleName,
|
|
12819
13025
|
kind: import_src$25.SpanKind.CLIENT,
|
|
12820
13026
|
stackTrace
|
|
12821
13027
|
},
|
|
12822
13028
|
tuskDrift: this.tuskDrift
|
|
12823
13029
|
});
|
|
13030
|
+
}
|
|
13031
|
+
/**
|
|
13032
|
+
* Helper to end a cursor span with collected rows.
|
|
13033
|
+
* Consolidates common span ending logic used in cursor and forEach operations.
|
|
13034
|
+
*/
|
|
13035
|
+
_endCursorSpan(spanInfo, allRows, result, operation = "Cursor") {
|
|
13036
|
+
addOutputAttributesToSpan(spanInfo, Object.assign(allRows, {
|
|
13037
|
+
count: allRows.length,
|
|
13038
|
+
columns: result?.columns,
|
|
13039
|
+
state: result?.state,
|
|
13040
|
+
statement: result?.statement
|
|
13041
|
+
}));
|
|
13042
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13043
|
+
logger.debug(`[PostgresInstrumentation] ${operation} completed, recorded ${allRows.length} rows`);
|
|
13044
|
+
}
|
|
13045
|
+
/**
|
|
13046
|
+
* Generic helper to handle replay for query operations (sql, unsafe, file).
|
|
13047
|
+
* Consolidates common logic for finding mock data and processing results.
|
|
13048
|
+
*/
|
|
13049
|
+
async _handleReplayQueryOperation({ inputValue, spanInfo, submodule, name, stackTrace, operationType }) {
|
|
13050
|
+
logger.debug(`[PostgresInstrumentation] Replaying Postgres ${operationType} query`);
|
|
13051
|
+
const mockData = await this._findMockData({
|
|
13052
|
+
spanInfo,
|
|
13053
|
+
name,
|
|
13054
|
+
inputValue,
|
|
13055
|
+
submoduleName: submodule,
|
|
13056
|
+
stackTrace
|
|
13057
|
+
});
|
|
12824
13058
|
if (!mockData) {
|
|
12825
|
-
const
|
|
12826
|
-
logger.warn(
|
|
12827
|
-
throw new Error(
|
|
13059
|
+
const errorMsg = `[PostgresInstrumentation] No matching mock found for Postgres ${operationType} query: ${inputValue.query || "UNKNOWN_QUERY"}`;
|
|
13060
|
+
logger.warn(errorMsg);
|
|
13061
|
+
throw new Error(errorMsg);
|
|
12828
13062
|
}
|
|
12829
|
-
logger.debug(`[PostgresInstrumentation] Found mock data for Postgres
|
|
12830
|
-
const processedResult =
|
|
12831
|
-
logger.debug(`[PostgresInstrumentation]
|
|
13063
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for Postgres ${operationType} query: ${JSON.stringify(mockData)}`);
|
|
13064
|
+
const processedResult = convertPostgresTypes(mockData.result);
|
|
13065
|
+
logger.debug(`[PostgresInstrumentation] ${operationType} query processed result: ${JSON.stringify(processedResult)}`);
|
|
12832
13066
|
return processedResult;
|
|
12833
13067
|
}
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
12837
|
-
|
|
12838
|
-
|
|
12839
|
-
|
|
12840
|
-
|
|
12841
|
-
|
|
12842
|
-
|
|
12843
|
-
|
|
12844
|
-
|
|
12845
|
-
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
13068
|
+
_handleCursorCallbackRecord({ originalCursor, rows, inputValue, creationContext, userCallback }) {
|
|
13069
|
+
const self = this;
|
|
13070
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13071
|
+
return handleRecordMode({
|
|
13072
|
+
originalFunctionCall: () => originalCursor(rows, userCallback),
|
|
13073
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
13074
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalCursor(rows, userCallback), {
|
|
13075
|
+
name: "postgres.cursor",
|
|
13076
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13077
|
+
submodule: "cursor",
|
|
13078
|
+
packageType: PackageType.PG,
|
|
13079
|
+
packageName: "postgres",
|
|
13080
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13081
|
+
inputValue,
|
|
13082
|
+
isPreAppStart
|
|
13083
|
+
}, (spanInfo) => {
|
|
13084
|
+
return self._executeAndRecordCursorCallback({
|
|
13085
|
+
originalCursor,
|
|
13086
|
+
rows,
|
|
13087
|
+
userCallback,
|
|
13088
|
+
spanInfo
|
|
13089
|
+
});
|
|
13090
|
+
});
|
|
13091
|
+
},
|
|
13092
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
13093
|
+
});
|
|
13094
|
+
});
|
|
13095
|
+
}
|
|
13096
|
+
async _executeAndRecordCursorCallback({ originalCursor, rows, userCallback, spanInfo }) {
|
|
13097
|
+
const allRows = [];
|
|
13098
|
+
try {
|
|
13099
|
+
const wrappedCallback = (batchRows) => {
|
|
13100
|
+
allRows.push(...batchRows);
|
|
13101
|
+
return userCallback(batchRows);
|
|
13102
|
+
};
|
|
13103
|
+
const cursorPromise = originalCursor(rows, wrappedCallback);
|
|
13104
|
+
cursorPromise._tuskRecorded = true;
|
|
13105
|
+
const result = await cursorPromise;
|
|
13106
|
+
if (spanInfo) try {
|
|
13107
|
+
this._endCursorSpan(spanInfo, allRows, result, "Cursor callback");
|
|
13108
|
+
} catch (error) {
|
|
13109
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13110
|
+
}
|
|
13111
|
+
} catch (error) {
|
|
13112
|
+
logger.debug(`[PostgresInstrumentation] Cursor callback error: ${error.message}`);
|
|
13113
|
+
if (spanInfo) try {
|
|
13114
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13115
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13116
|
+
message: error.message
|
|
13117
|
+
});
|
|
13118
|
+
} catch (error$1) {
|
|
13119
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error$1);
|
|
13120
|
+
}
|
|
13121
|
+
throw error;
|
|
13122
|
+
}
|
|
13123
|
+
}
|
|
13124
|
+
_handleCursorCallbackReplay({ inputValue, creationContext, cursorBatchSize, userCallback }) {
|
|
13125
|
+
const self = this;
|
|
13126
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13127
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13128
|
+
return handleReplayMode({
|
|
13129
|
+
noOpRequestHandler: () => Promise.resolve(),
|
|
13130
|
+
isServerRequest: false,
|
|
13131
|
+
replayModeHandler: () => {
|
|
13132
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => Promise.resolve(), {
|
|
13133
|
+
name: "postgres.cursor",
|
|
13134
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13135
|
+
submodule: "cursor",
|
|
13136
|
+
packageType: PackageType.PG,
|
|
13137
|
+
packageName: "postgres",
|
|
13138
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13139
|
+
inputValue,
|
|
13140
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
13141
|
+
}, async (spanInfo) => {
|
|
13142
|
+
try {
|
|
13143
|
+
const mockData = await this._findMockData({
|
|
13144
|
+
spanInfo,
|
|
13145
|
+
name: "postgres.cursor",
|
|
13146
|
+
inputValue,
|
|
13147
|
+
submoduleName: "cursor",
|
|
13148
|
+
stackTrace
|
|
13149
|
+
});
|
|
13150
|
+
if (!mockData) throw new Error(`[PostgresInstrumentation] No matching mock found for cursor query: ${inputValue.query}`);
|
|
13151
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for cursor query: ${JSON.stringify(mockData)}`);
|
|
13152
|
+
const processedResult = convertPostgresTypes(mockData.result);
|
|
13153
|
+
const mockedData = Array.isArray(processedResult) ? processedResult : [];
|
|
13154
|
+
for (let i = 0; i < mockedData.length; i += cursorBatchSize) {
|
|
13155
|
+
const batch = mockedData.slice(i, i + cursorBatchSize);
|
|
13156
|
+
logger.debug(`[PostgresInstrumentation] Cursor replay calling callback with batch of ${batch.length} rows`);
|
|
13157
|
+
await userCallback(batch);
|
|
13158
|
+
}
|
|
13159
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13160
|
+
} catch (error) {
|
|
13161
|
+
logger.debug(`[PostgresInstrumentation] Cursor callback replay error: ${error.message}`);
|
|
13162
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13163
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13164
|
+
message: error.message
|
|
13165
|
+
});
|
|
13166
|
+
throw error;
|
|
13167
|
+
}
|
|
13168
|
+
});
|
|
13169
|
+
}
|
|
13170
|
+
});
|
|
13171
|
+
});
|
|
13172
|
+
}
|
|
13173
|
+
_handleCursorRecord({ originalCursor, rows, inputValue, creationContext, queryObject }) {
|
|
13174
|
+
const self = this;
|
|
13175
|
+
return { [Symbol.asyncIterator]() {
|
|
13176
|
+
const iterator = originalCursor(rows)[Symbol.asyncIterator]();
|
|
13177
|
+
let allRows = [];
|
|
13178
|
+
let result;
|
|
13179
|
+
let spanInfo = null;
|
|
13180
|
+
let spanStarted = false;
|
|
13181
|
+
return {
|
|
13182
|
+
async next() {
|
|
13183
|
+
return import_src$25.context.with(creationContext, async () => {
|
|
13184
|
+
if (!spanStarted) {
|
|
13185
|
+
spanStarted = true;
|
|
13186
|
+
let spanInputValue;
|
|
13187
|
+
try {
|
|
13188
|
+
spanInputValue = createSpanInputValue(inputValue);
|
|
13189
|
+
} catch (error) {
|
|
13190
|
+
logger.error(`[PostgresInstrumentation] error creating span input value:`, error);
|
|
13191
|
+
spanInputValue = void 0;
|
|
13192
|
+
}
|
|
13193
|
+
spanInfo = SpanUtils.createSpan({
|
|
13194
|
+
name: "postgres.cursor",
|
|
13195
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13196
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true,
|
|
13197
|
+
attributes: {
|
|
13198
|
+
[TdSpanAttributes.NAME]: "postgres.cursor",
|
|
13199
|
+
[TdSpanAttributes.PACKAGE_NAME]: "postgres",
|
|
13200
|
+
[TdSpanAttributes.SUBMODULE_NAME]: "cursor",
|
|
13201
|
+
[TdSpanAttributes.INSTRUMENTATION_NAME]: self.INSTRUMENTATION_NAME,
|
|
13202
|
+
[TdSpanAttributes.PACKAGE_TYPE]: PackageType.PG,
|
|
13203
|
+
[TdSpanAttributes.INPUT_VALUE]: spanInputValue,
|
|
13204
|
+
[TdSpanAttributes.IS_PRE_APP_START]: self.tuskDrift.isAppReady() ? false : true
|
|
13205
|
+
}
|
|
13206
|
+
});
|
|
13207
|
+
if (!spanInfo) logger.warn(`[PostgresInstrumentation] Failed to create cursor span in RECORD mode`);
|
|
13208
|
+
}
|
|
13209
|
+
try {
|
|
13210
|
+
result = await iterator.next();
|
|
13211
|
+
if (result.done) {
|
|
13212
|
+
if (spanInfo) try {
|
|
13213
|
+
self._endCursorSpan(spanInfo, allRows, queryObject, "Cursor");
|
|
13214
|
+
} catch (error) {
|
|
13215
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13216
|
+
}
|
|
13217
|
+
return {
|
|
13218
|
+
done: true,
|
|
13219
|
+
value: void 0
|
|
13220
|
+
};
|
|
13221
|
+
}
|
|
13222
|
+
if (Array.isArray(result.value)) allRows.push(...result.value);
|
|
13223
|
+
return {
|
|
13224
|
+
done: false,
|
|
13225
|
+
value: result.value
|
|
13226
|
+
};
|
|
13227
|
+
} catch (error) {
|
|
13228
|
+
if (spanInfo) try {
|
|
13229
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13230
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13231
|
+
message: error.message
|
|
13232
|
+
});
|
|
13233
|
+
} catch (error$1) {
|
|
13234
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error$1);
|
|
13235
|
+
}
|
|
13236
|
+
throw error;
|
|
13237
|
+
}
|
|
13238
|
+
});
|
|
13239
|
+
},
|
|
13240
|
+
async return() {
|
|
13241
|
+
if (spanInfo) try {
|
|
13242
|
+
self._endCursorSpan(spanInfo, allRows, queryObject, "Cursor terminated early");
|
|
13243
|
+
} catch (error) {
|
|
13244
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13245
|
+
}
|
|
13246
|
+
if (iterator.return) await iterator.return();
|
|
13247
|
+
return {
|
|
13248
|
+
done: true,
|
|
13249
|
+
value: void 0
|
|
13250
|
+
};
|
|
13251
|
+
}
|
|
13252
|
+
};
|
|
13253
|
+
} };
|
|
13254
|
+
}
|
|
13255
|
+
_handleCursorReplay({ inputValue, creationContext, cursorBatchSize }) {
|
|
13256
|
+
const self = this;
|
|
13257
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13258
|
+
return { [Symbol.asyncIterator]() {
|
|
13259
|
+
let mockedData = null;
|
|
13260
|
+
let currentIndex = 0;
|
|
13261
|
+
let spanInfo = null;
|
|
13262
|
+
let dataFetched = false;
|
|
13263
|
+
return {
|
|
13264
|
+
async next() {
|
|
13265
|
+
return import_src$25.context.with(creationContext, async () => {
|
|
13266
|
+
if (!dataFetched) {
|
|
13267
|
+
dataFetched = true;
|
|
13268
|
+
spanInfo = SpanUtils.createSpan({
|
|
13269
|
+
name: "postgres.cursor",
|
|
13270
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13271
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true,
|
|
13272
|
+
attributes: {
|
|
13273
|
+
[TdSpanAttributes.NAME]: "postgres.cursor",
|
|
13274
|
+
[TdSpanAttributes.PACKAGE_NAME]: "postgres",
|
|
13275
|
+
[TdSpanAttributes.SUBMODULE_NAME]: "cursor",
|
|
13276
|
+
[TdSpanAttributes.INSTRUMENTATION_NAME]: self.INSTRUMENTATION_NAME,
|
|
13277
|
+
[TdSpanAttributes.PACKAGE_TYPE]: PackageType.PG,
|
|
13278
|
+
[TdSpanAttributes.INPUT_VALUE]: createSpanInputValue(inputValue),
|
|
13279
|
+
[TdSpanAttributes.IS_PRE_APP_START]: self.tuskDrift.isAppReady() ? false : true
|
|
13280
|
+
}
|
|
13281
|
+
});
|
|
13282
|
+
if (!spanInfo) throw new Error(`[PostgresInstrumentation] Failed to create cursor span in REPLAY mode`);
|
|
13283
|
+
const mockData = await self._findMockData({
|
|
13284
|
+
spanInfo,
|
|
13285
|
+
name: "postgres.cursor",
|
|
13286
|
+
inputValue,
|
|
13287
|
+
submoduleName: "cursor",
|
|
13288
|
+
stackTrace
|
|
13289
|
+
});
|
|
13290
|
+
if (!mockData) {
|
|
13291
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13292
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13293
|
+
message: "No mock data found"
|
|
13294
|
+
});
|
|
13295
|
+
throw new Error(`[PostgresInstrumentation] No matching mock found for cursor query: ${inputValue.query}`);
|
|
13296
|
+
}
|
|
13297
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for cursor query: ${JSON.stringify(mockData)}`);
|
|
13298
|
+
const processedResult = convertPostgresTypes(mockData.result);
|
|
13299
|
+
mockedData = Array.isArray(processedResult) ? processedResult : [];
|
|
13300
|
+
}
|
|
13301
|
+
if (currentIndex >= mockedData.length) {
|
|
13302
|
+
if (spanInfo) SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13303
|
+
return {
|
|
13304
|
+
done: true,
|
|
13305
|
+
value: void 0
|
|
13306
|
+
};
|
|
13307
|
+
}
|
|
13308
|
+
const batch = mockedData.slice(currentIndex, currentIndex + cursorBatchSize);
|
|
13309
|
+
currentIndex += batch.length;
|
|
13310
|
+
logger.debug(`[PostgresInstrumentation] Cursor replay returning batch of ${batch.length} rows`);
|
|
13311
|
+
return {
|
|
13312
|
+
done: false,
|
|
13313
|
+
value: batch
|
|
13314
|
+
};
|
|
13315
|
+
});
|
|
13316
|
+
},
|
|
13317
|
+
async return() {
|
|
13318
|
+
if (spanInfo) SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13319
|
+
return {
|
|
13320
|
+
done: true,
|
|
13321
|
+
value: void 0
|
|
13322
|
+
};
|
|
13323
|
+
}
|
|
13324
|
+
};
|
|
13325
|
+
} };
|
|
13326
|
+
}
|
|
13327
|
+
_handleForEachRecord({ originalForEach, inputValue, creationContext, userCallback }) {
|
|
13328
|
+
const self = this;
|
|
13329
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13330
|
+
return handleRecordMode({
|
|
13331
|
+
originalFunctionCall: () => originalForEach(userCallback),
|
|
13332
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
13333
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalForEach(userCallback), {
|
|
13334
|
+
name: "postgres.query",
|
|
13335
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13336
|
+
submodule: "query",
|
|
13337
|
+
packageType: PackageType.PG,
|
|
13338
|
+
packageName: "postgres",
|
|
13339
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13340
|
+
inputValue,
|
|
13341
|
+
isPreAppStart
|
|
13342
|
+
}, async (spanInfo) => {
|
|
13343
|
+
const allRows = [];
|
|
13344
|
+
const wrappedCallback = (row, result) => {
|
|
13345
|
+
allRows.push(row);
|
|
13346
|
+
return userCallback(row, result);
|
|
13347
|
+
};
|
|
13348
|
+
try {
|
|
13349
|
+
const result = await originalForEach(wrappedCallback);
|
|
13350
|
+
try {
|
|
13351
|
+
self._endCursorSpan(spanInfo, allRows, result, "forEach");
|
|
13352
|
+
} catch (error) {
|
|
13353
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13354
|
+
}
|
|
13355
|
+
return result;
|
|
13356
|
+
} catch (error) {
|
|
13357
|
+
try {
|
|
13358
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13359
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13360
|
+
message: error.message
|
|
13361
|
+
});
|
|
13362
|
+
} catch (error$1) {
|
|
13363
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error$1);
|
|
13364
|
+
}
|
|
13365
|
+
throw error;
|
|
13366
|
+
}
|
|
13367
|
+
});
|
|
13368
|
+
},
|
|
13369
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
13370
|
+
});
|
|
13371
|
+
});
|
|
13372
|
+
}
|
|
13373
|
+
_handleForEachReplay({ inputValue, creationContext, userCallback }) {
|
|
13374
|
+
const self = this;
|
|
13375
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13376
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13377
|
+
return handleReplayMode({
|
|
13378
|
+
noOpRequestHandler: () => Promise.resolve(Object.assign([], {
|
|
13379
|
+
count: 0,
|
|
13380
|
+
command: null
|
|
13381
|
+
})),
|
|
13382
|
+
isServerRequest: false,
|
|
13383
|
+
replayModeHandler: () => {
|
|
13384
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => Promise.resolve(Object.assign([], {
|
|
13385
|
+
count: 0,
|
|
13386
|
+
command: null
|
|
13387
|
+
})), {
|
|
13388
|
+
name: "postgres.query",
|
|
13389
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13390
|
+
submodule: "query",
|
|
13391
|
+
packageType: PackageType.PG,
|
|
13392
|
+
packageName: "postgres",
|
|
13393
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13394
|
+
inputValue,
|
|
13395
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
13396
|
+
}, async (spanInfo) => {
|
|
13397
|
+
try {
|
|
13398
|
+
const mockedResult = await self._handleReplayQueryOperation({
|
|
13399
|
+
inputValue,
|
|
13400
|
+
spanInfo,
|
|
13401
|
+
submodule: "query",
|
|
13402
|
+
name: "postgres.query",
|
|
13403
|
+
stackTrace,
|
|
13404
|
+
operationType: "forEach"
|
|
13405
|
+
});
|
|
13406
|
+
const mockedRows = Array.isArray(mockedResult) ? mockedResult : [];
|
|
13407
|
+
logger.debug(`[PostgresInstrumentation] forEach replay: calling callback with ${mockedRows.length} mocked rows`);
|
|
13408
|
+
for (const row of mockedRows) userCallback(row, mockedResult);
|
|
13409
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13410
|
+
return Object.assign([], {
|
|
13411
|
+
count: mockedRows.length,
|
|
13412
|
+
command: null
|
|
13413
|
+
});
|
|
13414
|
+
} catch (error) {
|
|
13415
|
+
logger.debug(`[PostgresInstrumentation] forEach replay error: ${error.message}`);
|
|
13416
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13417
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13418
|
+
message: error.message
|
|
13419
|
+
});
|
|
13420
|
+
throw error;
|
|
13421
|
+
}
|
|
13422
|
+
});
|
|
13423
|
+
}
|
|
13424
|
+
});
|
|
13425
|
+
});
|
|
13426
|
+
}
|
|
13427
|
+
/**
|
|
13428
|
+
* Wraps a query's .then() method to add instrumentation.
|
|
13429
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13430
|
+
*/
|
|
13431
|
+
_wrapThenMethod(query, originalThen, inputValue, creationContext, spanConfig) {
|
|
13432
|
+
const self = this;
|
|
13433
|
+
query.then = function(onFulfilled, onRejected) {
|
|
13434
|
+
if (query._forEachCalled) return originalThen(onFulfilled, onRejected);
|
|
13435
|
+
if (query._tuskRecorded) return originalThen(onFulfilled, onRejected);
|
|
13436
|
+
query._tuskRecorded = true;
|
|
13437
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13438
|
+
if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
13439
|
+
originalFunctionCall: () => originalThen(onFulfilled, onRejected),
|
|
13440
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
13441
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
13442
|
+
name: spanConfig.name,
|
|
13443
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13444
|
+
submodule: spanConfig.submodule,
|
|
13445
|
+
packageType: PackageType.PG,
|
|
13446
|
+
packageName: "postgres",
|
|
13447
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13448
|
+
inputValue,
|
|
13449
|
+
isPreAppStart
|
|
13450
|
+
}, (spanInfo) => {
|
|
13451
|
+
const wrappedOnFulfilled = (result) => {
|
|
13452
|
+
try {
|
|
13453
|
+
logger.debug(`[PostgresInstrumentation] Postgres ${spanConfig.operationType} query completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
13454
|
+
addOutputAttributesToSpan(spanInfo, result);
|
|
13455
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13456
|
+
} catch (error) {
|
|
13457
|
+
logger.error(`[PostgresInstrumentation] error processing ${spanConfig.operationType} query response:`, error);
|
|
13458
|
+
}
|
|
13459
|
+
return onFulfilled ? onFulfilled(result) : result;
|
|
13460
|
+
};
|
|
13461
|
+
const wrappedOnRejected = (error) => {
|
|
13462
|
+
try {
|
|
13463
|
+
logger.debug(`[PostgresInstrumentation] Postgres ${spanConfig.operationType} query error: ${error.message}`);
|
|
13464
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13465
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13466
|
+
message: error.message
|
|
13467
|
+
});
|
|
13468
|
+
} catch (spanError) {
|
|
13469
|
+
logger.error(`[PostgresInstrumentation] error ending span:`, spanError);
|
|
13470
|
+
}
|
|
13471
|
+
if (onRejected) return onRejected(error);
|
|
13472
|
+
throw error;
|
|
13473
|
+
};
|
|
13474
|
+
return originalThen(wrappedOnFulfilled, wrappedOnRejected);
|
|
13475
|
+
});
|
|
13476
|
+
},
|
|
13477
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
13478
|
+
});
|
|
13479
|
+
else if (self.mode === TuskDriftMode.REPLAY) {
|
|
13480
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13481
|
+
return handleReplayMode({
|
|
13482
|
+
noOpRequestHandler: () => Promise.resolve(Object.assign([], {
|
|
13483
|
+
count: 0,
|
|
13484
|
+
command: null
|
|
13485
|
+
})),
|
|
13486
|
+
isServerRequest: false,
|
|
13487
|
+
replayModeHandler: () => {
|
|
13488
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
13489
|
+
name: spanConfig.name,
|
|
13490
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13491
|
+
submodule: spanConfig.submodule,
|
|
13492
|
+
packageType: PackageType.PG,
|
|
13493
|
+
packageName: "postgres",
|
|
13494
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13495
|
+
inputValue,
|
|
13496
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
13497
|
+
}, async (spanInfo) => {
|
|
13498
|
+
const mockedResult = await self._handleReplayQueryOperation({
|
|
13499
|
+
inputValue,
|
|
13500
|
+
spanInfo,
|
|
13501
|
+
submodule: spanConfig.submodule,
|
|
13502
|
+
name: spanConfig.name,
|
|
13503
|
+
stackTrace,
|
|
13504
|
+
operationType: spanConfig.operationType
|
|
13505
|
+
});
|
|
13506
|
+
return onFulfilled ? onFulfilled(mockedResult) : mockedResult;
|
|
13507
|
+
});
|
|
13508
|
+
}
|
|
13509
|
+
});
|
|
13510
|
+
} else return originalThen(onFulfilled, onRejected);
|
|
13511
|
+
});
|
|
13512
|
+
};
|
|
13513
|
+
}
|
|
13514
|
+
/**
|
|
13515
|
+
* Wraps a query's .execute() method to prevent TCP calls in REPLAY mode.
|
|
13516
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13517
|
+
*/
|
|
13518
|
+
_wrapExecuteMethod(query) {
|
|
13519
|
+
const self = this;
|
|
13520
|
+
const originalExecute = query.execute ? query.execute.bind(query) : void 0;
|
|
13521
|
+
if (originalExecute) query.execute = function() {
|
|
13522
|
+
if (self.mode === TuskDriftMode.REPLAY) return this;
|
|
13523
|
+
else return originalExecute.call(this);
|
|
13524
|
+
};
|
|
12859
13525
|
}
|
|
12860
|
-
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
|
|
12865
|
-
|
|
12866
|
-
const
|
|
12867
|
-
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
|
|
12871
|
-
|
|
12872
|
-
}
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
|
|
12876
|
-
|
|
12877
|
-
|
|
12878
|
-
|
|
12879
|
-
|
|
13526
|
+
/**
|
|
13527
|
+
* Wraps a query's cursor() method to add instrumentation.
|
|
13528
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13529
|
+
*/
|
|
13530
|
+
_wrapCursorMethod(query, inputValue, creationContext) {
|
|
13531
|
+
if (typeof query.cursor !== "function") return;
|
|
13532
|
+
const self = this;
|
|
13533
|
+
const originalCursor = query.cursor.bind(query);
|
|
13534
|
+
query.cursor = function(rows, fn) {
|
|
13535
|
+
if (typeof rows === "function") {
|
|
13536
|
+
fn = rows;
|
|
13537
|
+
rows = 1;
|
|
13538
|
+
}
|
|
13539
|
+
if (!rows) rows = 1;
|
|
13540
|
+
if (typeof fn === "function") if (self.mode === TuskDriftMode.RECORD) return self._handleCursorCallbackRecord({
|
|
13541
|
+
originalCursor,
|
|
13542
|
+
rows,
|
|
13543
|
+
inputValue,
|
|
13544
|
+
creationContext,
|
|
13545
|
+
userCallback: fn
|
|
13546
|
+
});
|
|
13547
|
+
else if (self.mode === TuskDriftMode.REPLAY) return self._handleCursorCallbackReplay({
|
|
13548
|
+
inputValue,
|
|
13549
|
+
creationContext,
|
|
13550
|
+
cursorBatchSize: rows,
|
|
13551
|
+
userCallback: fn
|
|
13552
|
+
});
|
|
13553
|
+
else return originalCursor(rows, fn);
|
|
13554
|
+
if (self.mode === TuskDriftMode.RECORD) return self._handleCursorRecord({
|
|
13555
|
+
originalCursor,
|
|
13556
|
+
rows,
|
|
13557
|
+
inputValue,
|
|
13558
|
+
creationContext,
|
|
13559
|
+
queryObject: this
|
|
13560
|
+
});
|
|
13561
|
+
else if (self.mode === TuskDriftMode.REPLAY) return self._handleCursorReplay({
|
|
13562
|
+
inputValue,
|
|
13563
|
+
creationContext,
|
|
13564
|
+
cursorBatchSize: rows
|
|
13565
|
+
});
|
|
13566
|
+
else return originalCursor(rows);
|
|
13567
|
+
};
|
|
12880
13568
|
}
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
|
|
12885
|
-
|
|
12886
|
-
|
|
12887
|
-
|
|
12888
|
-
|
|
13569
|
+
/**
|
|
13570
|
+
* Wraps a query's forEach() method to add instrumentation.
|
|
13571
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13572
|
+
*/
|
|
13573
|
+
_wrapForEachMethod(query, inputValue, creationContext) {
|
|
13574
|
+
if (typeof query.forEach !== "function") return;
|
|
13575
|
+
const self = this;
|
|
13576
|
+
const originalForEach = query.forEach.bind(query);
|
|
13577
|
+
query.forEach = function(fn) {
|
|
13578
|
+
query._forEachCalled = true;
|
|
13579
|
+
if (self.mode === TuskDriftMode.RECORD) return self._handleForEachRecord({
|
|
13580
|
+
originalForEach,
|
|
13581
|
+
inputValue,
|
|
13582
|
+
creationContext,
|
|
13583
|
+
userCallback: fn
|
|
13584
|
+
});
|
|
13585
|
+
else if (self.mode === TuskDriftMode.REPLAY) return self._handleForEachReplay({
|
|
13586
|
+
inputValue,
|
|
13587
|
+
creationContext,
|
|
13588
|
+
userCallback: fn
|
|
13589
|
+
});
|
|
13590
|
+
else return originalForEach(fn);
|
|
12889
13591
|
};
|
|
12890
|
-
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
12891
13592
|
}
|
|
12892
13593
|
_wrap(target, propertyName, wrapper) {
|
|
12893
13594
|
wrap(target, propertyName, wrapper);
|
|
@@ -12910,8 +13611,9 @@ function isMysqlOkPacket(result) {
|
|
|
12910
13611
|
* Extends EventEmitter to properly handle all connection methods and events
|
|
12911
13612
|
*/
|
|
12912
13613
|
var TdMysqlConnectionMock = class extends EventEmitter {
|
|
12913
|
-
constructor(mysqlInstrumentation, clientType = "poolConnection", spanInfo) {
|
|
13614
|
+
constructor(mysqlInstrumentation, clientType = "poolConnection", spanInfo, pool) {
|
|
12914
13615
|
super();
|
|
13616
|
+
this._pool = null;
|
|
12915
13617
|
this.threadId = null;
|
|
12916
13618
|
this.config = {
|
|
12917
13619
|
host: "localhost",
|
|
@@ -12923,6 +13625,7 @@ var TdMysqlConnectionMock = class extends EventEmitter {
|
|
|
12923
13625
|
this.spanInfo = spanInfo;
|
|
12924
13626
|
this.clientType = clientType;
|
|
12925
13627
|
this.threadId = 1;
|
|
13628
|
+
this._pool = pool;
|
|
12926
13629
|
}
|
|
12927
13630
|
query(...args) {
|
|
12928
13631
|
logger.debug(`[TdMysqlConnectionMock] Mock connection query intercepted in REPLAY mode`);
|
|
@@ -12930,7 +13633,13 @@ var TdMysqlConnectionMock = class extends EventEmitter {
|
|
|
12930
13633
|
let values;
|
|
12931
13634
|
let callback;
|
|
12932
13635
|
let options = {};
|
|
12933
|
-
|
|
13636
|
+
const firstArg = args[0];
|
|
13637
|
+
if (firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function") {
|
|
13638
|
+
sql = firstArg.sql;
|
|
13639
|
+
values = firstArg.values;
|
|
13640
|
+
callback = firstArg._callback;
|
|
13641
|
+
options = { nestTables: firstArg.nestTables };
|
|
13642
|
+
} else if (typeof args[0] === "string") {
|
|
12934
13643
|
sql = args[0];
|
|
12935
13644
|
if (typeof args[1] === "function") callback = args[1];
|
|
12936
13645
|
else if (Array.isArray(args[1])) {
|
|
@@ -12982,6 +13691,7 @@ var TdMysqlConnectionMock = class extends EventEmitter {
|
|
|
12982
13691
|
}
|
|
12983
13692
|
}
|
|
12984
13693
|
release() {
|
|
13694
|
+
if (this._pool) this._pool.emit("release", this);
|
|
12985
13695
|
this.emit("end");
|
|
12986
13696
|
}
|
|
12987
13697
|
destroy() {
|
|
@@ -13006,19 +13716,22 @@ var TdMysqlConnectionMock = class extends EventEmitter {
|
|
|
13006
13716
|
return;
|
|
13007
13717
|
}
|
|
13008
13718
|
}
|
|
13009
|
-
beginTransaction(
|
|
13719
|
+
beginTransaction(optionsOrCallback, callbackArg) {
|
|
13720
|
+
const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : callbackArg;
|
|
13010
13721
|
if (callback) {
|
|
13011
13722
|
process.nextTick(() => callback(null));
|
|
13012
13723
|
return;
|
|
13013
13724
|
}
|
|
13014
13725
|
}
|
|
13015
|
-
commit(
|
|
13726
|
+
commit(optionsOrCallback, callbackArg) {
|
|
13727
|
+
const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : callbackArg;
|
|
13016
13728
|
if (callback) {
|
|
13017
13729
|
process.nextTick(() => callback(null));
|
|
13018
13730
|
return;
|
|
13019
13731
|
}
|
|
13020
13732
|
}
|
|
13021
|
-
rollback(
|
|
13733
|
+
rollback(optionsOrCallback, callbackArg) {
|
|
13734
|
+
const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : callbackArg;
|
|
13022
13735
|
if (callback) {
|
|
13023
13736
|
process.nextTick(() => callback(null));
|
|
13024
13737
|
return;
|
|
@@ -13214,6 +13927,11 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13214
13927
|
name: "mysql/lib/Pool.js",
|
|
13215
13928
|
supportedVersions: ["2.*"],
|
|
13216
13929
|
patch: (moduleExports) => this._patchPoolFile(moduleExports)
|
|
13930
|
+
}),
|
|
13931
|
+
new TdInstrumentationNodeModuleFile({
|
|
13932
|
+
name: "mysql/lib/PoolNamespace.js",
|
|
13933
|
+
supportedVersions: ["2.*"],
|
|
13934
|
+
patch: (moduleExports) => this._patchPoolNamespaceFile(moduleExports)
|
|
13217
13935
|
})
|
|
13218
13936
|
]
|
|
13219
13937
|
})];
|
|
@@ -13353,12 +14071,40 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13353
14071
|
return PoolClass;
|
|
13354
14072
|
}
|
|
13355
14073
|
/**
|
|
14074
|
+
* Patch PoolNamespace.prototype methods at the file level
|
|
14075
|
+
* This handles queries made via poolCluster.of("pattern").query()
|
|
14076
|
+
*/
|
|
14077
|
+
_patchPoolNamespaceFile(PoolNamespaceClass) {
|
|
14078
|
+
logger.debug(`[MysqlInstrumentation] Patching PoolNamespace class (file-based)`);
|
|
14079
|
+
if (this.isModulePatched(PoolNamespaceClass)) {
|
|
14080
|
+
logger.debug(`[MysqlInstrumentation] PoolNamespace class already patched, skipping`);
|
|
14081
|
+
return PoolNamespaceClass;
|
|
14082
|
+
}
|
|
14083
|
+
if (PoolNamespaceClass.prototype && PoolNamespaceClass.prototype.query) {
|
|
14084
|
+
if (!isWrapped$1(PoolNamespaceClass.prototype.query)) {
|
|
14085
|
+
this._wrap(PoolNamespaceClass.prototype, "query", this._getPoolNamespaceQueryPatchFn());
|
|
14086
|
+
logger.debug(`[MysqlInstrumentation] Wrapped PoolNamespace.prototype.query`);
|
|
14087
|
+
}
|
|
14088
|
+
}
|
|
14089
|
+
if (PoolNamespaceClass.prototype && PoolNamespaceClass.prototype.getConnection) {
|
|
14090
|
+
if (!isWrapped$1(PoolNamespaceClass.prototype.getConnection)) {
|
|
14091
|
+
this._wrap(PoolNamespaceClass.prototype, "getConnection", this._getPoolNamespaceGetConnectionPatchFn());
|
|
14092
|
+
logger.debug(`[MysqlInstrumentation] Wrapped PoolNamespace.prototype.getConnection`);
|
|
14093
|
+
}
|
|
14094
|
+
}
|
|
14095
|
+
this.markModuleAsPatched(PoolNamespaceClass);
|
|
14096
|
+
logger.debug(`[MysqlInstrumentation] PoolNamespace class patching complete`);
|
|
14097
|
+
return PoolNamespaceClass;
|
|
14098
|
+
}
|
|
14099
|
+
/**
|
|
13356
14100
|
* Get wrapper function for query method (prototype-level patching)
|
|
13357
14101
|
*/
|
|
13358
14102
|
_getQueryPatchFn() {
|
|
13359
14103
|
const self = this;
|
|
13360
14104
|
return (originalQuery) => {
|
|
13361
14105
|
return function query(...args) {
|
|
14106
|
+
const firstArg = args[0];
|
|
14107
|
+
const hasInternalCallback = firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function";
|
|
13362
14108
|
let sql;
|
|
13363
14109
|
let values;
|
|
13364
14110
|
let callback;
|
|
@@ -13369,6 +14115,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13369
14115
|
values = queryObj.values;
|
|
13370
14116
|
options = { nestTables: queryObj.nestTables };
|
|
13371
14117
|
callback = args.find((arg) => typeof arg === "function");
|
|
14118
|
+
if (!callback && hasInternalCallback) callback = firstArg._callback;
|
|
13372
14119
|
} catch (error) {
|
|
13373
14120
|
logger.debug(`[MysqlInstrumentation] Error using createQuery, falling back to manual parsing:`, error);
|
|
13374
14121
|
({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
@@ -13379,7 +14126,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13379
14126
|
values,
|
|
13380
14127
|
options: options.nestTables ? { nestTables: options.nestTables } : void 0
|
|
13381
14128
|
};
|
|
13382
|
-
const isEventEmitterMode = !callback;
|
|
14129
|
+
const isEventEmitterMode = !callback && !hasInternalCallback;
|
|
13383
14130
|
if (self.mode === TuskDriftMode.REPLAY) {
|
|
13384
14131
|
const stackTrace = captureStackTrace(["MysqlInstrumentation"]);
|
|
13385
14132
|
return handleReplayMode({
|
|
@@ -13475,11 +14222,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13475
14222
|
_getBeginTransactionPatchFn() {
|
|
13476
14223
|
const self = this;
|
|
13477
14224
|
return (originalBeginTransaction) => {
|
|
13478
|
-
return function beginTransaction(
|
|
14225
|
+
return function beginTransaction(optionsOrCallback, callbackArg) {
|
|
14226
|
+
let actualCallback;
|
|
14227
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14228
|
+
else actualCallback = callbackArg;
|
|
13479
14229
|
const inputValue = { query: "BEGIN" };
|
|
13480
14230
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13481
14231
|
noOpRequestHandler: () => {
|
|
13482
|
-
if (
|
|
14232
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13483
14233
|
},
|
|
13484
14234
|
isServerRequest: false,
|
|
13485
14235
|
replayModeHandler: () => {
|
|
@@ -13493,7 +14243,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13493
14243
|
inputValue,
|
|
13494
14244
|
isPreAppStart: false
|
|
13495
14245
|
}, (spanInfo) => {
|
|
13496
|
-
return self._handleReplayTransaction(inputValue,
|
|
14246
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13497
14247
|
});
|
|
13498
14248
|
}
|
|
13499
14249
|
});
|
|
@@ -13510,7 +14260,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13510
14260
|
inputValue,
|
|
13511
14261
|
isPreAppStart
|
|
13512
14262
|
}, (spanInfo) => {
|
|
13513
|
-
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, this, arguments,
|
|
14263
|
+
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, this, arguments, actualCallback);
|
|
13514
14264
|
});
|
|
13515
14265
|
},
|
|
13516
14266
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13525,11 +14275,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13525
14275
|
_getCommitPatchFn() {
|
|
13526
14276
|
const self = this;
|
|
13527
14277
|
return (originalCommit) => {
|
|
13528
|
-
return function commit(
|
|
14278
|
+
return function commit(optionsOrCallback, callbackArg) {
|
|
14279
|
+
let actualCallback;
|
|
14280
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14281
|
+
else actualCallback = callbackArg;
|
|
13529
14282
|
const inputValue = { query: "COMMIT" };
|
|
13530
14283
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13531
14284
|
noOpRequestHandler: () => {
|
|
13532
|
-
if (
|
|
14285
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13533
14286
|
},
|
|
13534
14287
|
isServerRequest: false,
|
|
13535
14288
|
replayModeHandler: () => {
|
|
@@ -13543,7 +14296,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13543
14296
|
inputValue,
|
|
13544
14297
|
isPreAppStart: false
|
|
13545
14298
|
}, (spanInfo) => {
|
|
13546
|
-
return self._handleReplayTransaction(inputValue,
|
|
14299
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13547
14300
|
});
|
|
13548
14301
|
}
|
|
13549
14302
|
});
|
|
@@ -13560,7 +14313,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13560
14313
|
inputValue,
|
|
13561
14314
|
isPreAppStart
|
|
13562
14315
|
}, (spanInfo) => {
|
|
13563
|
-
return self._handleRecordTransaction(spanInfo, originalCommit, this, arguments,
|
|
14316
|
+
return self._handleRecordTransaction(spanInfo, originalCommit, this, arguments, actualCallback);
|
|
13564
14317
|
});
|
|
13565
14318
|
},
|
|
13566
14319
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13575,11 +14328,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13575
14328
|
_getRollbackPatchFn() {
|
|
13576
14329
|
const self = this;
|
|
13577
14330
|
return (originalRollback) => {
|
|
13578
|
-
return function rollback(
|
|
14331
|
+
return function rollback(optionsOrCallback, callbackArg) {
|
|
14332
|
+
let actualCallback;
|
|
14333
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14334
|
+
else actualCallback = callbackArg;
|
|
13579
14335
|
const inputValue = { query: "ROLLBACK" };
|
|
13580
14336
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13581
14337
|
noOpRequestHandler: () => {
|
|
13582
|
-
if (
|
|
14338
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13583
14339
|
},
|
|
13584
14340
|
isServerRequest: false,
|
|
13585
14341
|
replayModeHandler: () => {
|
|
@@ -13593,7 +14349,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13593
14349
|
inputValue,
|
|
13594
14350
|
isPreAppStart: false
|
|
13595
14351
|
}, (spanInfo) => {
|
|
13596
|
-
return self._handleReplayTransaction(inputValue,
|
|
14352
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13597
14353
|
});
|
|
13598
14354
|
}
|
|
13599
14355
|
});
|
|
@@ -13610,7 +14366,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13610
14366
|
inputValue,
|
|
13611
14367
|
isPreAppStart
|
|
13612
14368
|
}, (spanInfo) => {
|
|
13613
|
-
return self._handleRecordTransaction(spanInfo, originalRollback, this, arguments,
|
|
14369
|
+
return self._handleRecordTransaction(spanInfo, originalRollback, this, arguments, actualCallback);
|
|
13614
14370
|
});
|
|
13615
14371
|
},
|
|
13616
14372
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13778,9 +14534,10 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13778
14534
|
return (originalGetConnection) => {
|
|
13779
14535
|
return function getConnection(callback) {
|
|
13780
14536
|
const inputValue = { clientType: "pool" };
|
|
14537
|
+
const pool = this;
|
|
13781
14538
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13782
14539
|
noOpRequestHandler: () => {
|
|
13783
|
-
return self._handleNoOpReplayGetConnection(callback);
|
|
14540
|
+
return self._handleNoOpReplayGetConnection(pool, callback);
|
|
13784
14541
|
},
|
|
13785
14542
|
isServerRequest: false,
|
|
13786
14543
|
replayModeHandler: () => {
|
|
@@ -13794,7 +14551,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13794
14551
|
inputValue,
|
|
13795
14552
|
isPreAppStart: false
|
|
13796
14553
|
}, (spanInfo) => {
|
|
13797
|
-
return self._handleReplayPoolGetConnection(spanInfo, callback);
|
|
14554
|
+
return self._handleReplayPoolGetConnection(pool, spanInfo, callback);
|
|
13798
14555
|
});
|
|
13799
14556
|
}
|
|
13800
14557
|
});
|
|
@@ -13824,6 +14581,8 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13824
14581
|
const self = this;
|
|
13825
14582
|
return (originalQuery) => {
|
|
13826
14583
|
return function query(...args) {
|
|
14584
|
+
const firstArg = args[0];
|
|
14585
|
+
const hasInternalCallback = firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function";
|
|
13827
14586
|
let sql;
|
|
13828
14587
|
let values;
|
|
13829
14588
|
let callback;
|
|
@@ -13834,6 +14593,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13834
14593
|
values = queryObj.values;
|
|
13835
14594
|
options = { nestTables: queryObj.nestTables };
|
|
13836
14595
|
callback = args.find((arg) => typeof arg === "function");
|
|
14596
|
+
if (!callback && hasInternalCallback) callback = firstArg._callback;
|
|
13837
14597
|
} catch (error) {
|
|
13838
14598
|
logger.debug(`[MysqlInstrumentation] Error using createQuery, falling back to manual parsing:`, error);
|
|
13839
14599
|
({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
@@ -13844,7 +14604,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13844
14604
|
values,
|
|
13845
14605
|
options: options.nestTables ? { nestTables: options.nestTables } : void 0
|
|
13846
14606
|
};
|
|
13847
|
-
const isEventEmitterMode = !callback;
|
|
14607
|
+
const isEventEmitterMode = !callback && !hasInternalCallback;
|
|
13848
14608
|
if (self.mode === TuskDriftMode.REPLAY) {
|
|
13849
14609
|
const stackTrace = captureStackTrace(["MysqlInstrumentation"]);
|
|
13850
14610
|
return handleReplayMode({
|
|
@@ -13946,6 +14706,33 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13946
14706
|
});
|
|
13947
14707
|
return queryEmitter;
|
|
13948
14708
|
} else {
|
|
14709
|
+
const queryObject = args[0];
|
|
14710
|
+
if (queryObject && typeof queryObject === "object" && typeof queryObject._callback === "function") {
|
|
14711
|
+
const originalCallback$1 = queryObject._callback;
|
|
14712
|
+
queryObject._callback = function(err, results, fields) {
|
|
14713
|
+
if (err) try {
|
|
14714
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
14715
|
+
code: import_src$23.SpanStatusCode.ERROR,
|
|
14716
|
+
message: err.message
|
|
14717
|
+
});
|
|
14718
|
+
} catch (error) {
|
|
14719
|
+
logger.error(`[MysqlInstrumentation] error ending span:`, error);
|
|
14720
|
+
}
|
|
14721
|
+
else try {
|
|
14722
|
+
const outputValue = {
|
|
14723
|
+
results,
|
|
14724
|
+
fields
|
|
14725
|
+
};
|
|
14726
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
14727
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$23.SpanStatusCode.OK });
|
|
14728
|
+
} catch (error) {
|
|
14729
|
+
logger.error(`[MysqlInstrumentation] error ending span:`, error);
|
|
14730
|
+
}
|
|
14731
|
+
logger.debug(`[MysqlInstrumentation] Query completed`);
|
|
14732
|
+
originalCallback$1.call(this, err, results, fields);
|
|
14733
|
+
};
|
|
14734
|
+
return originalQuery.apply(connection, args);
|
|
14735
|
+
}
|
|
13949
14736
|
const originalCallback = callback;
|
|
13950
14737
|
const callbackIndex = args.findIndex((arg) => typeof arg === "function");
|
|
13951
14738
|
args[callbackIndex] = function(err, results, fields) {
|
|
@@ -14000,11 +14787,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14000
14787
|
_patchBeginTransaction(connection) {
|
|
14001
14788
|
const self = this;
|
|
14002
14789
|
return (originalBeginTransaction) => {
|
|
14003
|
-
return function beginTransaction(
|
|
14790
|
+
return function beginTransaction(optionsOrCallback, callbackArg) {
|
|
14791
|
+
let actualCallback;
|
|
14792
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14793
|
+
else actualCallback = callbackArg;
|
|
14004
14794
|
const inputValue = { query: "BEGIN" };
|
|
14005
14795
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
14006
14796
|
noOpRequestHandler: () => {
|
|
14007
|
-
if (
|
|
14797
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
14008
14798
|
},
|
|
14009
14799
|
isServerRequest: false,
|
|
14010
14800
|
replayModeHandler: () => {
|
|
@@ -14018,7 +14808,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14018
14808
|
inputValue,
|
|
14019
14809
|
isPreAppStart: false
|
|
14020
14810
|
}, (spanInfo) => {
|
|
14021
|
-
return self._handleReplayTransaction(inputValue,
|
|
14811
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
14022
14812
|
});
|
|
14023
14813
|
}
|
|
14024
14814
|
});
|
|
@@ -14035,7 +14825,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14035
14825
|
inputValue,
|
|
14036
14826
|
isPreAppStart
|
|
14037
14827
|
}, (spanInfo) => {
|
|
14038
|
-
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, connection, arguments,
|
|
14828
|
+
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, connection, arguments, actualCallback);
|
|
14039
14829
|
});
|
|
14040
14830
|
},
|
|
14041
14831
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -14047,11 +14837,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14047
14837
|
_patchCommit(connection) {
|
|
14048
14838
|
const self = this;
|
|
14049
14839
|
return (originalCommit) => {
|
|
14050
|
-
return function commit(
|
|
14840
|
+
return function commit(optionsOrCallback, callbackArg) {
|
|
14841
|
+
let actualCallback;
|
|
14842
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14843
|
+
else actualCallback = callbackArg;
|
|
14051
14844
|
const inputValue = { query: "COMMIT" };
|
|
14052
14845
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
14053
14846
|
noOpRequestHandler: () => {
|
|
14054
|
-
if (
|
|
14847
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
14055
14848
|
},
|
|
14056
14849
|
isServerRequest: false,
|
|
14057
14850
|
replayModeHandler: () => {
|
|
@@ -14065,7 +14858,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14065
14858
|
inputValue,
|
|
14066
14859
|
isPreAppStart: false
|
|
14067
14860
|
}, (spanInfo) => {
|
|
14068
|
-
return self._handleReplayTransaction(inputValue,
|
|
14861
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
14069
14862
|
});
|
|
14070
14863
|
}
|
|
14071
14864
|
});
|
|
@@ -14082,7 +14875,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14082
14875
|
inputValue,
|
|
14083
14876
|
isPreAppStart
|
|
14084
14877
|
}, (spanInfo) => {
|
|
14085
|
-
return self._handleRecordTransaction(spanInfo, originalCommit, connection, arguments,
|
|
14878
|
+
return self._handleRecordTransaction(spanInfo, originalCommit, connection, arguments, actualCallback);
|
|
14086
14879
|
});
|
|
14087
14880
|
},
|
|
14088
14881
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -14094,11 +14887,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14094
14887
|
_patchRollback(connection) {
|
|
14095
14888
|
const self = this;
|
|
14096
14889
|
return (originalRollback) => {
|
|
14097
|
-
return function rollback(
|
|
14890
|
+
return function rollback(optionsOrCallback, callbackArg) {
|
|
14891
|
+
let actualCallback;
|
|
14892
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14893
|
+
else actualCallback = callbackArg;
|
|
14098
14894
|
const inputValue = { query: "ROLLBACK" };
|
|
14099
14895
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
14100
14896
|
noOpRequestHandler: () => {
|
|
14101
|
-
if (
|
|
14897
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
14102
14898
|
},
|
|
14103
14899
|
isServerRequest: false,
|
|
14104
14900
|
replayModeHandler: () => {
|
|
@@ -14112,7 +14908,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14112
14908
|
inputValue,
|
|
14113
14909
|
isPreAppStart: false
|
|
14114
14910
|
}, (spanInfo) => {
|
|
14115
|
-
return self._handleReplayTransaction(inputValue,
|
|
14911
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
14116
14912
|
});
|
|
14117
14913
|
}
|
|
14118
14914
|
});
|
|
@@ -14129,7 +14925,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14129
14925
|
inputValue,
|
|
14130
14926
|
isPreAppStart
|
|
14131
14927
|
}, (spanInfo) => {
|
|
14132
|
-
return self._handleRecordTransaction(spanInfo, originalRollback, connection, arguments,
|
|
14928
|
+
return self._handleRecordTransaction(spanInfo, originalRollback, connection, arguments, actualCallback);
|
|
14133
14929
|
});
|
|
14134
14930
|
},
|
|
14135
14931
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -14162,7 +14958,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14162
14958
|
const argsArray = Array.from(args);
|
|
14163
14959
|
const callbackIndex = argsArray.findIndex((arg) => typeof arg === "function");
|
|
14164
14960
|
if (callbackIndex !== -1) {
|
|
14165
|
-
const originalCallback =
|
|
14961
|
+
const originalCallback = argsArray[callbackIndex];
|
|
14166
14962
|
argsArray[callbackIndex] = function(err) {
|
|
14167
14963
|
if (err) try {
|
|
14168
14964
|
SpanUtils.endSpan(spanInfo.span, {
|
|
@@ -14191,7 +14987,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14191
14987
|
callback(null);
|
|
14192
14988
|
});
|
|
14193
14989
|
}
|
|
14194
|
-
_handleRecordPoolGetConnectionInSpan(spanInfo, originalGetConnection, callback,
|
|
14990
|
+
_handleRecordPoolGetConnectionInSpan(spanInfo, originalGetConnection, callback, poolContext) {
|
|
14195
14991
|
const self = this;
|
|
14196
14992
|
if (callback) {
|
|
14197
14993
|
const wrappedCallback = (error, connection) => {
|
|
@@ -14216,11 +15012,11 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14216
15012
|
} });
|
|
14217
15013
|
SpanUtils.endSpan(spanInfo.span, { code: import_src$23.SpanStatusCode.OK });
|
|
14218
15014
|
}
|
|
14219
|
-
return callback(error, connection);
|
|
15015
|
+
return import_src$23.context.bind(spanInfo.context, callback)(error, connection);
|
|
14220
15016
|
};
|
|
14221
|
-
return originalGetConnection.call(
|
|
15017
|
+
return originalGetConnection.call(poolContext, wrappedCallback);
|
|
14222
15018
|
} else try {
|
|
14223
|
-
const result = originalGetConnection.call(
|
|
15019
|
+
const result = originalGetConnection.call(poolContext);
|
|
14224
15020
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
14225
15021
|
connected: true,
|
|
14226
15022
|
hasConnection: true
|
|
@@ -14235,20 +15031,28 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14235
15031
|
throw error;
|
|
14236
15032
|
}
|
|
14237
15033
|
}
|
|
14238
|
-
_handleNoOpReplayGetConnection(callback) {
|
|
15034
|
+
_handleNoOpReplayGetConnection(pool, callback) {
|
|
14239
15035
|
logger.debug(`[MysqlInstrumentation] Background getConnection detected, returning mock connection`);
|
|
14240
|
-
const mockConnection = new TdMysqlConnectionMock(this, "pool");
|
|
15036
|
+
const mockConnection = new TdMysqlConnectionMock(this, "pool", void 0, pool);
|
|
14241
15037
|
if (callback) {
|
|
14242
|
-
process.nextTick(() =>
|
|
15038
|
+
process.nextTick(() => {
|
|
15039
|
+
pool.emit("connection", mockConnection);
|
|
15040
|
+
pool.emit("acquire", mockConnection);
|
|
15041
|
+
callback(null, mockConnection);
|
|
15042
|
+
});
|
|
14243
15043
|
return;
|
|
14244
15044
|
}
|
|
14245
15045
|
return mockConnection;
|
|
14246
15046
|
}
|
|
14247
|
-
_handleReplayPoolGetConnection(spanInfo, callback) {
|
|
15047
|
+
_handleReplayPoolGetConnection(pool, spanInfo, callback) {
|
|
14248
15048
|
logger.debug(`[MysqlInstrumentation] Replaying MySQL Pool getConnection`);
|
|
14249
|
-
const mockConnection = new TdMysqlConnectionMock(this, "pool", spanInfo);
|
|
15049
|
+
const mockConnection = new TdMysqlConnectionMock(this, "pool", spanInfo, pool);
|
|
14250
15050
|
if (callback) {
|
|
14251
|
-
process.nextTick(() =>
|
|
15051
|
+
process.nextTick(() => {
|
|
15052
|
+
pool.emit("connection", mockConnection);
|
|
15053
|
+
pool.emit("acquire", mockConnection);
|
|
15054
|
+
callback(null, mockConnection);
|
|
15055
|
+
});
|
|
14252
15056
|
return;
|
|
14253
15057
|
}
|
|
14254
15058
|
return mockConnection;
|
|
@@ -14481,6 +15285,122 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14481
15285
|
});
|
|
14482
15286
|
return readableStream;
|
|
14483
15287
|
}
|
|
15288
|
+
/**
|
|
15289
|
+
* Get wrapper function for PoolNamespace.query method
|
|
15290
|
+
* This handles queries made via poolCluster.of("pattern").query()
|
|
15291
|
+
*/
|
|
15292
|
+
_getPoolNamespaceQueryPatchFn() {
|
|
15293
|
+
const self = this;
|
|
15294
|
+
return (originalQuery) => {
|
|
15295
|
+
return function query(...args) {
|
|
15296
|
+
const firstArg = args[0];
|
|
15297
|
+
const hasInternalCallback = firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function";
|
|
15298
|
+
if (self.mode === TuskDriftMode.REPLAY) {
|
|
15299
|
+
let sql;
|
|
15300
|
+
let values;
|
|
15301
|
+
let callback;
|
|
15302
|
+
let options = {};
|
|
15303
|
+
if (self.createQuery) try {
|
|
15304
|
+
const queryObj = self.createQuery(...args);
|
|
15305
|
+
sql = queryObj.sql;
|
|
15306
|
+
values = queryObj.values;
|
|
15307
|
+
options = { nestTables: queryObj.nestTables };
|
|
15308
|
+
callback = args.find((arg) => typeof arg === "function");
|
|
15309
|
+
if (!callback && hasInternalCallback) callback = firstArg._callback;
|
|
15310
|
+
} catch (error) {
|
|
15311
|
+
({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
15312
|
+
}
|
|
15313
|
+
else ({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
15314
|
+
const inputValue = {
|
|
15315
|
+
sql,
|
|
15316
|
+
values,
|
|
15317
|
+
options: options.nestTables ? { nestTables: options.nestTables } : void 0
|
|
15318
|
+
};
|
|
15319
|
+
const stackTrace = captureStackTrace(["MysqlInstrumentation"]);
|
|
15320
|
+
return handleReplayMode({
|
|
15321
|
+
noOpRequestHandler: () => {
|
|
15322
|
+
return self.queryMock.handleNoOpReplayQuery({
|
|
15323
|
+
sql,
|
|
15324
|
+
values,
|
|
15325
|
+
callback,
|
|
15326
|
+
options
|
|
15327
|
+
});
|
|
15328
|
+
},
|
|
15329
|
+
isServerRequest: false,
|
|
15330
|
+
replayModeHandler: () => {
|
|
15331
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalQuery.apply(this, args), {
|
|
15332
|
+
name: "mysql.query",
|
|
15333
|
+
kind: import_src$23.SpanKind.CLIENT,
|
|
15334
|
+
submodule: "query",
|
|
15335
|
+
packageType: PackageType.MYSQL,
|
|
15336
|
+
packageName: "mysql",
|
|
15337
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
15338
|
+
inputValue,
|
|
15339
|
+
isPreAppStart: false
|
|
15340
|
+
}, (spanInfo) => {
|
|
15341
|
+
const queryEmitter = self.queryMock.handleReplayQuery({
|
|
15342
|
+
sql,
|
|
15343
|
+
values,
|
|
15344
|
+
callback,
|
|
15345
|
+
options
|
|
15346
|
+
}, inputValue, spanInfo, stackTrace);
|
|
15347
|
+
if (queryEmitter && typeof queryEmitter === "object") queryEmitter.stream = function(streamOptions) {
|
|
15348
|
+
return self._createReplayStreamForQuery(inputValue, spanInfo, stackTrace, queryEmitter, streamOptions);
|
|
15349
|
+
};
|
|
15350
|
+
return queryEmitter;
|
|
15351
|
+
});
|
|
15352
|
+
}
|
|
15353
|
+
});
|
|
15354
|
+
} else if (self.mode === TuskDriftMode.RECORD) return originalQuery.apply(this, args);
|
|
15355
|
+
else return originalQuery.apply(this, args);
|
|
15356
|
+
};
|
|
15357
|
+
};
|
|
15358
|
+
}
|
|
15359
|
+
/**
|
|
15360
|
+
* Get wrapper function for PoolNamespace.getConnection method
|
|
15361
|
+
* This handles connections obtained via poolCluster.of("pattern").getConnection()
|
|
15362
|
+
*/
|
|
15363
|
+
_getPoolNamespaceGetConnectionPatchFn() {
|
|
15364
|
+
const self = this;
|
|
15365
|
+
return (originalGetConnection) => {
|
|
15366
|
+
return function getConnection(callback) {
|
|
15367
|
+
const namespace = this;
|
|
15368
|
+
const inputValue = { clientType: "poolNamespace" };
|
|
15369
|
+
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
15370
|
+
noOpRequestHandler: () => {
|
|
15371
|
+
const mockConnection = new TdMysqlConnectionMock(self, "pool", void 0, void 0);
|
|
15372
|
+
if (callback) {
|
|
15373
|
+
process.nextTick(() => callback(null, mockConnection));
|
|
15374
|
+
return;
|
|
15375
|
+
}
|
|
15376
|
+
return mockConnection;
|
|
15377
|
+
},
|
|
15378
|
+
isServerRequest: false,
|
|
15379
|
+
replayModeHandler: () => {
|
|
15380
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalGetConnection.apply(namespace, [callback]), {
|
|
15381
|
+
name: `mysql.poolNamespace.getConnection`,
|
|
15382
|
+
kind: import_src$23.SpanKind.CLIENT,
|
|
15383
|
+
submodule: "getConnection",
|
|
15384
|
+
packageName: "mysql",
|
|
15385
|
+
packageType: PackageType.MYSQL,
|
|
15386
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
15387
|
+
inputValue,
|
|
15388
|
+
isPreAppStart: false
|
|
15389
|
+
}, (spanInfo) => {
|
|
15390
|
+
const mockConnection = new TdMysqlConnectionMock(self, "pool", spanInfo, void 0);
|
|
15391
|
+
if (callback) {
|
|
15392
|
+
process.nextTick(() => callback(null, mockConnection));
|
|
15393
|
+
return;
|
|
15394
|
+
}
|
|
15395
|
+
return mockConnection;
|
|
15396
|
+
});
|
|
15397
|
+
}
|
|
15398
|
+
});
|
|
15399
|
+
else if (self.mode === TuskDriftMode.RECORD) return originalGetConnection.apply(namespace, [callback]);
|
|
15400
|
+
else return originalGetConnection.apply(namespace, [callback]);
|
|
15401
|
+
};
|
|
15402
|
+
};
|
|
15403
|
+
}
|
|
14484
15404
|
_wrap(target, propertyName, wrapper) {
|
|
14485
15405
|
wrap(target, propertyName, wrapper);
|
|
14486
15406
|
}
|
|
@@ -19552,13 +20472,6 @@ var NextjsInstrumentation = class extends TdInstrumentationBase {
|
|
|
19552
20472
|
return originalHandleRequest.call(this, req, res, parsedUrl);
|
|
19553
20473
|
}
|
|
19554
20474
|
logger.debug(`[NextjsInstrumentation] Setting replay trace id`, replayTraceId);
|
|
19555
|
-
if (self.replayHooks.extractShouldFetchEnvVars(req)) try {
|
|
19556
|
-
const envVars = self.tuskDrift.requestEnvVarsSync(replayTraceId);
|
|
19557
|
-
EnvVarTracker.setEnvVars(replayTraceId, envVars);
|
|
19558
|
-
logger.debug(`[NextjsInstrumentation] Fetched env vars from CLI for trace ${replayTraceId}`);
|
|
19559
|
-
} catch (error) {
|
|
19560
|
-
logger.error(`[NextjsInstrumentation] Failed to fetch env vars from CLI:`, error);
|
|
19561
|
-
}
|
|
19562
20475
|
const ctxWithReplayTraceId = SpanUtils.setCurrentReplayTraceId(replayTraceId);
|
|
19563
20476
|
if (!ctxWithReplayTraceId) throw new Error("Error setting current replay trace id");
|
|
19564
20477
|
return import_src$11.context.with(ctxWithReplayTraceId, () => {
|
|
@@ -19713,10 +20626,8 @@ var NextjsInstrumentation = class extends TdInstrumentationBase {
|
|
|
19713
20626
|
decodedType: getDecodedType(outputValue.headers?.["content-type"] || "")
|
|
19714
20627
|
},
|
|
19715
20628
|
headers: { matchImportance: 0 }
|
|
19716
|
-
}
|
|
19717
|
-
metadata: { ENV_VARS: EnvVarTracker.getEnvVars(spanInfo.traceId) }
|
|
20629
|
+
}
|
|
19718
20630
|
});
|
|
19719
|
-
EnvVarTracker.clearEnvVars(spanInfo.traceId);
|
|
19720
20631
|
const status = (capturedStatusCode || 200) >= 400 ? {
|
|
19721
20632
|
code: import_src$11.SpanStatusCode.ERROR,
|
|
19722
20633
|
message: `HTTP ${capturedStatusCode}`
|
|
@@ -19754,6 +20665,7 @@ var NextjsInstrumentation = class extends TdInstrumentationBase {
|
|
|
19754
20665
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
19755
20666
|
submoduleName: completeInputValue.method,
|
|
19756
20667
|
inputValue: completeInputValue,
|
|
20668
|
+
environment: self.tuskDrift.getEnvironment(),
|
|
19757
20669
|
outputValue,
|
|
19758
20670
|
inputSchema,
|
|
19759
20671
|
outputSchema,
|
|
@@ -24243,7 +25155,7 @@ var SpanTransformer = class SpanTransformer {
|
|
|
24243
25155
|
* Return type is derived from protobuf schema but uses clean JSON.
|
|
24244
25156
|
* We use JSON because serialized protobuf is extremely verbose and not readable.
|
|
24245
25157
|
*/
|
|
24246
|
-
static transformSpanToCleanJSON(span) {
|
|
25158
|
+
static transformSpanToCleanJSON(span, environment) {
|
|
24247
25159
|
const isRootSpan = !span.parentSpanId || span.kind === import_src$9.SpanKind.SERVER;
|
|
24248
25160
|
const attributes = span.attributes;
|
|
24249
25161
|
const packageName = SpanTransformer.extractPackageName(attributes);
|
|
@@ -24287,6 +25199,7 @@ var SpanTransformer = class SpanTransformer {
|
|
|
24287
25199
|
instrumentationName,
|
|
24288
25200
|
submoduleName: submoduleName || "",
|
|
24289
25201
|
packageType: attributes[TdSpanAttributes.PACKAGE_TYPE] || void 0,
|
|
25202
|
+
environment,
|
|
24290
25203
|
inputValue: inputData,
|
|
24291
25204
|
outputValue: outputData,
|
|
24292
25205
|
inputSchema,
|
|
@@ -24750,7 +25663,7 @@ var ApiSpanAdapter = class {
|
|
|
24750
25663
|
const protoSpans = spans.map((span) => this.transformSpanToProtobuf(span));
|
|
24751
25664
|
const request = {
|
|
24752
25665
|
observableServiceId: this.observableServiceId,
|
|
24753
|
-
environment: this.environment,
|
|
25666
|
+
environment: this.environment || "",
|
|
24754
25667
|
sdkVersion: this.sdkVersion,
|
|
24755
25668
|
sdkInstanceId: this.sdkInstanceId,
|
|
24756
25669
|
spans: protoSpans
|
|
@@ -24777,6 +25690,7 @@ var ApiSpanAdapter = class {
|
|
|
24777
25690
|
instrumentationName: cleanSpan.instrumentationName,
|
|
24778
25691
|
submoduleName: cleanSpan.submoduleName,
|
|
24779
25692
|
packageType: cleanSpan.packageType || PackageType.UNSPECIFIED,
|
|
25693
|
+
environment: this.environment,
|
|
24780
25694
|
inputValue: toStruct(cleanSpan.inputValue),
|
|
24781
25695
|
outputValue: toStruct(cleanSpan.outputValue),
|
|
24782
25696
|
inputSchema: cleanSpan.inputSchema,
|
|
@@ -24802,12 +25716,12 @@ var ApiSpanAdapter = class {
|
|
|
24802
25716
|
}
|
|
24803
25717
|
mapSpanKind(kind) {
|
|
24804
25718
|
switch (kind) {
|
|
24805
|
-
case import_src$7.SpanKind.CLIENT: return SpanKind.CLIENT;
|
|
24806
|
-
case import_src$7.SpanKind.SERVER: return SpanKind.SERVER;
|
|
24807
|
-
case import_src$7.SpanKind.PRODUCER: return SpanKind.PRODUCER;
|
|
24808
|
-
case import_src$7.SpanKind.CONSUMER: return SpanKind.CONSUMER;
|
|
24809
|
-
case import_src$7.SpanKind.INTERNAL: return SpanKind.INTERNAL;
|
|
24810
|
-
default: return SpanKind.UNSPECIFIED;
|
|
25719
|
+
case import_src$7.SpanKind.CLIENT: return SpanKind$1.CLIENT;
|
|
25720
|
+
case import_src$7.SpanKind.SERVER: return SpanKind$1.SERVER;
|
|
25721
|
+
case import_src$7.SpanKind.PRODUCER: return SpanKind$1.PRODUCER;
|
|
25722
|
+
case import_src$7.SpanKind.CONSUMER: return SpanKind$1.CONSUMER;
|
|
25723
|
+
case import_src$7.SpanKind.INTERNAL: return SpanKind$1.INTERNAL;
|
|
25724
|
+
default: return SpanKind$1.UNSPECIFIED;
|
|
24811
25725
|
}
|
|
24812
25726
|
}
|
|
24813
25727
|
async shutdown() {
|
|
@@ -24822,6 +25736,7 @@ var TdSpanExporter = class {
|
|
|
24822
25736
|
constructor(config) {
|
|
24823
25737
|
this.adapters = [];
|
|
24824
25738
|
this.mode = config.mode;
|
|
25739
|
+
this.environment = config.environment;
|
|
24825
25740
|
this.setupDefaultAdapters(config);
|
|
24826
25741
|
logger.debug(`TdSpanExporter initialized with ${this.adapters.length} adapter(s)`);
|
|
24827
25742
|
}
|
|
@@ -24905,7 +25820,7 @@ var TdSpanExporter = class {
|
|
|
24905
25820
|
return true;
|
|
24906
25821
|
});
|
|
24907
25822
|
logger.debug(`Filtered ${filteredSpansBasedOnLibraryName.length - filteredBlockedSpans.length} blocked/oversized span(s), ${filteredBlockedSpans.length} remaining`);
|
|
24908
|
-
const cleanSpans = filteredBlockedSpans.map((span) => SpanTransformer.transformSpanToCleanJSON(span));
|
|
25823
|
+
const cleanSpans = filteredBlockedSpans.map((span) => SpanTransformer.transformSpanToCleanJSON(span, this.environment));
|
|
24909
25824
|
if (this.adapters.length === 0) {
|
|
24910
25825
|
logger.debug("No adapters configured");
|
|
24911
25826
|
resultCallback({ code: import_src$5.ExportResultCode.SUCCESS });
|
|
@@ -32056,7 +32971,7 @@ var require_src = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/sdk-
|
|
|
32056
32971
|
//#endregion
|
|
32057
32972
|
//#region package.json
|
|
32058
32973
|
var import_src$1 = /* @__PURE__ */ __toESM(require_src(), 1);
|
|
32059
|
-
var version = "0.1.
|
|
32974
|
+
var version = "0.1.19";
|
|
32060
32975
|
|
|
32061
32976
|
//#endregion
|
|
32062
32977
|
//#region src/version.ts
|
|
@@ -32064,7 +32979,7 @@ const SDK_VERSION = version;
|
|
|
32064
32979
|
const MIN_CLI_VERSION = "0.1.0";
|
|
32065
32980
|
|
|
32066
32981
|
//#endregion
|
|
32067
|
-
//#region node_modules/@use-tusk/drift-schemas/dist/communication-
|
|
32982
|
+
//#region node_modules/@use-tusk/drift-schemas/dist/communication-BY2KZhrg.js
|
|
32068
32983
|
var import_commonjs = /* @__PURE__ */ __toESM(require_commonjs$1(), 1);
|
|
32069
32984
|
var import_commonjs$1 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
|
|
32070
32985
|
/**
|
|
@@ -33208,12 +34123,6 @@ var ProtobufCommunicator = class ProtobufCommunicator {
|
|
|
33208
34123
|
});
|
|
33209
34124
|
await this.sendProtobufMessage(sdkMessage);
|
|
33210
34125
|
}
|
|
33211
|
-
getStackTrace() {
|
|
33212
|
-
Error.stackTraceLimit = 100;
|
|
33213
|
-
const s = (/* @__PURE__ */ new Error()).stack || "";
|
|
33214
|
-
Error.stackTraceLimit = 10;
|
|
33215
|
-
return s.split("\n").slice(2).filter((l) => !l.includes("ProtobufCommunicator")).join("\n");
|
|
33216
|
-
}
|
|
33217
34126
|
async requestMockAsync(mockRequest) {
|
|
33218
34127
|
const requestId = this.generateRequestId();
|
|
33219
34128
|
const cleanSpan = mockRequest.outboundSpan ? this.cleanSpan(mockRequest.outboundSpan) : void 0;
|
|
@@ -33246,7 +34155,7 @@ var ProtobufCommunicator = class ProtobufCommunicator {
|
|
|
33246
34155
|
/**
|
|
33247
34156
|
* Generic synchronous request handler that spawns a child process.
|
|
33248
34157
|
* @param sdkMessage The SDK message to send
|
|
33249
|
-
* @param filePrefix Prefix for temporary files (e.g., '
|
|
34158
|
+
* @param filePrefix Prefix for temporary files (e.g., 'mock')
|
|
33250
34159
|
* @param responseHandler Function to extract and return the desired response
|
|
33251
34160
|
*/
|
|
33252
34161
|
executeSyncRequest(sdkMessage, filePrefix, responseHandler) {
|
|
@@ -33315,35 +34224,6 @@ var ProtobufCommunicator = class ProtobufCommunicator {
|
|
|
33315
34224
|
}
|
|
33316
34225
|
}
|
|
33317
34226
|
/**
|
|
33318
|
-
* Request environment variables from CLI synchronously using a child process.
|
|
33319
|
-
* This blocks the main thread, so it should be used carefully.
|
|
33320
|
-
* Similar to requestMockSync but for environment variables.
|
|
33321
|
-
*/
|
|
33322
|
-
requestEnvVarsSync(traceTestServerSpanId) {
|
|
33323
|
-
const requestId = this.generateRequestId();
|
|
33324
|
-
const envVarRequest = EnvVarRequest.create({ traceTestServerSpanId });
|
|
33325
|
-
const sdkMessage = SDKMessage.create({
|
|
33326
|
-
type: MessageType$1.ENV_VAR_REQUEST,
|
|
33327
|
-
requestId,
|
|
33328
|
-
payload: {
|
|
33329
|
-
oneofKind: "envVarRequest",
|
|
33330
|
-
envVarRequest
|
|
33331
|
-
}
|
|
33332
|
-
});
|
|
33333
|
-
logger.debug(`[ProtobufCommunicator] Requesting env vars (sync) for trace: ${traceTestServerSpanId}`);
|
|
33334
|
-
return this.executeSyncRequest(sdkMessage, "envvar", (cliMessage) => {
|
|
33335
|
-
if (cliMessage.payload.oneofKind !== "envVarResponse") throw new Error(`Unexpected response type: ${cliMessage.type}`);
|
|
33336
|
-
const envVarResponse = cliMessage.payload.envVarResponse;
|
|
33337
|
-
if (!envVarResponse) throw new Error("No env var response received");
|
|
33338
|
-
const envVars = {};
|
|
33339
|
-
if (envVarResponse.envVars) Object.entries(envVarResponse.envVars).forEach(([key, value]) => {
|
|
33340
|
-
envVars[key] = value;
|
|
33341
|
-
});
|
|
33342
|
-
logger.debug(`[ProtobufCommunicator] Received env vars (sync), count: ${Object.keys(envVars).length}`);
|
|
33343
|
-
return envVars;
|
|
33344
|
-
});
|
|
33345
|
-
}
|
|
33346
|
-
/**
|
|
33347
34227
|
* This function uses a separate Node.js child process to communicate with the CLI over a socket.
|
|
33348
34228
|
* The child process creates its own connection and event loop, allowing proper async socket handling.
|
|
33349
34229
|
* The parent process blocks synchronously waiting for the child to complete.
|
|
@@ -33554,22 +34434,6 @@ var ProtobufCommunicator = class ProtobufCommunicator {
|
|
|
33554
34434
|
error: mockResponse.error || "Mock not found"
|
|
33555
34435
|
});
|
|
33556
34436
|
}
|
|
33557
|
-
if (message.payload.oneofKind === "envVarResponse") {
|
|
33558
|
-
const envVarResponse = message.payload.envVarResponse;
|
|
33559
|
-
logger.debug(`[ProtobufCommunicator] Received env var response for requestId: ${requestId}`);
|
|
33560
|
-
const pendingRequest = this.pendingRequests.get(requestId);
|
|
33561
|
-
if (!pendingRequest) {
|
|
33562
|
-
logger.warn("[ProtobufCommunicator] received env var response for unknown request:", requestId);
|
|
33563
|
-
return;
|
|
33564
|
-
}
|
|
33565
|
-
this.pendingRequests.delete(requestId);
|
|
33566
|
-
const envVars = {};
|
|
33567
|
-
if (envVarResponse?.envVars) Object.entries(envVarResponse.envVars).forEach(([key, value]) => {
|
|
33568
|
-
envVars[key] = value;
|
|
33569
|
-
});
|
|
33570
|
-
pendingRequest.resolve(envVars);
|
|
33571
|
-
return;
|
|
33572
|
-
}
|
|
33573
34437
|
}
|
|
33574
34438
|
/**
|
|
33575
34439
|
* Extract response data from MockResponse
|
|
@@ -33869,10 +34733,6 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
33869
34733
|
enabled: true,
|
|
33870
34734
|
mode: this.mode
|
|
33871
34735
|
});
|
|
33872
|
-
new EnvInstrumentation({
|
|
33873
|
-
enabled: this.config.recording?.enable_env_var_recording || false,
|
|
33874
|
-
mode: this.mode
|
|
33875
|
-
});
|
|
33876
34736
|
new PostgresInstrumentation({
|
|
33877
34737
|
enabled: true,
|
|
33878
34738
|
mode: this.mode
|
|
@@ -33920,7 +34780,7 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
33920
34780
|
observableServiceId: this.config.service?.id,
|
|
33921
34781
|
apiKey: this.initParams.apiKey,
|
|
33922
34782
|
tuskBackendBaseUrl: this.config.tusk_api?.url || "https://api.usetusk.ai",
|
|
33923
|
-
environment: this.initParams.env
|
|
34783
|
+
environment: this.initParams.env,
|
|
33924
34784
|
sdkVersion: SDK_VERSION,
|
|
33925
34785
|
sdkInstanceId: this.generateSdkInstanceId()
|
|
33926
34786
|
});
|
|
@@ -33938,6 +34798,34 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
33938
34798
|
generateSdkInstanceId() {
|
|
33939
34799
|
return `sdk-${OriginalGlobalUtils.getOriginalDate().getTime()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
33940
34800
|
}
|
|
34801
|
+
/**
|
|
34802
|
+
* Creates a pre-app-start span containing a snapshot of all environment variables.
|
|
34803
|
+
* Only runs in RECORD mode when env var recording is enabled.
|
|
34804
|
+
*/
|
|
34805
|
+
createEnvVarsSnapshot() {
|
|
34806
|
+
if (this.mode !== TuskDriftMode.RECORD || !this.config.recording?.enable_env_var_recording) return;
|
|
34807
|
+
try {
|
|
34808
|
+
const envVarsSnapshot = {};
|
|
34809
|
+
for (const key of Object.keys(process.env)) envVarsSnapshot[key] = process.env[key];
|
|
34810
|
+
logger.debug(`Creating env vars snapshot with ${Object.keys(envVarsSnapshot).length} variables`);
|
|
34811
|
+
SpanUtils.createAndExecuteSpan(this.mode, () => {}, {
|
|
34812
|
+
name: "ENV_VARS_SNAPSHOT",
|
|
34813
|
+
kind: import_src.SpanKind.INTERNAL,
|
|
34814
|
+
packageName: "process.env",
|
|
34815
|
+
packageType: PackageType.UNSPECIFIED,
|
|
34816
|
+
instrumentationName: "TuskDriftCore",
|
|
34817
|
+
submodule: "env",
|
|
34818
|
+
inputValue: {},
|
|
34819
|
+
outputValue: { ENV_VARS: envVarsSnapshot },
|
|
34820
|
+
isPreAppStart: true
|
|
34821
|
+
}, (spanInfo) => {
|
|
34822
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src.SpanStatusCode.OK });
|
|
34823
|
+
logger.debug(`Env vars snapshot span created: ${spanInfo.spanId}`);
|
|
34824
|
+
});
|
|
34825
|
+
} catch (error) {
|
|
34826
|
+
logger.error("Failed to create env vars snapshot:", error);
|
|
34827
|
+
}
|
|
34828
|
+
}
|
|
33941
34829
|
initialize(initParams) {
|
|
33942
34830
|
initializeGlobalLogger({
|
|
33943
34831
|
logLevel: initParams.logLevel || "info",
|
|
@@ -34014,6 +34902,7 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
34014
34902
|
logger.debug(`Base directory: ${baseDirectory}`);
|
|
34015
34903
|
this.registerDefaultInstrumentations();
|
|
34016
34904
|
this.initializeTracing({ baseDirectory });
|
|
34905
|
+
this.createEnvVarsSnapshot();
|
|
34017
34906
|
this.initialized = true;
|
|
34018
34907
|
logger.info("SDK initialized successfully");
|
|
34019
34908
|
}
|
|
@@ -34077,30 +34966,6 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
34077
34966
|
};
|
|
34078
34967
|
}
|
|
34079
34968
|
}
|
|
34080
|
-
/**
|
|
34081
|
-
* Request environment variables from CLI for a specific trace (synchronously).
|
|
34082
|
-
* This blocks the main thread, so it should be used carefully.
|
|
34083
|
-
*/
|
|
34084
|
-
requestEnvVarsSync(traceTestServerSpanId) {
|
|
34085
|
-
if (!this.isConnectedWithCLI) {
|
|
34086
|
-
logger.error("Requesting sync env vars but CLI is not ready yet");
|
|
34087
|
-
throw new Error("Requesting sync env vars but CLI is not ready yet");
|
|
34088
|
-
}
|
|
34089
|
-
if (!this.communicator || this.mode !== TuskDriftMode.REPLAY) {
|
|
34090
|
-
logger.debug("Cannot request env vars: not in replay mode or no CLI connection");
|
|
34091
|
-
return {};
|
|
34092
|
-
}
|
|
34093
|
-
try {
|
|
34094
|
-
logger.debug(`Requesting env vars (sync) for trace: ${traceTestServerSpanId}`);
|
|
34095
|
-
const envVars = this.communicator.requestEnvVarsSync(traceTestServerSpanId);
|
|
34096
|
-
logger.debug(`Received env vars from CLI, count: ${Object.keys(envVars).length}`);
|
|
34097
|
-
logger.debug(`First 10 env vars: ${JSON.stringify(Object.keys(envVars).slice(0, 10), null, 2)}`);
|
|
34098
|
-
return envVars;
|
|
34099
|
-
} catch (error) {
|
|
34100
|
-
logger.error(`[TuskDrift] Error requesting env vars from CLI:`, error);
|
|
34101
|
-
return {};
|
|
34102
|
-
}
|
|
34103
|
-
}
|
|
34104
34969
|
requestMockSync(mockRequest) {
|
|
34105
34970
|
if (!this.isConnectedWithCLI) {
|
|
34106
34971
|
logger.error("Requesting sync mock but CLI is not ready yet");
|
|
@@ -34152,6 +35017,9 @@ var TuskDriftCore = class TuskDriftCore {
|
|
|
34152
35017
|
getInitParams() {
|
|
34153
35018
|
return this.initParams;
|
|
34154
35019
|
}
|
|
35020
|
+
getEnvironment() {
|
|
35021
|
+
return this.initParams.env;
|
|
35022
|
+
}
|
|
34155
35023
|
getTracer() {
|
|
34156
35024
|
return import_src.trace.getTracer(TD_INSTRUMENTATION_LIBRARY_NAME);
|
|
34157
35025
|
}
|