@use-tusk/drift-node-sdk 0.1.18 → 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 +1517 -481
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1517 -481
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4989,31 +4989,31 @@ var require_SamplingResult = /* @__PURE__ */ __commonJS({ "node_modules/@opentel
|
|
|
4989
4989
|
var require_span_kind = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/api/build/src/trace/span_kind.js": ((exports) => {
|
|
4990
4990
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4991
4991
|
exports.SpanKind = void 0;
|
|
4992
|
-
(function(SpanKind$
|
|
4992
|
+
(function(SpanKind$26) {
|
|
4993
4993
|
/** Default value. Indicates that the span is used internally. */
|
|
4994
|
-
SpanKind$
|
|
4994
|
+
SpanKind$26[SpanKind$26["INTERNAL"] = 0] = "INTERNAL";
|
|
4995
4995
|
/**
|
|
4996
4996
|
* Indicates that the span covers server-side handling of an RPC or other
|
|
4997
4997
|
* remote request.
|
|
4998
4998
|
*/
|
|
4999
|
-
SpanKind$
|
|
4999
|
+
SpanKind$26[SpanKind$26["SERVER"] = 1] = "SERVER";
|
|
5000
5000
|
/**
|
|
5001
5001
|
* Indicates that the span covers the client-side wrapper around an RPC or
|
|
5002
5002
|
* other remote request.
|
|
5003
5003
|
*/
|
|
5004
|
-
SpanKind$
|
|
5004
|
+
SpanKind$26[SpanKind$26["CLIENT"] = 2] = "CLIENT";
|
|
5005
5005
|
/**
|
|
5006
5006
|
* Indicates that the span describes producer sending a message to a
|
|
5007
5007
|
* broker. Unlike client and server, there is no direct critical path latency
|
|
5008
5008
|
* relationship between producer and consumer spans.
|
|
5009
5009
|
*/
|
|
5010
|
-
SpanKind$
|
|
5010
|
+
SpanKind$26[SpanKind$26["PRODUCER"] = 3] = "PRODUCER";
|
|
5011
5011
|
/**
|
|
5012
5012
|
* Indicates that the span describes consumer receiving a message from a
|
|
5013
5013
|
* broker. Unlike client and server, there is no direct critical path latency
|
|
5014
5014
|
* relationship between producer and consumer spans.
|
|
5015
5015
|
*/
|
|
5016
|
-
SpanKind$
|
|
5016
|
+
SpanKind$26[SpanKind$26["CONSUMER"] = 4] = "CONSUMER";
|
|
5017
5017
|
})(exports.SpanKind || (exports.SpanKind = {}));
|
|
5018
5018
|
}) });
|
|
5019
5019
|
|
|
@@ -5022,20 +5022,20 @@ var require_span_kind = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetr
|
|
|
5022
5022
|
var require_status = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/api/build/src/trace/status.js": ((exports) => {
|
|
5023
5023
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5024
5024
|
exports.SpanStatusCode = void 0;
|
|
5025
|
-
(function(SpanStatusCode$
|
|
5025
|
+
(function(SpanStatusCode$15) {
|
|
5026
5026
|
/**
|
|
5027
5027
|
* The default status.
|
|
5028
5028
|
*/
|
|
5029
|
-
SpanStatusCode$
|
|
5029
|
+
SpanStatusCode$15[SpanStatusCode$15["UNSET"] = 0] = "UNSET";
|
|
5030
5030
|
/**
|
|
5031
5031
|
* The operation has been validated by an Application developer or
|
|
5032
5032
|
* Operator to have completed successfully.
|
|
5033
5033
|
*/
|
|
5034
|
-
SpanStatusCode$
|
|
5034
|
+
SpanStatusCode$15[SpanStatusCode$15["OK"] = 1] = "OK";
|
|
5035
5035
|
/**
|
|
5036
5036
|
* The operation contains an error.
|
|
5037
5037
|
*/
|
|
5038
|
-
SpanStatusCode$
|
|
5038
|
+
SpanStatusCode$15[SpanStatusCode$15["ERROR"] = 2] = "ERROR";
|
|
5039
5039
|
})(exports.SpanStatusCode || (exports.SpanStatusCode = {}));
|
|
5040
5040
|
}) });
|
|
5041
5041
|
|
|
@@ -5684,7 +5684,7 @@ var require_src$7 = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/ap
|
|
|
5684
5684
|
|
|
5685
5685
|
//#endregion
|
|
5686
5686
|
//#region node_modules/@use-tusk/drift-schemas/dist/duration-B3fwb4jB.js
|
|
5687
|
-
var import_src$
|
|
5687
|
+
var import_src$35 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
5688
5688
|
var import_commonjs$9 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
|
|
5689
5689
|
var Duration$Type = class extends import_commonjs$9.MessageType {
|
|
5690
5690
|
constructor() {
|
|
@@ -7008,11 +7008,11 @@ const Trace = new Trace$Type();
|
|
|
7008
7008
|
const toStruct = (obj) => obj ? objectToProtobufStruct(obj) : void 0;
|
|
7009
7009
|
const mapOtToPb = (k) => {
|
|
7010
7010
|
switch (k) {
|
|
7011
|
-
case import_src$
|
|
7012
|
-
case import_src$
|
|
7013
|
-
case import_src$
|
|
7014
|
-
case import_src$
|
|
7015
|
-
case import_src$
|
|
7011
|
+
case import_src$35.SpanKind.INTERNAL: return SpanKind$1.INTERNAL;
|
|
7012
|
+
case import_src$35.SpanKind.SERVER: return SpanKind$1.SERVER;
|
|
7013
|
+
case import_src$35.SpanKind.CLIENT: return SpanKind$1.CLIENT;
|
|
7014
|
+
case import_src$35.SpanKind.PRODUCER: return SpanKind$1.PRODUCER;
|
|
7015
|
+
case import_src$35.SpanKind.CONSUMER: return SpanKind$1.CONSUMER;
|
|
7016
7016
|
default: return SpanKind$1.UNSPECIFIED;
|
|
7017
7017
|
}
|
|
7018
7018
|
};
|
|
@@ -7416,13 +7416,13 @@ var TdInstrumentationNodeModule = class {
|
|
|
7416
7416
|
|
|
7417
7417
|
//#endregion
|
|
7418
7418
|
//#region src/core/types.ts
|
|
7419
|
-
var import_src$
|
|
7419
|
+
var import_src$34 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
7420
7420
|
const TD_INSTRUMENTATION_LIBRARY_NAME = "tusk-drift-sdk";
|
|
7421
|
-
const REPLAY_TRACE_ID_CONTEXT_KEY = (0, import_src$
|
|
7422
|
-
const SPAN_KIND_CONTEXT_KEY = (0, import_src$
|
|
7423
|
-
const IS_PRE_APP_START_CONTEXT_KEY = (0, import_src$
|
|
7424
|
-
const STOP_RECORDING_CHILD_SPANS_CONTEXT_KEY = (0, import_src$
|
|
7425
|
-
const CALLING_LIBRARY_CONTEXT_KEY = (0, import_src$
|
|
7421
|
+
const REPLAY_TRACE_ID_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.replayTraceId");
|
|
7422
|
+
const SPAN_KIND_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.spanKind");
|
|
7423
|
+
const IS_PRE_APP_START_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.isPreAppStart");
|
|
7424
|
+
const STOP_RECORDING_CHILD_SPANS_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.stopRecordingChildSpans");
|
|
7425
|
+
const CALLING_LIBRARY_CONTEXT_KEY = (0, import_src$34.createContextKey)("td.callingLibrary");
|
|
7426
7426
|
let TdSpanAttributes = /* @__PURE__ */ function(TdSpanAttributes$1) {
|
|
7427
7427
|
/**
|
|
7428
7428
|
* Presentational information:
|
|
@@ -7534,7 +7534,7 @@ TraceBlockingManager.instance = null;
|
|
|
7534
7534
|
|
|
7535
7535
|
//#endregion
|
|
7536
7536
|
//#region src/core/tracing/SpanUtils.ts
|
|
7537
|
-
var import_src$
|
|
7537
|
+
var import_src$33 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
7538
7538
|
var SpanUtils = class SpanUtils {
|
|
7539
7539
|
/**
|
|
7540
7540
|
* Creates a new span and returns span info including trace ID and span ID
|
|
@@ -7542,8 +7542,8 @@ var SpanUtils = class SpanUtils {
|
|
|
7542
7542
|
static createSpan(options) {
|
|
7543
7543
|
try {
|
|
7544
7544
|
const tracer = TuskDriftCore.getInstance().getTracer();
|
|
7545
|
-
const parentContext = options.parentContext || import_src$
|
|
7546
|
-
const activeSpan = import_src$
|
|
7545
|
+
const parentContext = options.parentContext || import_src$33.context.active();
|
|
7546
|
+
const activeSpan = import_src$33.trace.getSpan(parentContext);
|
|
7547
7547
|
if (activeSpan) {
|
|
7548
7548
|
const parentTraceId = activeSpan.spanContext().traceId;
|
|
7549
7549
|
if (TraceBlockingManager.getInstance().isTraceBlocked(parentTraceId)) {
|
|
@@ -7552,11 +7552,11 @@ var SpanUtils = class SpanUtils {
|
|
|
7552
7552
|
}
|
|
7553
7553
|
}
|
|
7554
7554
|
const span = tracer.startSpan(options.name, {
|
|
7555
|
-
kind: options.kind || import_src$
|
|
7555
|
+
kind: options.kind || import_src$33.SpanKind.CLIENT,
|
|
7556
7556
|
attributes: options.attributes || {}
|
|
7557
7557
|
}, parentContext);
|
|
7558
7558
|
const spanContext = span.spanContext();
|
|
7559
|
-
const newContext = import_src$
|
|
7559
|
+
const newContext = import_src$33.trace.setSpan(parentContext, span).setValue(SPAN_KIND_CONTEXT_KEY, options.kind).setValue(IS_PRE_APP_START_CONTEXT_KEY, options.isPreAppStart);
|
|
7560
7560
|
return {
|
|
7561
7561
|
traceId: spanContext.traceId,
|
|
7562
7562
|
spanId: spanContext.spanId,
|
|
@@ -7573,7 +7573,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7573
7573
|
* Executes a function within a span context
|
|
7574
7574
|
*/
|
|
7575
7575
|
static withSpan(spanInfo, fn) {
|
|
7576
|
-
return import_src$
|
|
7576
|
+
return import_src$33.context.with(spanInfo.context, fn);
|
|
7577
7577
|
}
|
|
7578
7578
|
/**
|
|
7579
7579
|
* Execute a function within a properly configured span
|
|
@@ -7590,9 +7590,9 @@ var SpanUtils = class SpanUtils {
|
|
|
7590
7590
|
* @returns The result of the function execution
|
|
7591
7591
|
*/
|
|
7592
7592
|
static createAndExecuteSpan(mode, originalFunctionCall, options, fn) {
|
|
7593
|
-
const spanContext = import_src$
|
|
7593
|
+
const spanContext = import_src$33.trace.getActiveSpan()?.spanContext();
|
|
7594
7594
|
if (spanContext) {
|
|
7595
|
-
if (import_src$
|
|
7595
|
+
if (import_src$33.context.active().getValue(STOP_RECORDING_CHILD_SPANS_CONTEXT_KEY)) {
|
|
7596
7596
|
logger.debug(`[SpanUtils] Stopping recording of child spans for span ${spanContext.spanId}, packageName: ${options.packageName}, instrumentationName: ${options.instrumentationName}`);
|
|
7597
7597
|
return originalFunctionCall();
|
|
7598
7598
|
}
|
|
@@ -7631,15 +7631,15 @@ var SpanUtils = class SpanUtils {
|
|
|
7631
7631
|
*/
|
|
7632
7632
|
static getCurrentSpanInfo() {
|
|
7633
7633
|
try {
|
|
7634
|
-
const activeSpan = import_src$
|
|
7634
|
+
const activeSpan = import_src$33.trace.getActiveSpan();
|
|
7635
7635
|
if (!activeSpan) return null;
|
|
7636
7636
|
const spanContext = activeSpan.spanContext();
|
|
7637
7637
|
return {
|
|
7638
7638
|
traceId: spanContext.traceId,
|
|
7639
7639
|
spanId: spanContext.spanId,
|
|
7640
7640
|
span: activeSpan,
|
|
7641
|
-
context: import_src$
|
|
7642
|
-
isPreAppStart: import_src$
|
|
7641
|
+
context: import_src$33.context.active(),
|
|
7642
|
+
isPreAppStart: import_src$33.context.active().getValue(IS_PRE_APP_START_CONTEXT_KEY)
|
|
7643
7643
|
};
|
|
7644
7644
|
} catch (error) {
|
|
7645
7645
|
logger.error("SpanUtils error getting current span info:", error);
|
|
@@ -7703,7 +7703,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7703
7703
|
}
|
|
7704
7704
|
static setCurrentReplayTraceId(replayTraceId) {
|
|
7705
7705
|
try {
|
|
7706
|
-
return import_src$
|
|
7706
|
+
return import_src$33.context.active().setValue(REPLAY_TRACE_ID_CONTEXT_KEY, replayTraceId);
|
|
7707
7707
|
} catch (error) {
|
|
7708
7708
|
logger.error("SpanUtils error setting current replay trace id:", error);
|
|
7709
7709
|
return null;
|
|
@@ -7714,7 +7714,7 @@ var SpanUtils = class SpanUtils {
|
|
|
7714
7714
|
*/
|
|
7715
7715
|
static getCurrentReplayTraceId() {
|
|
7716
7716
|
try {
|
|
7717
|
-
return import_src$
|
|
7717
|
+
return import_src$33.context.active().getValue(REPLAY_TRACE_ID_CONTEXT_KEY);
|
|
7718
7718
|
} catch (error) {
|
|
7719
7719
|
logger.error("SpanUtils error getting current replay trace id:", error);
|
|
7720
7720
|
return null;
|
|
@@ -8363,7 +8363,7 @@ function findMockResponseSync({ mockRequestData, tuskDrift, inputValueSchemaMerg
|
|
|
8363
8363
|
|
|
8364
8364
|
//#endregion
|
|
8365
8365
|
//#region src/instrumentation/libraries/http/mocks/TdMockClientRequest.ts
|
|
8366
|
-
var import_src$
|
|
8366
|
+
var import_src$32 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
8367
8367
|
let ClientRequest;
|
|
8368
8368
|
/**
|
|
8369
8369
|
* Mock ClientRequest implementation for Tusk Drift HTTP replay
|
|
@@ -8534,7 +8534,7 @@ var TdMockClientRequest = class TdMockClientRequest extends events.EventEmitter
|
|
|
8534
8534
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
8535
8535
|
submoduleName: rawInputValue.method,
|
|
8536
8536
|
inputValue,
|
|
8537
|
-
kind: import_src$
|
|
8537
|
+
kind: import_src$32.SpanKind.CLIENT,
|
|
8538
8538
|
stackTrace: this.stackTrace
|
|
8539
8539
|
},
|
|
8540
8540
|
tuskDrift: this.tuskDrift,
|
|
@@ -8704,7 +8704,7 @@ var HttpReplayHooks = class {
|
|
|
8704
8704
|
|
|
8705
8705
|
//#endregion
|
|
8706
8706
|
//#region src/instrumentation/core/utils/modeUtils.ts
|
|
8707
|
-
var import_src$
|
|
8707
|
+
var import_src$31 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
8708
8708
|
/**
|
|
8709
8709
|
* Utility function that abstracts the common record mode pattern of checking for current span context
|
|
8710
8710
|
* and deciding whether to execute record mode logic or just call the original function.
|
|
@@ -8725,7 +8725,7 @@ function handleRecordMode({ originalFunctionCall, recordModeHandler, spanKind })
|
|
|
8725
8725
|
return originalFunctionCall();
|
|
8726
8726
|
}
|
|
8727
8727
|
if (!isAppReady) return recordModeHandler({ isPreAppStart: true });
|
|
8728
|
-
if (!currentSpanInfo && spanKind !== import_src$
|
|
8728
|
+
if (!currentSpanInfo && spanKind !== import_src$31.SpanKind.SERVER || currentSpanInfo?.isPreAppStart) return originalFunctionCall();
|
|
8729
8729
|
else return recordModeHandler({ isPreAppStart: false });
|
|
8730
8730
|
}
|
|
8731
8731
|
/**
|
|
@@ -10205,7 +10205,7 @@ function captureStackTrace(excludeClassNames = []) {
|
|
|
10205
10205
|
|
|
10206
10206
|
//#endregion
|
|
10207
10207
|
//#region src/instrumentation/libraries/http/HttpTransformEngine.ts
|
|
10208
|
-
var import_src$
|
|
10208
|
+
var import_src$30 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
10209
10209
|
/**
|
|
10210
10210
|
* Creates an empty HttpClientInputValue object for dropped spans
|
|
10211
10211
|
*/
|
|
@@ -10258,7 +10258,7 @@ var HttpTransformEngine = class {
|
|
|
10258
10258
|
const testSpan = {
|
|
10259
10259
|
traceId: "",
|
|
10260
10260
|
spanId: "",
|
|
10261
|
-
kind: import_src$
|
|
10261
|
+
kind: import_src$30.SpanKind.SERVER,
|
|
10262
10262
|
protocol: "http",
|
|
10263
10263
|
inputValue: {
|
|
10264
10264
|
method,
|
|
@@ -10281,7 +10281,7 @@ var HttpTransformEngine = class {
|
|
|
10281
10281
|
const testSpan = {
|
|
10282
10282
|
traceId: "",
|
|
10283
10283
|
spanId: "",
|
|
10284
|
-
kind: import_src$
|
|
10284
|
+
kind: import_src$30.SpanKind.CLIENT,
|
|
10285
10285
|
protocol: inputValue.protocol || "http",
|
|
10286
10286
|
inputValue: clonedInputValue
|
|
10287
10287
|
};
|
|
@@ -10308,8 +10308,8 @@ var HttpTransformEngine = class {
|
|
|
10308
10308
|
const matcherFunction = this.compileMatcher(matcher);
|
|
10309
10309
|
if (action.type === "drop") return (span) => {
|
|
10310
10310
|
if (!matcherFunction(span)) return;
|
|
10311
|
-
if (span.inputValue) span.inputValue = span.kind === import_src$
|
|
10312
|
-
if (span.outputValue) span.outputValue = span.kind === import_src$
|
|
10311
|
+
if (span.inputValue) span.inputValue = span.kind === import_src$30.SpanKind.CLIENT ? createEmptyClientInputValue(span.protocol) : createEmptyServerInputValue();
|
|
10312
|
+
if (span.outputValue) span.outputValue = span.kind === import_src$30.SpanKind.CLIENT ? createEmptyClientOutputValue() : createEmptyServerOutputValue();
|
|
10313
10313
|
return {
|
|
10314
10314
|
type: "drop",
|
|
10315
10315
|
field: "entire_span",
|
|
@@ -10339,8 +10339,8 @@ var HttpTransformEngine = class {
|
|
|
10339
10339
|
}
|
|
10340
10340
|
compileMatcher(matcher) {
|
|
10341
10341
|
const checks = [];
|
|
10342
|
-
if (matcher.direction === "outbound") checks.push((span) => span.kind === import_src$
|
|
10343
|
-
else if (matcher.direction === "inbound") checks.push((span) => span.kind === import_src$
|
|
10342
|
+
if (matcher.direction === "outbound") checks.push((span) => span.kind === import_src$30.SpanKind.CLIENT);
|
|
10343
|
+
else if (matcher.direction === "inbound") checks.push((span) => span.kind === import_src$30.SpanKind.SERVER);
|
|
10344
10344
|
if (matcher.method) if (matcher.method.length === 0) {} else {
|
|
10345
10345
|
const methods = matcher.method.map((method) => method.toUpperCase());
|
|
10346
10346
|
checks.push((span) => {
|
|
@@ -10568,7 +10568,7 @@ var HttpTransformEngine = class {
|
|
|
10568
10568
|
|
|
10569
10569
|
//#endregion
|
|
10570
10570
|
//#region src/instrumentation/libraries/http/Instrumentation.ts
|
|
10571
|
-
var import_src$
|
|
10571
|
+
var import_src$29 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
10572
10572
|
var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
10573
10573
|
constructor(config) {
|
|
10574
10574
|
super("http", config);
|
|
@@ -10655,10 +10655,10 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10655
10655
|
logger.debug(`[HttpInstrumentation] Setting replay trace id`, replayTraceId);
|
|
10656
10656
|
const ctxWithReplayTraceId = SpanUtils.setCurrentReplayTraceId(replayTraceId);
|
|
10657
10657
|
if (!ctxWithReplayTraceId) throw new Error("Error setting current replay trace id");
|
|
10658
|
-
return import_src$
|
|
10658
|
+
return import_src$29.context.with(ctxWithReplayTraceId, () => {
|
|
10659
10659
|
return SpanUtils.createAndExecuteSpan(this.mode, () => originalHandler.call(this), {
|
|
10660
10660
|
name: `${target}`,
|
|
10661
|
-
kind: import_src$
|
|
10661
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10662
10662
|
packageName: spanProtocol,
|
|
10663
10663
|
submodule: method,
|
|
10664
10664
|
packageType: PackageType.HTTP,
|
|
@@ -10703,7 +10703,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10703
10703
|
logger.debug(`[HttpInstrumentation] Http inbound request arriving, inputValue: ${JSON.stringify(inputValue)}`);
|
|
10704
10704
|
return SpanUtils.createAndExecuteSpan(this.mode, () => originalHandler.call(this), {
|
|
10705
10705
|
name: `${target}`,
|
|
10706
|
-
kind: import_src$
|
|
10706
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10707
10707
|
packageName: spanProtocol,
|
|
10708
10708
|
packageType: PackageType.HTTP,
|
|
10709
10709
|
submodule: method,
|
|
@@ -10723,7 +10723,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10723
10723
|
});
|
|
10724
10724
|
});
|
|
10725
10725
|
},
|
|
10726
|
-
spanKind: import_src$
|
|
10726
|
+
spanKind: import_src$29.SpanKind.SERVER
|
|
10727
10727
|
});
|
|
10728
10728
|
} else return originalHandler.call(this);
|
|
10729
10729
|
}
|
|
@@ -10740,8 +10740,8 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10740
10740
|
_handleInboundRequestInSpan({ req, res, originalHandler, spanInfo, inputValue, schemaMerges, protocol }) {
|
|
10741
10741
|
const self = this;
|
|
10742
10742
|
const spanProtocol = this._normalizeProtocol(protocol, "http");
|
|
10743
|
-
import_src$
|
|
10744
|
-
import_src$
|
|
10743
|
+
import_src$29.context.bind(spanInfo.context, req);
|
|
10744
|
+
import_src$29.context.bind(spanInfo.context, res);
|
|
10745
10745
|
let completeInputValue = inputValue;
|
|
10746
10746
|
this._captureServerRequestBody(req, spanInfo, inputValue, schemaMerges, (updatedInputValue) => {
|
|
10747
10747
|
completeInputValue = updatedInputValue;
|
|
@@ -10779,7 +10779,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10779
10779
|
const spanData = {
|
|
10780
10780
|
traceId: spanInfo.traceId,
|
|
10781
10781
|
spanId: spanInfo.spanId,
|
|
10782
|
-
kind: import_src$
|
|
10782
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10783
10783
|
protocol: spanProtocol,
|
|
10784
10784
|
inputValue: completeInputValue,
|
|
10785
10785
|
outputValue
|
|
@@ -10798,9 +10798,9 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10798
10798
|
...spanData.transformMetadata && { transformMetadata: spanData.transformMetadata }
|
|
10799
10799
|
});
|
|
10800
10800
|
const status = statusCode >= 400 ? {
|
|
10801
|
-
code: import_src$
|
|
10801
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
10802
10802
|
message: `HTTP ${statusCode}`
|
|
10803
|
-
} : { code: import_src$
|
|
10803
|
+
} : { code: import_src$29.SpanStatusCode.OK };
|
|
10804
10804
|
SpanUtils.setStatus(spanInfo.span, status);
|
|
10805
10805
|
const decodedType = getDecodedType(outputValue.headers?.["content-type"] || "");
|
|
10806
10806
|
if (decodedType && !ACCEPTABLE_CONTENT_TYPES.has(decodedType)) {
|
|
@@ -10850,7 +10850,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10850
10850
|
outputSchemaHash: JsonSchemaHelper.generateDeterministicHash(outputSchema),
|
|
10851
10851
|
inputValueHash,
|
|
10852
10852
|
outputValueHash,
|
|
10853
|
-
kind: import_src$
|
|
10853
|
+
kind: import_src$29.SpanKind.SERVER,
|
|
10854
10854
|
packageType: PackageType.HTTP,
|
|
10855
10855
|
status: {
|
|
10856
10856
|
code: statusCode >= 400 ? StatusCode.ERROR : StatusCode.OK,
|
|
@@ -10879,7 +10879,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10879
10879
|
try {
|
|
10880
10880
|
logger.debug(`[HttpInstrumentation] Server request error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
10881
10881
|
SpanUtils.endSpan(spanInfo.span, {
|
|
10882
|
-
code: import_src$
|
|
10882
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
10883
10883
|
message: error.message
|
|
10884
10884
|
});
|
|
10885
10885
|
} catch (error$1) {
|
|
@@ -10890,7 +10890,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
10890
10890
|
try {
|
|
10891
10891
|
logger.debug(`[HttpInstrumentation] Server response error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
10892
10892
|
SpanUtils.endSpan(spanInfo.span, {
|
|
10893
|
-
code: import_src$
|
|
10893
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
10894
10894
|
message: error.message
|
|
10895
10895
|
});
|
|
10896
10896
|
} catch (error$1) {
|
|
@@ -11095,7 +11095,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11095
11095
|
inputValue: completeInputValue
|
|
11096
11096
|
});
|
|
11097
11097
|
SpanUtils.endSpan(spanInfo.span, {
|
|
11098
|
-
code: import_src$
|
|
11098
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
11099
11099
|
message: error.message
|
|
11100
11100
|
});
|
|
11101
11101
|
} catch (error$1) {
|
|
@@ -11112,7 +11112,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11112
11112
|
const spanData = {
|
|
11113
11113
|
traceId: spanInfo.traceId,
|
|
11114
11114
|
spanId: spanInfo.spanId,
|
|
11115
|
-
kind: import_src$
|
|
11115
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11116
11116
|
protocol: normalizedProtocol,
|
|
11117
11117
|
inputValue,
|
|
11118
11118
|
outputValue
|
|
@@ -11125,9 +11125,9 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11125
11125
|
transformMetadata: spanData.transformMetadata ? spanData.transformMetadata : void 0
|
|
11126
11126
|
});
|
|
11127
11127
|
const status = statusCode >= 400 ? {
|
|
11128
|
-
code: import_src$
|
|
11128
|
+
code: import_src$29.SpanStatusCode.ERROR,
|
|
11129
11129
|
message: `HTTP ${statusCode}`
|
|
11130
|
-
} : { code: import_src$
|
|
11130
|
+
} : { code: import_src$29.SpanStatusCode.OK };
|
|
11131
11131
|
SpanUtils.endSpan(spanInfo.span, status);
|
|
11132
11132
|
}
|
|
11133
11133
|
_captureHeadersFromRawHeaders(rawHeaders) {
|
|
@@ -11181,7 +11181,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11181
11181
|
};
|
|
11182
11182
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalRequest.apply(this, args), {
|
|
11183
11183
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11184
|
-
kind: import_src$
|
|
11184
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11185
11185
|
packageName: requestProtocol,
|
|
11186
11186
|
packageType: PackageType.HTTP,
|
|
11187
11187
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11216,7 +11216,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11216
11216
|
};
|
|
11217
11217
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalRequest.apply(this, args), {
|
|
11218
11218
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11219
|
-
kind: import_src$
|
|
11219
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11220
11220
|
packageName: requestProtocol,
|
|
11221
11221
|
packageType: PackageType.HTTP,
|
|
11222
11222
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11228,7 +11228,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11228
11228
|
return self._handleOutboundRequestInSpan(originalRequest, args, spanInfo, inputValue, { headers: { matchImportance: 0 } });
|
|
11229
11229
|
});
|
|
11230
11230
|
},
|
|
11231
|
-
spanKind: import_src$
|
|
11231
|
+
spanKind: import_src$29.SpanKind.CLIENT
|
|
11232
11232
|
});
|
|
11233
11233
|
else return originalRequest.apply(this, args);
|
|
11234
11234
|
};
|
|
@@ -11274,7 +11274,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11274
11274
|
};
|
|
11275
11275
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalGet.apply(this, args), {
|
|
11276
11276
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11277
|
-
kind: import_src$
|
|
11277
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11278
11278
|
packageName: requestProtocol,
|
|
11279
11279
|
packageType: PackageType.HTTP,
|
|
11280
11280
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11308,7 +11308,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11308
11308
|
};
|
|
11309
11309
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalGet.apply(this, args), {
|
|
11310
11310
|
name: requestOptions.path || `${requestProtocol.toUpperCase()} ${method}`,
|
|
11311
|
-
kind: import_src$
|
|
11311
|
+
kind: import_src$29.SpanKind.CLIENT,
|
|
11312
11312
|
packageName: requestProtocol,
|
|
11313
11313
|
packageType: PackageType.HTTP,
|
|
11314
11314
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11320,7 +11320,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11320
11320
|
return self._handleOutboundRequestInSpan(originalGet, args, spanInfo, inputValue, { headers: { matchImportance: 0 } });
|
|
11321
11321
|
});
|
|
11322
11322
|
},
|
|
11323
|
-
spanKind: import_src$
|
|
11323
|
+
spanKind: import_src$29.SpanKind.CLIENT
|
|
11324
11324
|
});
|
|
11325
11325
|
else return originalGet.apply(this, args);
|
|
11326
11326
|
};
|
|
@@ -11365,7 +11365,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
|
|
|
11365
11365
|
|
|
11366
11366
|
//#endregion
|
|
11367
11367
|
//#region src/instrumentation/libraries/date/Instrumentation.ts
|
|
11368
|
-
var import_src$
|
|
11368
|
+
var import_src$28 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
11369
11369
|
/**
|
|
11370
11370
|
* Date instrumentation that provides consistent dates in replay mode.
|
|
11371
11371
|
* In replay mode, new Date() calls return the latest mock response timestamp.
|
|
@@ -11404,7 +11404,7 @@ var DateInstrumentation = class DateInstrumentation extends TdInstrumentationBas
|
|
|
11404
11404
|
if (this.mode !== TuskDriftMode.REPLAY) return this._callOriginalDate(args, isConstructorCall);
|
|
11405
11405
|
const currentSpanInfo = SpanUtils.getCurrentSpanInfo();
|
|
11406
11406
|
if (!currentSpanInfo) return this._callOriginalDate(args, isConstructorCall);
|
|
11407
|
-
if (currentSpanInfo.context.getValue(SPAN_KIND_CONTEXT_KEY) !== import_src$
|
|
11407
|
+
if (currentSpanInfo.context.getValue(SPAN_KIND_CONTEXT_KEY) !== import_src$28.SpanKind.SERVER) return this._callOriginalDate(args, isConstructorCall);
|
|
11408
11408
|
this.isInPatchedCall = true;
|
|
11409
11409
|
try {
|
|
11410
11410
|
return this._handleReplayDate(args, isConstructorCall);
|
|
@@ -11650,7 +11650,7 @@ var TdPgClientMock = class extends events.EventEmitter {
|
|
|
11650
11650
|
|
|
11651
11651
|
//#endregion
|
|
11652
11652
|
//#region src/instrumentation/libraries/pg/Instrumentation.ts
|
|
11653
|
-
var import_src$
|
|
11653
|
+
var import_src$27 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
11654
11654
|
var PgInstrumentation = class extends TdInstrumentationBase {
|
|
11655
11655
|
constructor(config = {}) {
|
|
11656
11656
|
super("pg", config);
|
|
@@ -11691,6 +11691,10 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11691
11691
|
const self = this;
|
|
11692
11692
|
return (originalQuery) => {
|
|
11693
11693
|
return function query(...args) {
|
|
11694
|
+
if (self.isSubmittable(args[0])) {
|
|
11695
|
+
logger.debug(`[PgInstrumentation] Submittable query detected, passing through uninstrumented`);
|
|
11696
|
+
return originalQuery.apply(this, args);
|
|
11697
|
+
}
|
|
11694
11698
|
let queryConfig = null;
|
|
11695
11699
|
try {
|
|
11696
11700
|
queryConfig = self.parseQueryArgs(args);
|
|
@@ -11719,7 +11723,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11719
11723
|
const spanName = inputValue.clientType === "pool" ? "pg-pool.query" : "pg.query";
|
|
11720
11724
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalQuery.apply(this, args), {
|
|
11721
11725
|
name: spanName,
|
|
11722
|
-
kind: import_src$
|
|
11726
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11723
11727
|
submodule: "query",
|
|
11724
11728
|
packageType: PackageType.PG,
|
|
11725
11729
|
packageName,
|
|
@@ -11738,7 +11742,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11738
11742
|
const spanName = inputValue.clientType === "pool" ? "pg-pool.query" : "pg.query";
|
|
11739
11743
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalQuery.apply(this, args), {
|
|
11740
11744
|
name: spanName,
|
|
11741
|
-
kind: import_src$
|
|
11745
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11742
11746
|
submodule: "query",
|
|
11743
11747
|
packageType: PackageType.PG,
|
|
11744
11748
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -11749,7 +11753,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11749
11753
|
return self._handleRecordQueryInSpan(spanInfo, originalQuery, queryConfig, args, this);
|
|
11750
11754
|
});
|
|
11751
11755
|
},
|
|
11752
|
-
spanKind: import_src$
|
|
11756
|
+
spanKind: import_src$27.SpanKind.CLIENT
|
|
11753
11757
|
});
|
|
11754
11758
|
else return originalQuery.apply(this, args);
|
|
11755
11759
|
};
|
|
@@ -11771,7 +11775,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11771
11775
|
replayModeHandler: () => {
|
|
11772
11776
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
11773
11777
|
name: `pg.connect`,
|
|
11774
|
-
kind: import_src$
|
|
11778
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11775
11779
|
submodule: "connect",
|
|
11776
11780
|
packageName: "pg",
|
|
11777
11781
|
packageType: PackageType.PG,
|
|
@@ -11788,7 +11792,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11788
11792
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
11789
11793
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
11790
11794
|
name: `pg.connect`,
|
|
11791
|
-
kind: import_src$
|
|
11795
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11792
11796
|
submodule: "connect",
|
|
11793
11797
|
packageName: "pg",
|
|
11794
11798
|
packageType: PackageType.PG,
|
|
@@ -11799,12 +11803,19 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11799
11803
|
return self._handleRecordConnectInSpan(spanInfo, originalConnect, callback, this);
|
|
11800
11804
|
});
|
|
11801
11805
|
},
|
|
11802
|
-
spanKind: import_src$
|
|
11806
|
+
spanKind: import_src$27.SpanKind.CLIENT
|
|
11803
11807
|
});
|
|
11804
11808
|
else return originalConnect.apply(this, [callback]);
|
|
11805
11809
|
};
|
|
11806
11810
|
};
|
|
11807
11811
|
}
|
|
11812
|
+
/**
|
|
11813
|
+
* Check if an object is a Submittable (Query object with submit method).
|
|
11814
|
+
* This is the same check pg uses internally: typeof config.submit === 'function'
|
|
11815
|
+
*/
|
|
11816
|
+
isSubmittable(arg) {
|
|
11817
|
+
return arg && typeof arg.submit === "function";
|
|
11818
|
+
}
|
|
11808
11819
|
parseQueryArgs(args) {
|
|
11809
11820
|
if (args.length === 0) return null;
|
|
11810
11821
|
const firstArg = args[0];
|
|
@@ -11832,7 +11843,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11832
11843
|
logger.debug(`[PgInstrumentation] PG query error (hasCallback): ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
11833
11844
|
try {
|
|
11834
11845
|
SpanUtils.endSpan(spanInfo.span, {
|
|
11835
|
-
code: import_src$
|
|
11846
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
11836
11847
|
message: error.message
|
|
11837
11848
|
});
|
|
11838
11849
|
} catch (error$1) {
|
|
@@ -11842,7 +11853,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11842
11853
|
logger.debug(`[PgInstrumentation] PG query completed successfully (hasCallback) (${SpanUtils.getTraceInfo()})`);
|
|
11843
11854
|
try {
|
|
11844
11855
|
this._addOutputAttributesToSpan(spanInfo, result);
|
|
11845
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
11856
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
11846
11857
|
} catch (error$1) {
|
|
11847
11858
|
logger.error(`[PgInstrumentation] error processing response:`, error$1);
|
|
11848
11859
|
}
|
|
@@ -11869,7 +11880,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11869
11880
|
logger.debug(`[PgInstrumentation] PG query completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
11870
11881
|
try {
|
|
11871
11882
|
this._addOutputAttributesToSpan(spanInfo, result);
|
|
11872
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
11883
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
11873
11884
|
} catch (error) {
|
|
11874
11885
|
logger.error(`[PgInstrumentation] error processing response:`, error);
|
|
11875
11886
|
}
|
|
@@ -11878,7 +11889,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11878
11889
|
logger.debug(`[PgInstrumentation] PG query error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
11879
11890
|
try {
|
|
11880
11891
|
SpanUtils.endSpan(spanInfo.span, {
|
|
11881
|
-
code: import_src$
|
|
11892
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
11882
11893
|
message: error.message
|
|
11883
11894
|
});
|
|
11884
11895
|
} catch (error$1) {
|
|
@@ -11910,7 +11921,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11910
11921
|
packageName,
|
|
11911
11922
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
11912
11923
|
submoduleName: "query",
|
|
11913
|
-
kind: import_src$
|
|
11924
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
11914
11925
|
stackTrace
|
|
11915
11926
|
},
|
|
11916
11927
|
tuskDrift: this.tuskDrift
|
|
@@ -11954,6 +11965,8 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11954
11965
|
* Reference for data type IDs: https://jdbc.postgresql.org/documentation/publicapi/constant-values.html
|
|
11955
11966
|
*/
|
|
11956
11967
|
convertPostgresTypes(result, rowMode) {
|
|
11968
|
+
if (result && result.isMultiStatement && Array.isArray(result.results)) return result.results.map((singleResult) => this.convertPostgresTypes(singleResult, rowMode));
|
|
11969
|
+
if (Array.isArray(result)) return result.map((singleResult) => this.convertPostgresTypes(singleResult, rowMode));
|
|
11957
11970
|
if (!result || !result.fields || !result.rows) return result;
|
|
11958
11971
|
if (rowMode === "array") {
|
|
11959
11972
|
const convertedRows$1 = result.rows.map((row) => {
|
|
@@ -11994,7 +12007,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
11994
12007
|
logger.debug(`[PgInstrumentation] PG connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
11995
12008
|
try {
|
|
11996
12009
|
SpanUtils.endSpan(spanInfo.span, {
|
|
11997
|
-
code: import_src$
|
|
12010
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
11998
12011
|
message: error.message
|
|
11999
12012
|
});
|
|
12000
12013
|
} catch (error$1) {
|
|
@@ -12004,7 +12017,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12004
12017
|
logger.debug(`[PgInstrumentation] PG connect completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12005
12018
|
try {
|
|
12006
12019
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { connected: true } });
|
|
12007
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12020
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12008
12021
|
} catch (error$1) {
|
|
12009
12022
|
logger.error(`[PgInstrumentation] error processing connect response:`, error$1);
|
|
12010
12023
|
}
|
|
@@ -12016,7 +12029,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12016
12029
|
logger.debug(`[PgInstrumentation] PG connect completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12017
12030
|
try {
|
|
12018
12031
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { connected: true } });
|
|
12019
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12032
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12020
12033
|
} catch (error) {
|
|
12021
12034
|
logger.error(`[PgInstrumentation] error processing connect response:`, error);
|
|
12022
12035
|
}
|
|
@@ -12025,7 +12038,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12025
12038
|
logger.debug(`[PgInstrumentation] PG connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12026
12039
|
try {
|
|
12027
12040
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12028
|
-
code: import_src$
|
|
12041
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12029
12042
|
message: error.message
|
|
12030
12043
|
});
|
|
12031
12044
|
} catch (error$1) {
|
|
@@ -12043,7 +12056,18 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12043
12056
|
}
|
|
12044
12057
|
_addOutputAttributesToSpan(spanInfo, result) {
|
|
12045
12058
|
if (!result) return;
|
|
12046
|
-
|
|
12059
|
+
let outputValue;
|
|
12060
|
+
if (Array.isArray(result)) outputValue = {
|
|
12061
|
+
isMultiStatement: true,
|
|
12062
|
+
results: result.map((r) => ({
|
|
12063
|
+
command: r.command,
|
|
12064
|
+
rowCount: r.rowCount,
|
|
12065
|
+
oid: r.oid,
|
|
12066
|
+
rows: r.rows || [],
|
|
12067
|
+
fields: r.fields || []
|
|
12068
|
+
}))
|
|
12069
|
+
};
|
|
12070
|
+
else outputValue = {
|
|
12047
12071
|
command: result.command,
|
|
12048
12072
|
rowCount: result.rowCount,
|
|
12049
12073
|
oid: result.oid,
|
|
@@ -12086,7 +12110,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12086
12110
|
replayModeHandler: () => {
|
|
12087
12111
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
12088
12112
|
name: `pg-pool.connect`,
|
|
12089
|
-
kind: import_src$
|
|
12113
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
12090
12114
|
submodule: "connect",
|
|
12091
12115
|
packageName: "pg-pool",
|
|
12092
12116
|
packageType: PackageType.PG,
|
|
@@ -12103,7 +12127,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12103
12127
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
12104
12128
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalConnect.apply(this, [callback]), {
|
|
12105
12129
|
name: `pg-pool.connect`,
|
|
12106
|
-
kind: import_src$
|
|
12130
|
+
kind: import_src$27.SpanKind.CLIENT,
|
|
12107
12131
|
submodule: "connect",
|
|
12108
12132
|
packageName: "pg-pool",
|
|
12109
12133
|
packageType: PackageType.PG,
|
|
@@ -12114,7 +12138,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12114
12138
|
return self._handleRecordPoolConnectInSpan(spanInfo, originalConnect, callback, this);
|
|
12115
12139
|
});
|
|
12116
12140
|
},
|
|
12117
|
-
spanKind: import_src$
|
|
12141
|
+
spanKind: import_src$27.SpanKind.CLIENT
|
|
12118
12142
|
});
|
|
12119
12143
|
else return originalConnect.apply(this, [callback]);
|
|
12120
12144
|
};
|
|
@@ -12127,7 +12151,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12127
12151
|
logger.debug(`[PgInstrumentation] PG Pool connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12128
12152
|
try {
|
|
12129
12153
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12130
|
-
code: import_src$
|
|
12154
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12131
12155
|
message: error.message
|
|
12132
12156
|
});
|
|
12133
12157
|
} catch (error$1) {
|
|
@@ -12140,7 +12164,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12140
12164
|
connected: true,
|
|
12141
12165
|
hasClient: !!client
|
|
12142
12166
|
} });
|
|
12143
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12167
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12144
12168
|
} catch (error$1) {
|
|
12145
12169
|
logger.error(`[PgInstrumentation] error processing pool connect response:`, error$1);
|
|
12146
12170
|
}
|
|
@@ -12155,7 +12179,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12155
12179
|
connected: true,
|
|
12156
12180
|
hasClient: !!client
|
|
12157
12181
|
} });
|
|
12158
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12182
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$27.SpanStatusCode.OK });
|
|
12159
12183
|
} catch (error) {
|
|
12160
12184
|
logger.error(`[PgInstrumentation] error processing pool connect response:`, error);
|
|
12161
12185
|
}
|
|
@@ -12164,7 +12188,7 @@ var PgInstrumentation = class extends TdInstrumentationBase {
|
|
|
12164
12188
|
logger.debug(`[PgInstrumentation] PG Pool connect error: ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12165
12189
|
try {
|
|
12166
12190
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12167
|
-
code: import_src$
|
|
12191
|
+
code: import_src$27.SpanStatusCode.ERROR,
|
|
12168
12192
|
message: error.message
|
|
12169
12193
|
});
|
|
12170
12194
|
} catch (error$1) {
|
|
@@ -12193,68 +12217,114 @@ function isPostgresOutputValueType(value) {
|
|
|
12193
12217
|
}
|
|
12194
12218
|
|
|
12195
12219
|
//#endregion
|
|
12196
|
-
//#region src/instrumentation/libraries/postgres/
|
|
12197
|
-
|
|
12198
|
-
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12202
|
-
|
|
12203
|
-
|
|
12220
|
+
//#region src/instrumentation/libraries/postgres/utils/typeConversion.ts
|
|
12221
|
+
/**
|
|
12222
|
+
* Convert PostgreSQL string values back to appropriate JavaScript types
|
|
12223
|
+
* based on field metadata from the recorded response.
|
|
12224
|
+
*/
|
|
12225
|
+
function convertPostgresTypes(result) {
|
|
12226
|
+
if (!isPostgresOutputValueType(result)) {
|
|
12227
|
+
logger.error(`[PostgresInstrumentation] output value is not of type PostgresOutputValueType`, result);
|
|
12228
|
+
return;
|
|
12204
12229
|
}
|
|
12205
|
-
|
|
12206
|
-
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12230
|
+
const { rows, count, command, columns, state, statement } = result;
|
|
12231
|
+
const resultArray = Array.from((rows || []).map((row) => reconstructBuffers(row)));
|
|
12232
|
+
if (count !== void 0) Object.defineProperty(resultArray, "count", {
|
|
12233
|
+
value: count,
|
|
12234
|
+
writable: true,
|
|
12235
|
+
enumerable: false
|
|
12236
|
+
});
|
|
12237
|
+
if (command !== void 0) Object.defineProperty(resultArray, "command", {
|
|
12238
|
+
value: command,
|
|
12239
|
+
writable: true,
|
|
12240
|
+
enumerable: false
|
|
12241
|
+
});
|
|
12242
|
+
if (columns !== void 0) Object.defineProperty(resultArray, "columns", {
|
|
12243
|
+
value: columns,
|
|
12244
|
+
writable: true,
|
|
12245
|
+
enumerable: false
|
|
12246
|
+
});
|
|
12247
|
+
if (state !== void 0) Object.defineProperty(resultArray, "state", {
|
|
12248
|
+
value: state,
|
|
12249
|
+
writable: true,
|
|
12250
|
+
enumerable: false
|
|
12251
|
+
});
|
|
12252
|
+
if (statement !== void 0) Object.defineProperty(resultArray, "statement", {
|
|
12253
|
+
value: statement,
|
|
12254
|
+
writable: true,
|
|
12255
|
+
enumerable: false
|
|
12256
|
+
});
|
|
12257
|
+
return resultArray;
|
|
12258
|
+
}
|
|
12259
|
+
/**
|
|
12260
|
+
* Recursively reconstructs Buffer objects from their JSON-serialized format.
|
|
12261
|
+
* When Buffers are JSON.stringify'd, they become { type: "Buffer", data: [...] }.
|
|
12262
|
+
* This method converts them back to actual Buffer instances.
|
|
12263
|
+
*/
|
|
12264
|
+
function reconstructBuffers(value) {
|
|
12265
|
+
if (value === null || value === void 0) return value;
|
|
12266
|
+
if (typeof value === "object" && value.type === "Buffer" && Array.isArray(value.data)) return Buffer.from(value.data);
|
|
12267
|
+
if (Array.isArray(value)) return value.map((item) => reconstructBuffers(item));
|
|
12268
|
+
if (typeof value === "object") {
|
|
12269
|
+
const result = {};
|
|
12270
|
+
for (const key of Object.keys(value)) result[key] = reconstructBuffers(value[key]);
|
|
12271
|
+
return result;
|
|
12211
12272
|
}
|
|
12212
|
-
|
|
12213
|
-
|
|
12214
|
-
|
|
12215
|
-
|
|
12216
|
-
|
|
12217
|
-
|
|
12218
|
-
|
|
12219
|
-
|
|
12220
|
-
|
|
12221
|
-
|
|
12222
|
-
|
|
12223
|
-
|
|
12224
|
-
|
|
12225
|
-
|
|
12226
|
-
|
|
12227
|
-
|
|
12228
|
-
|
|
12229
|
-
|
|
12230
|
-
|
|
12231
|
-
|
|
12232
|
-
|
|
12233
|
-
|
|
12234
|
-
|
|
12235
|
-
|
|
12236
|
-
|
|
12237
|
-
|
|
12238
|
-
|
|
12239
|
-
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
|
|
12246
|
-
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
logger.debug(`[PostgresInstrumentation] Postgres module patching complete`);
|
|
12250
|
-
return postgresModule;
|
|
12273
|
+
return value;
|
|
12274
|
+
}
|
|
12275
|
+
/**
|
|
12276
|
+
* Add output attributes to span for PostgreSQL results.
|
|
12277
|
+
*/
|
|
12278
|
+
function addOutputAttributesToSpan(spanInfo, result) {
|
|
12279
|
+
if (!result) return;
|
|
12280
|
+
const isArray$1 = Array.isArray(result);
|
|
12281
|
+
logger.debug(`[PostgresInstrumentation] Adding output attributes to span for ${isArray$1 ? "array" : "object"} result`);
|
|
12282
|
+
const normalizeValue = (val) => {
|
|
12283
|
+
if (Buffer.isBuffer(val)) return val.toString("utf8");
|
|
12284
|
+
else if (Array.isArray(val)) return val.map(normalizeValue);
|
|
12285
|
+
else if (val && typeof val === "object" && val.type === "Buffer" && Array.isArray(val.data)) return Buffer.from(val.data).toString("utf8");
|
|
12286
|
+
return val;
|
|
12287
|
+
};
|
|
12288
|
+
const outputValue = {
|
|
12289
|
+
rows: isArray$1 ? Array.from(result).map(normalizeValue) : (result.rows || []).map(normalizeValue),
|
|
12290
|
+
count: result.count !== void 0 && result.count !== null ? result.count : void 0,
|
|
12291
|
+
command: result.command || void 0,
|
|
12292
|
+
columns: result.columns || void 0,
|
|
12293
|
+
state: result.state || void 0,
|
|
12294
|
+
statement: result.statement || void 0
|
|
12295
|
+
};
|
|
12296
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
12297
|
+
}
|
|
12298
|
+
|
|
12299
|
+
//#endregion
|
|
12300
|
+
//#region src/instrumentation/libraries/postgres/utils/queryUtils.ts
|
|
12301
|
+
/**
|
|
12302
|
+
* Reconstruct a parameterized query string from template strings array and values.
|
|
12303
|
+
* Converts values to $1, $2, etc. placeholders.
|
|
12304
|
+
*/
|
|
12305
|
+
function reconstructQueryString(strings, values) {
|
|
12306
|
+
let queryString = "";
|
|
12307
|
+
for (let i = 0; i < strings.length; i++) {
|
|
12308
|
+
queryString += strings[i];
|
|
12309
|
+
if (i < values.length) queryString += `$${i + 1}`;
|
|
12251
12310
|
}
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12311
|
+
return queryString;
|
|
12312
|
+
}
|
|
12313
|
+
|
|
12314
|
+
//#endregion
|
|
12315
|
+
//#region src/instrumentation/libraries/postgres/handlers/ConnectionHandler.ts
|
|
12316
|
+
var import_src$26 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
12317
|
+
var ConnectionHandler = class {
|
|
12318
|
+
constructor(mode, instrumentationName, isAppReady, wrapSqlInstance) {
|
|
12319
|
+
this.mode = mode;
|
|
12320
|
+
this.instrumentationName = instrumentationName;
|
|
12321
|
+
this.isAppReady = isAppReady;
|
|
12322
|
+
this.wrapSqlInstance = wrapSqlInstance;
|
|
12323
|
+
}
|
|
12324
|
+
handlePostgresConnection(originalFunction, args) {
|
|
12255
12325
|
const inputValue = {
|
|
12256
|
-
connectionString:
|
|
12257
|
-
options:
|
|
12326
|
+
connectionString: typeof args[0] === "string" ? args[0] : void 0,
|
|
12327
|
+
options: typeof args[0] === "string" ? args[1] : args[0]
|
|
12258
12328
|
};
|
|
12259
12329
|
if (this.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
12260
12330
|
noOpRequestHandler: () => {
|
|
@@ -12268,96 +12338,148 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12268
12338
|
}));
|
|
12269
12339
|
mockSql.begin = () => Promise.resolve();
|
|
12270
12340
|
mockSql.end = () => Promise.resolve();
|
|
12341
|
+
mockSql.file = () => Promise.resolve(Object.assign([], {
|
|
12342
|
+
count: 0,
|
|
12343
|
+
command: null
|
|
12344
|
+
}));
|
|
12345
|
+
mockSql.reserve = () => Promise.resolve(mockSql);
|
|
12346
|
+
mockSql.listen = () => Promise.resolve({
|
|
12347
|
+
state: { state: "I" },
|
|
12348
|
+
unlisten: async () => {}
|
|
12349
|
+
});
|
|
12350
|
+
mockSql.notify = () => Promise.resolve();
|
|
12271
12351
|
return mockSql;
|
|
12272
12352
|
},
|
|
12273
12353
|
isServerRequest: false,
|
|
12274
12354
|
replayModeHandler: () => {
|
|
12275
12355
|
return SpanUtils.createAndExecuteSpan(this.mode, () => {
|
|
12276
12356
|
const sqlInstance = originalFunction(...args);
|
|
12277
|
-
return this.
|
|
12357
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12278
12358
|
}, {
|
|
12279
12359
|
name: "postgres.connect",
|
|
12280
|
-
kind: import_src$
|
|
12360
|
+
kind: import_src$26.SpanKind.CLIENT,
|
|
12281
12361
|
submodule: "connect",
|
|
12282
12362
|
packageType: PackageType.PG,
|
|
12283
12363
|
packageName: "postgres",
|
|
12284
|
-
instrumentationName: this.
|
|
12364
|
+
instrumentationName: this.instrumentationName,
|
|
12285
12365
|
inputValue,
|
|
12286
|
-
isPreAppStart: false
|
|
12366
|
+
isPreAppStart: this.isAppReady() ? false : true
|
|
12287
12367
|
}, (spanInfo) => {
|
|
12288
|
-
return this.
|
|
12368
|
+
return this.handleReplayConnect(originalFunction, args);
|
|
12289
12369
|
});
|
|
12290
12370
|
}
|
|
12291
12371
|
});
|
|
12292
12372
|
else if (this.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
12293
12373
|
originalFunctionCall: () => {
|
|
12294
12374
|
const sqlInstance = originalFunction(...args);
|
|
12295
|
-
return this.
|
|
12375
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12296
12376
|
},
|
|
12297
12377
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
12298
12378
|
return SpanUtils.createAndExecuteSpan(this.mode, () => {
|
|
12299
12379
|
const sqlInstance = originalFunction(...args);
|
|
12300
|
-
return this.
|
|
12380
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12301
12381
|
}, {
|
|
12302
12382
|
name: "postgres.connect",
|
|
12303
|
-
kind: import_src$
|
|
12383
|
+
kind: import_src$26.SpanKind.CLIENT,
|
|
12304
12384
|
submodule: "connect",
|
|
12305
12385
|
packageType: PackageType.PG,
|
|
12306
12386
|
packageName: "postgres",
|
|
12307
|
-
instrumentationName: this.
|
|
12387
|
+
instrumentationName: this.instrumentationName,
|
|
12308
12388
|
inputValue,
|
|
12309
12389
|
isPreAppStart
|
|
12310
12390
|
}, (spanInfo) => {
|
|
12311
|
-
return this.
|
|
12391
|
+
return this.handleRecordConnect(spanInfo, originalFunction, args);
|
|
12312
12392
|
});
|
|
12313
12393
|
},
|
|
12314
|
-
spanKind: import_src$
|
|
12394
|
+
spanKind: import_src$26.SpanKind.CLIENT
|
|
12315
12395
|
});
|
|
12316
12396
|
else return originalFunction(...args);
|
|
12317
12397
|
}
|
|
12318
|
-
|
|
12319
|
-
try {
|
|
12320
|
-
const url = new URL(connectionString);
|
|
12321
|
-
if (url.password) url.password = "***";
|
|
12322
|
-
return url.toString();
|
|
12323
|
-
} catch {
|
|
12324
|
-
return "[INVALID_URL]";
|
|
12325
|
-
}
|
|
12326
|
-
}
|
|
12327
|
-
_sanitizeConnectionOptions(options) {
|
|
12328
|
-
if (!options || typeof options !== "object") return options;
|
|
12329
|
-
const sanitized = { ...options };
|
|
12330
|
-
if (sanitized.password) sanitized.password = "***";
|
|
12331
|
-
if (sanitized.ssl && typeof sanitized.ssl === "object") {
|
|
12332
|
-
sanitized.ssl = { ...sanitized.ssl };
|
|
12333
|
-
if (sanitized.ssl.key) sanitized.ssl.key = "***";
|
|
12334
|
-
if (sanitized.ssl.cert) sanitized.ssl.cert = "***";
|
|
12335
|
-
if (sanitized.ssl.ca) sanitized.ssl.ca = "***";
|
|
12336
|
-
}
|
|
12337
|
-
return sanitized;
|
|
12338
|
-
}
|
|
12339
|
-
_handleRecordConnect(spanInfo, originalFunction, args) {
|
|
12398
|
+
handleRecordConnect(spanInfo, originalFunction, args) {
|
|
12340
12399
|
const sqlInstance = originalFunction(...args);
|
|
12341
|
-
const wrappedInstance = this.
|
|
12400
|
+
const wrappedInstance = this.wrapSqlInstance(sqlInstance);
|
|
12342
12401
|
try {
|
|
12343
12402
|
logger.debug(`[PostgresInstrumentation] Postgres connection created successfully (${SpanUtils.getTraceInfo()})`);
|
|
12344
12403
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { connected: true } });
|
|
12345
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$
|
|
12404
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$26.SpanStatusCode.OK });
|
|
12346
12405
|
} catch (error) {
|
|
12347
12406
|
logger.error(`[PostgresInstrumentation] error adding span attributes:`, error);
|
|
12348
12407
|
}
|
|
12349
12408
|
return wrappedInstance;
|
|
12350
12409
|
}
|
|
12351
|
-
|
|
12410
|
+
handleReplayConnect(originalFunction, args) {
|
|
12352
12411
|
logger.debug(`[PostgresInstrumentation] Replaying Postgres connection`);
|
|
12353
12412
|
try {
|
|
12354
12413
|
const sqlInstance = originalFunction(...args);
|
|
12355
|
-
return this.
|
|
12414
|
+
return this.wrapSqlInstance(sqlInstance);
|
|
12356
12415
|
} catch (error) {
|
|
12357
12416
|
logger.debug(`[PostgresInstrumentation] Postgres connection error in replay: ${error.message}`);
|
|
12358
12417
|
throw error;
|
|
12359
12418
|
}
|
|
12360
12419
|
}
|
|
12420
|
+
};
|
|
12421
|
+
|
|
12422
|
+
//#endregion
|
|
12423
|
+
//#region src/instrumentation/libraries/postgres/Instrumentation.ts
|
|
12424
|
+
var import_src$25 = /* @__PURE__ */ __toESM(require_src$7(), 1);
|
|
12425
|
+
var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
12426
|
+
constructor(config = {}) {
|
|
12427
|
+
super("postgres", config);
|
|
12428
|
+
this.INSTRUMENTATION_NAME = "PostgresInstrumentation";
|
|
12429
|
+
this.mode = config.mode || TuskDriftMode.DISABLED;
|
|
12430
|
+
this.tuskDrift = TuskDriftCore.getInstance();
|
|
12431
|
+
this.connectionHandler = new ConnectionHandler(this.mode, this.INSTRUMENTATION_NAME, () => this.tuskDrift.isAppReady(), (sqlInstance) => this._wrapSqlInstance(sqlInstance));
|
|
12432
|
+
}
|
|
12433
|
+
init() {
|
|
12434
|
+
return [new TdInstrumentationNodeModule({
|
|
12435
|
+
name: "postgres",
|
|
12436
|
+
supportedVersions: ["3.*"],
|
|
12437
|
+
patch: (moduleExports) => this._patchPostgresModule(moduleExports)
|
|
12438
|
+
})];
|
|
12439
|
+
}
|
|
12440
|
+
_patchPostgresModule(postgresModule) {
|
|
12441
|
+
logger.debug(`[PostgresInstrumentation] Patching Postgres module in ${this.mode} mode`);
|
|
12442
|
+
if (this.isModulePatched(postgresModule)) {
|
|
12443
|
+
logger.debug(`[PostgresInstrumentation] Postgres module already patched, skipping`);
|
|
12444
|
+
return postgresModule;
|
|
12445
|
+
}
|
|
12446
|
+
const self = this;
|
|
12447
|
+
if (isEsm(postgresModule)) {
|
|
12448
|
+
logger.debug(`[PostgresInstrumentation] Wrapping ESM default export`);
|
|
12449
|
+
this._wrap(postgresModule, "default", (originalFunction) => {
|
|
12450
|
+
return function(...args) {
|
|
12451
|
+
return self._handlePostgresConnection(originalFunction, args);
|
|
12452
|
+
};
|
|
12453
|
+
});
|
|
12454
|
+
} else {
|
|
12455
|
+
logger.debug(`[PostgresInstrumentation] Module is a function (CJS style)`);
|
|
12456
|
+
const originalFunction = postgresModule;
|
|
12457
|
+
const wrappedFunction = function(...args) {
|
|
12458
|
+
logger.debug(`[PostgresInstrumentation] Wrapped postgres() (CJS) called with args:`, args);
|
|
12459
|
+
return self._handlePostgresConnection(originalFunction, args);
|
|
12460
|
+
};
|
|
12461
|
+
Object.setPrototypeOf(wrappedFunction, Object.getPrototypeOf(originalFunction));
|
|
12462
|
+
Object.defineProperty(wrappedFunction, "name", { value: originalFunction.name });
|
|
12463
|
+
for (const key in originalFunction) if (originalFunction.hasOwnProperty(key)) wrappedFunction[key] = originalFunction[key];
|
|
12464
|
+
Object.getOwnPropertyNames(originalFunction).forEach((key) => {
|
|
12465
|
+
if (key !== "prototype" && key !== "length" && key !== "name") {
|
|
12466
|
+
const descriptor = Object.getOwnPropertyDescriptor(originalFunction, key);
|
|
12467
|
+
if (descriptor) Object.defineProperty(wrappedFunction, key, descriptor);
|
|
12468
|
+
}
|
|
12469
|
+
});
|
|
12470
|
+
postgresModule = wrappedFunction;
|
|
12471
|
+
}
|
|
12472
|
+
if (postgresModule.sql && typeof postgresModule.sql === "function") {
|
|
12473
|
+
this._wrap(postgresModule, "sql", this._getSqlPatchFn());
|
|
12474
|
+
logger.debug(`[PostgresInstrumentation] Wrapped sql function`);
|
|
12475
|
+
}
|
|
12476
|
+
this.markModuleAsPatched(postgresModule);
|
|
12477
|
+
logger.debug(`[PostgresInstrumentation] Postgres module patching complete`);
|
|
12478
|
+
return postgresModule;
|
|
12479
|
+
}
|
|
12480
|
+
_handlePostgresConnection(originalFunction, args) {
|
|
12481
|
+
return this.connectionHandler.handlePostgresConnection(originalFunction, args);
|
|
12482
|
+
}
|
|
12361
12483
|
_wrapSqlInstance(sqlInstance) {
|
|
12362
12484
|
if (!sqlInstance || typeof sqlInstance !== "function") return sqlInstance;
|
|
12363
12485
|
const self = this;
|
|
@@ -12373,11 +12495,34 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12373
12495
|
logger.debug(`[PostgresInstrumentation] Wrapped unsafe method on sql instance`);
|
|
12374
12496
|
}
|
|
12375
12497
|
if (typeof originalSql.begin === "function") {
|
|
12376
|
-
|
|
12377
|
-
|
|
12498
|
+
const wrappedBegin = self._wrapBeginMethod(originalSql);
|
|
12499
|
+
originalSql.begin = wrappedBegin;
|
|
12500
|
+
wrappedSql.begin = wrappedBegin;
|
|
12501
|
+
}
|
|
12502
|
+
if (typeof originalSql.file === "function") {
|
|
12503
|
+
wrappedSql.file = self._wrapFileMethod(originalSql);
|
|
12504
|
+
logger.debug(`[PostgresInstrumentation] Wrapped file method on sql instance`);
|
|
12505
|
+
}
|
|
12506
|
+
if (typeof originalSql.reserve === "function") {
|
|
12507
|
+
wrappedSql.reserve = self._wrapReserveMethod(originalSql);
|
|
12508
|
+
logger.debug(`[PostgresInstrumentation] Wrapped reserve method on sql instance`);
|
|
12509
|
+
}
|
|
12510
|
+
if (typeof originalSql.listen === "function") {
|
|
12511
|
+
wrappedSql.listen = self._wrapListenMethod(originalSql);
|
|
12512
|
+
logger.debug(`[PostgresInstrumentation] Wrapped listen method on sql instance`);
|
|
12513
|
+
}
|
|
12514
|
+
if (typeof originalSql.notify === "function") {
|
|
12515
|
+
wrappedSql.notify = self._wrapNotifyMethod(wrappedSql);
|
|
12516
|
+
logger.debug(`[PostgresInstrumentation] Wrapped notify method on sql instance`);
|
|
12378
12517
|
}
|
|
12379
12518
|
return wrappedSql;
|
|
12380
12519
|
}
|
|
12520
|
+
_wrapNotifyMethod(wrappedSqlInstance) {
|
|
12521
|
+
return async function notify(channel, payload) {
|
|
12522
|
+
logger.debug(`[PostgresInstrumentation] notify() called for channel ${channel}`);
|
|
12523
|
+
return wrappedSqlInstance`select pg_notify(${channel}, ${String(payload)})`;
|
|
12524
|
+
};
|
|
12525
|
+
}
|
|
12381
12526
|
_wrapUnsafeMethod(sqlInstance) {
|
|
12382
12527
|
const self = this;
|
|
12383
12528
|
const originalUnsafe = sqlInstance.unsafe;
|
|
@@ -12394,6 +12539,175 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12394
12539
|
return self._handleBeginTransaction(sqlInstance, originalBegin, options, transactionCallback);
|
|
12395
12540
|
};
|
|
12396
12541
|
}
|
|
12542
|
+
_wrapFileMethod(sqlInstance) {
|
|
12543
|
+
const self = this;
|
|
12544
|
+
const originalFile = sqlInstance.file;
|
|
12545
|
+
return function file(path$5, parameters, queryOptions) {
|
|
12546
|
+
return self._handleFileQuery(sqlInstance, originalFile, path$5, parameters, queryOptions);
|
|
12547
|
+
};
|
|
12548
|
+
}
|
|
12549
|
+
_wrapReserveMethod(sqlInstance) {
|
|
12550
|
+
const self = this;
|
|
12551
|
+
const originalReserve = sqlInstance.reserve;
|
|
12552
|
+
return async function reserve() {
|
|
12553
|
+
if (self.mode === TuskDriftMode.REPLAY) {
|
|
12554
|
+
logger.debug(`[PostgresInstrumentation] REPLAY mode: Creating mock reserved connection without TCP`);
|
|
12555
|
+
const mockReservedSql = self._wrapSqlInstance(sqlInstance);
|
|
12556
|
+
if (typeof mockReservedSql === "function") mockReservedSql.release = function() {
|
|
12557
|
+
logger.debug(`[PostgresInstrumentation] Mock reserved connection released`);
|
|
12558
|
+
};
|
|
12559
|
+
return mockReservedSql;
|
|
12560
|
+
}
|
|
12561
|
+
const reservedSql = await originalReserve.call(sqlInstance);
|
|
12562
|
+
const wrappedReservedSql = self._wrapSqlInstance(reservedSql);
|
|
12563
|
+
logger.debug(`[PostgresInstrumentation] Reserved connection obtained and wrapped`);
|
|
12564
|
+
return wrappedReservedSql;
|
|
12565
|
+
};
|
|
12566
|
+
}
|
|
12567
|
+
_wrapListenMethod(sqlInstance) {
|
|
12568
|
+
const self = this;
|
|
12569
|
+
const originalListen = sqlInstance.listen;
|
|
12570
|
+
return async function listen(channelName, callback, onlisten) {
|
|
12571
|
+
return self._handleListenMethod(sqlInstance, originalListen, channelName, callback, onlisten);
|
|
12572
|
+
};
|
|
12573
|
+
}
|
|
12574
|
+
async _handleListenMethod(sqlInstance, originalListen, channelName, callback, onlisten) {
|
|
12575
|
+
const inputValue = {
|
|
12576
|
+
operation: "listen",
|
|
12577
|
+
channel: channelName
|
|
12578
|
+
};
|
|
12579
|
+
if (this.mode === TuskDriftMode.REPLAY) return this._handleReplayListen(channelName, callback, onlisten, inputValue);
|
|
12580
|
+
else if (this.mode === TuskDriftMode.RECORD) return this._handleRecordListen(sqlInstance, originalListen, channelName, callback, onlisten, inputValue);
|
|
12581
|
+
else return originalListen.call(sqlInstance, channelName, callback, onlisten);
|
|
12582
|
+
}
|
|
12583
|
+
async _handleRecordListen(sqlInstance, originalListen, channelName, callback, onlisten, inputValue) {
|
|
12584
|
+
const receivedPayloads = [];
|
|
12585
|
+
const wrappedCallback = (payload) => {
|
|
12586
|
+
logger.debug(`[PostgresInstrumentation] RECORD: Captured notification payload on channel ${channelName}: ${payload}`);
|
|
12587
|
+
receivedPayloads.push(payload);
|
|
12588
|
+
callback(payload);
|
|
12589
|
+
};
|
|
12590
|
+
return handleRecordMode({
|
|
12591
|
+
originalFunctionCall: () => originalListen.call(sqlInstance, channelName, callback, onlisten),
|
|
12592
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
12593
|
+
return SpanUtils.createAndExecuteSpan(this.mode, () => originalListen.call(sqlInstance, channelName, callback, onlisten), {
|
|
12594
|
+
name: "postgres.listen",
|
|
12595
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
12596
|
+
submodule: "listen",
|
|
12597
|
+
packageType: PackageType.PG,
|
|
12598
|
+
packageName: "postgres",
|
|
12599
|
+
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12600
|
+
inputValue,
|
|
12601
|
+
isPreAppStart
|
|
12602
|
+
}, async (spanInfo) => {
|
|
12603
|
+
try {
|
|
12604
|
+
const result = await originalListen.call(sqlInstance, channelName, wrappedCallback, onlisten);
|
|
12605
|
+
try {
|
|
12606
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12607
|
+
channel: channelName,
|
|
12608
|
+
state: result.state
|
|
12609
|
+
} });
|
|
12610
|
+
} catch (error) {
|
|
12611
|
+
logger.error(`[PostgresInstrumentation] error adding span attributes:`, error);
|
|
12612
|
+
}
|
|
12613
|
+
const originalUnlisten = result.unlisten;
|
|
12614
|
+
const wrappedUnlisten = async () => {
|
|
12615
|
+
logger.debug(`[PostgresInstrumentation] RECORD: Unlisten called, captured ${receivedPayloads.length} payloads`);
|
|
12616
|
+
try {
|
|
12617
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12618
|
+
channel: channelName,
|
|
12619
|
+
state: result.state,
|
|
12620
|
+
payloads: receivedPayloads
|
|
12621
|
+
} });
|
|
12622
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12623
|
+
} catch (error) {
|
|
12624
|
+
logger.error(`[PostgresInstrumentation] error adding span attributes:`, error);
|
|
12625
|
+
}
|
|
12626
|
+
return originalUnlisten();
|
|
12627
|
+
};
|
|
12628
|
+
return {
|
|
12629
|
+
state: result.state,
|
|
12630
|
+
unlisten: wrappedUnlisten
|
|
12631
|
+
};
|
|
12632
|
+
} catch (error) {
|
|
12633
|
+
logger.error(`[PostgresInstrumentation] RECORD listen error: ${error.message}`);
|
|
12634
|
+
try {
|
|
12635
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
12636
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
12637
|
+
message: error.message
|
|
12638
|
+
});
|
|
12639
|
+
} catch (error$1) {
|
|
12640
|
+
logger.error(`[PostgresInstrumentation] error ending span:`, error$1);
|
|
12641
|
+
}
|
|
12642
|
+
throw error;
|
|
12643
|
+
}
|
|
12644
|
+
});
|
|
12645
|
+
},
|
|
12646
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
12647
|
+
});
|
|
12648
|
+
}
|
|
12649
|
+
async _handleReplayListen(channelName, callback, onlisten, inputValue) {
|
|
12650
|
+
logger.debug(`[PostgresInstrumentation] REPLAY: Mocking listen for channel ${channelName} without TCP`);
|
|
12651
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
12652
|
+
return handleReplayMode({
|
|
12653
|
+
noOpRequestHandler: () => Promise.resolve({
|
|
12654
|
+
state: { state: "I" },
|
|
12655
|
+
unlisten: async () => {}
|
|
12656
|
+
}),
|
|
12657
|
+
isServerRequest: false,
|
|
12658
|
+
replayModeHandler: () => {
|
|
12659
|
+
return SpanUtils.createAndExecuteSpan(this.mode, () => Promise.resolve({
|
|
12660
|
+
state: { state: "I" },
|
|
12661
|
+
unlisten: async () => {}
|
|
12662
|
+
}), {
|
|
12663
|
+
name: "postgres.listen",
|
|
12664
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
12665
|
+
submodule: "listen",
|
|
12666
|
+
packageType: PackageType.PG,
|
|
12667
|
+
packageName: "postgres",
|
|
12668
|
+
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12669
|
+
inputValue,
|
|
12670
|
+
isPreAppStart: this.tuskDrift.isAppReady() ? false : true
|
|
12671
|
+
}, async (spanInfo) => {
|
|
12672
|
+
try {
|
|
12673
|
+
const mockData = await this._findMockData({
|
|
12674
|
+
spanInfo,
|
|
12675
|
+
name: "postgres.listen",
|
|
12676
|
+
inputValue,
|
|
12677
|
+
submoduleName: "listen",
|
|
12678
|
+
stackTrace
|
|
12679
|
+
});
|
|
12680
|
+
if (!mockData) {
|
|
12681
|
+
logger.warn(`[PostgresInstrumentation] No mock data found for listen channel: ${channelName}`);
|
|
12682
|
+
throw new Error(`No mock data found for listen channel: ${channelName}`);
|
|
12683
|
+
}
|
|
12684
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for listen: ${JSON.stringify(mockData)}`);
|
|
12685
|
+
const recordedPayloads = mockData.result?.payloads || [];
|
|
12686
|
+
const recordedState = mockData.result?.state || { state: "I" };
|
|
12687
|
+
if (onlisten) onlisten();
|
|
12688
|
+
for (const payload of recordedPayloads) {
|
|
12689
|
+
logger.debug(`[PostgresInstrumentation] REPLAY: Invoking callback with recorded payload: ${payload}`);
|
|
12690
|
+
callback(payload);
|
|
12691
|
+
}
|
|
12692
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12693
|
+
return {
|
|
12694
|
+
state: recordedState,
|
|
12695
|
+
unlisten: async () => {
|
|
12696
|
+
logger.debug(`[PostgresInstrumentation] REPLAY: Mock unlisten called`);
|
|
12697
|
+
}
|
|
12698
|
+
};
|
|
12699
|
+
} catch (error) {
|
|
12700
|
+
logger.error(`[PostgresInstrumentation] REPLAY listen error: ${error.message}`);
|
|
12701
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
12702
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
12703
|
+
message: error.message
|
|
12704
|
+
});
|
|
12705
|
+
throw error;
|
|
12706
|
+
}
|
|
12707
|
+
});
|
|
12708
|
+
}
|
|
12709
|
+
});
|
|
12710
|
+
}
|
|
12397
12711
|
_getSqlPatchFn() {
|
|
12398
12712
|
const self = this;
|
|
12399
12713
|
return (originalSql) => {
|
|
@@ -12406,93 +12720,19 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12406
12720
|
if (!strings || !Array.isArray(strings.raw)) return originalSql.call(this, strings, ...values);
|
|
12407
12721
|
const creationContext = import_src$25.context.active();
|
|
12408
12722
|
const query = originalSql.call(this, strings, ...values);
|
|
12723
|
+
const inputValue = {
|
|
12724
|
+
query: reconstructQueryString(strings, values).trim(),
|
|
12725
|
+
parameters: values
|
|
12726
|
+
};
|
|
12409
12727
|
const originalThen = query.then.bind(query);
|
|
12410
|
-
|
|
12411
|
-
|
|
12412
|
-
|
|
12413
|
-
|
|
12414
|
-
|
|
12415
|
-
|
|
12416
|
-
|
|
12417
|
-
|
|
12418
|
-
query: queryString.trim(),
|
|
12419
|
-
parameters: values
|
|
12420
|
-
};
|
|
12421
|
-
return import_src$25.context.with(creationContext, () => {
|
|
12422
|
-
if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
12423
|
-
originalFunctionCall: () => originalThen(onFulfilled, onRejected),
|
|
12424
|
-
recordModeHandler: ({ isPreAppStart }) => {
|
|
12425
|
-
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12426
|
-
name: "postgres.query",
|
|
12427
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12428
|
-
submodule: "query",
|
|
12429
|
-
packageType: PackageType.PG,
|
|
12430
|
-
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
12431
|
-
packageName: "postgres",
|
|
12432
|
-
inputValue,
|
|
12433
|
-
isPreAppStart
|
|
12434
|
-
}, (spanInfo) => {
|
|
12435
|
-
const wrappedOnFulfilled = (result) => {
|
|
12436
|
-
try {
|
|
12437
|
-
logger.debug(`[PostgresInstrumentation] Postgres query completed successfully`, result);
|
|
12438
|
-
self._addOutputAttributesToSpan(spanInfo, result);
|
|
12439
|
-
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12440
|
-
} catch (error) {
|
|
12441
|
-
logger.error(`[PostgresInstrumentation] error processing query response:`, error);
|
|
12442
|
-
}
|
|
12443
|
-
return onFulfilled ? onFulfilled(result) : result;
|
|
12444
|
-
};
|
|
12445
|
-
const wrappedOnRejected = (error) => {
|
|
12446
|
-
try {
|
|
12447
|
-
logger.debug(`[PostgresInstrumentation] Postgres query error`, error);
|
|
12448
|
-
SpanUtils.endSpan(spanInfo.span, {
|
|
12449
|
-
code: import_src$25.SpanStatusCode.ERROR,
|
|
12450
|
-
message: error.message
|
|
12451
|
-
});
|
|
12452
|
-
} catch (spanError) {
|
|
12453
|
-
logger.error(`[PostgresInstrumentation] error ending span:`, spanError);
|
|
12454
|
-
}
|
|
12455
|
-
if (onRejected) return onRejected(error);
|
|
12456
|
-
throw error;
|
|
12457
|
-
};
|
|
12458
|
-
return originalThen(wrappedOnFulfilled, wrappedOnRejected);
|
|
12459
|
-
});
|
|
12460
|
-
},
|
|
12461
|
-
spanKind: import_src$25.SpanKind.CLIENT
|
|
12462
|
-
});
|
|
12463
|
-
else if (self.mode === TuskDriftMode.REPLAY) {
|
|
12464
|
-
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
12465
|
-
return handleReplayMode({
|
|
12466
|
-
noOpRequestHandler: () => Promise.resolve(Object.assign([], {
|
|
12467
|
-
count: 0,
|
|
12468
|
-
command: null
|
|
12469
|
-
})),
|
|
12470
|
-
isServerRequest: false,
|
|
12471
|
-
replayModeHandler: () => {
|
|
12472
|
-
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12473
|
-
name: "postgres.query",
|
|
12474
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12475
|
-
submodule: "query",
|
|
12476
|
-
packageType: PackageType.PG,
|
|
12477
|
-
packageName: "postgres",
|
|
12478
|
-
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
12479
|
-
inputValue,
|
|
12480
|
-
isPreAppStart: false
|
|
12481
|
-
}, async (spanInfo) => {
|
|
12482
|
-
const mockedResult = await self.handleReplaySqlQuery({
|
|
12483
|
-
inputValue,
|
|
12484
|
-
spanInfo,
|
|
12485
|
-
submodule: "query",
|
|
12486
|
-
name: "postgres.query",
|
|
12487
|
-
stackTrace
|
|
12488
|
-
});
|
|
12489
|
-
return onFulfilled ? onFulfilled(mockedResult) : mockedResult;
|
|
12490
|
-
});
|
|
12491
|
-
}
|
|
12492
|
-
});
|
|
12493
|
-
} else return originalThen(onFulfilled, onRejected);
|
|
12494
|
-
});
|
|
12495
|
-
};
|
|
12728
|
+
this._wrapThenMethod(query, originalThen, inputValue, creationContext, {
|
|
12729
|
+
name: "postgres.query",
|
|
12730
|
+
submodule: "query",
|
|
12731
|
+
operationType: "sql"
|
|
12732
|
+
});
|
|
12733
|
+
this._wrapExecuteMethod(query);
|
|
12734
|
+
this._wrapCursorMethod(query, inputValue, creationContext);
|
|
12735
|
+
this._wrapForEachMethod(query, inputValue, creationContext);
|
|
12496
12736
|
return query;
|
|
12497
12737
|
}
|
|
12498
12738
|
_handleUnsafeQuery(sqlInstance, originalUnsafe, query, parameters, queryOptions) {
|
|
@@ -12503,21 +12743,46 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12503
12743
|
})();
|
|
12504
12744
|
const creationContext = import_src$25.context.active();
|
|
12505
12745
|
const originalThen = unsafeQuery.then.bind(unsafeQuery);
|
|
12506
|
-
const self = this;
|
|
12507
12746
|
const inputValue = {
|
|
12508
12747
|
query: query.trim(),
|
|
12509
12748
|
parameters: parameters || [],
|
|
12510
12749
|
options: queryOptions
|
|
12511
12750
|
};
|
|
12512
|
-
unsafeQuery
|
|
12751
|
+
this._wrapThenMethod(unsafeQuery, originalThen, inputValue, creationContext, {
|
|
12752
|
+
name: "postgres.unsafe",
|
|
12753
|
+
submodule: "unsafe",
|
|
12754
|
+
operationType: "unsafe"
|
|
12755
|
+
});
|
|
12756
|
+
this._wrapExecuteMethod(unsafeQuery);
|
|
12757
|
+
this._wrapCursorMethod(unsafeQuery, inputValue, creationContext);
|
|
12758
|
+
this._wrapForEachMethod(unsafeQuery, inputValue, creationContext);
|
|
12759
|
+
return unsafeQuery;
|
|
12760
|
+
}
|
|
12761
|
+
_handleFileQuery(sqlInstance, originalFile, path$5, parameters, queryOptions) {
|
|
12762
|
+
const fileQuery = (() => {
|
|
12763
|
+
if (queryOptions !== void 0) return originalFile.call(sqlInstance, path$5, parameters, queryOptions);
|
|
12764
|
+
else if (parameters !== void 0) return originalFile.call(sqlInstance, path$5, parameters);
|
|
12765
|
+
else return originalFile.call(sqlInstance, path$5);
|
|
12766
|
+
})();
|
|
12767
|
+
const creationContext = import_src$25.context.active();
|
|
12768
|
+
const originalThen = fileQuery.then.bind(fileQuery);
|
|
12769
|
+
const self = this;
|
|
12770
|
+
const inputValue = {
|
|
12771
|
+
query: path$5,
|
|
12772
|
+
parameters: parameters || [],
|
|
12773
|
+
options: queryOptions
|
|
12774
|
+
};
|
|
12775
|
+
fileQuery.then = function(onFulfilled, onRejected) {
|
|
12776
|
+
if (fileQuery._tuskRecorded) return originalThen(onFulfilled, onRejected);
|
|
12777
|
+
fileQuery._tuskRecorded = true;
|
|
12513
12778
|
return import_src$25.context.with(creationContext, () => {
|
|
12514
12779
|
if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
12515
12780
|
originalFunctionCall: () => originalThen(onFulfilled, onRejected),
|
|
12516
12781
|
recordModeHandler: ({ isPreAppStart }) => {
|
|
12517
12782
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12518
|
-
name: "postgres.
|
|
12783
|
+
name: "postgres.file",
|
|
12519
12784
|
kind: import_src$25.SpanKind.CLIENT,
|
|
12520
|
-
submodule: "
|
|
12785
|
+
submodule: "file",
|
|
12521
12786
|
packageType: PackageType.PG,
|
|
12522
12787
|
packageName: "postgres",
|
|
12523
12788
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
@@ -12526,17 +12791,17 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12526
12791
|
}, (spanInfo) => {
|
|
12527
12792
|
const wrappedOnFulfilled = (result) => {
|
|
12528
12793
|
try {
|
|
12529
|
-
logger.debug(`[PostgresInstrumentation] Postgres
|
|
12530
|
-
|
|
12794
|
+
logger.debug(`[PostgresInstrumentation] Postgres file query completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12795
|
+
addOutputAttributesToSpan(spanInfo, result);
|
|
12531
12796
|
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12532
12797
|
} catch (error) {
|
|
12533
|
-
logger.error(`[PostgresInstrumentation] error processing
|
|
12798
|
+
logger.error(`[PostgresInstrumentation] error processing file query response:`, error);
|
|
12534
12799
|
}
|
|
12535
12800
|
return onFulfilled ? onFulfilled(result) : result;
|
|
12536
12801
|
};
|
|
12537
12802
|
const wrappedOnRejected = (error) => {
|
|
12538
12803
|
try {
|
|
12539
|
-
logger.debug(`[PostgresInstrumentation] Postgres
|
|
12804
|
+
logger.debug(`[PostgresInstrumentation] Postgres file query error: ${error.message}`);
|
|
12540
12805
|
SpanUtils.endSpan(spanInfo.span, {
|
|
12541
12806
|
code: import_src$25.SpanStatusCode.ERROR,
|
|
12542
12807
|
message: error.message
|
|
@@ -12562,22 +12827,24 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12562
12827
|
isServerRequest: false,
|
|
12563
12828
|
replayModeHandler: () => {
|
|
12564
12829
|
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
12565
|
-
name: "postgres.
|
|
12830
|
+
name: "postgres.file",
|
|
12566
12831
|
kind: import_src$25.SpanKind.CLIENT,
|
|
12567
|
-
submodule: "
|
|
12832
|
+
submodule: "file",
|
|
12568
12833
|
packageType: PackageType.PG,
|
|
12569
12834
|
packageName: "postgres",
|
|
12570
12835
|
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
12571
12836
|
inputValue,
|
|
12572
|
-
isPreAppStart: false
|
|
12837
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
12573
12838
|
}, async (spanInfo) => {
|
|
12574
|
-
const mockedResult = await self.
|
|
12839
|
+
const mockedResult = await self._handleReplayQueryOperation({
|
|
12575
12840
|
inputValue,
|
|
12576
12841
|
spanInfo,
|
|
12577
|
-
submodule: "
|
|
12578
|
-
name: "postgres.
|
|
12579
|
-
stackTrace
|
|
12842
|
+
submodule: "file",
|
|
12843
|
+
name: "postgres.file",
|
|
12844
|
+
stackTrace,
|
|
12845
|
+
operationType: "file"
|
|
12580
12846
|
});
|
|
12847
|
+
if (!mockedResult) throw new Error(`No mock data found for Postgres file query: ${inputValue.query}`);
|
|
12581
12848
|
return onFulfilled ? onFulfilled(mockedResult) : mockedResult;
|
|
12582
12849
|
});
|
|
12583
12850
|
}
|
|
@@ -12585,16 +12852,45 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12585
12852
|
} else return originalThen(onFulfilled, onRejected);
|
|
12586
12853
|
});
|
|
12587
12854
|
};
|
|
12588
|
-
|
|
12855
|
+
const originalExecute = fileQuery.execute ? fileQuery.execute.bind(fileQuery) : void 0;
|
|
12856
|
+
if (originalExecute) fileQuery.execute = function() {
|
|
12857
|
+
if (self.mode === TuskDriftMode.REPLAY) return this;
|
|
12858
|
+
else return originalExecute.call(this);
|
|
12859
|
+
};
|
|
12860
|
+
return fileQuery;
|
|
12861
|
+
}
|
|
12862
|
+
/**
|
|
12863
|
+
* Wraps a transaction callback to ensure the inner SQL instance is instrumented.
|
|
12864
|
+
* This is necessary because postgres.js creates a new SQL instance inside begin()
|
|
12865
|
+
* that would otherwise bypass instrumentation.
|
|
12866
|
+
*/
|
|
12867
|
+
_wrapTransactionCallback(transactionCallback) {
|
|
12868
|
+
const self = this;
|
|
12869
|
+
return (transactionSql) => {
|
|
12870
|
+
const wrappedSql = self._wrapSqlInstance(transactionSql);
|
|
12871
|
+
if (typeof transactionSql.savepoint === "function") {
|
|
12872
|
+
const originalSavepoint = transactionSql.savepoint;
|
|
12873
|
+
wrappedSql.savepoint = function(nameOrFn, fn) {
|
|
12874
|
+
const savepointCallback = typeof nameOrFn === "function" ? nameOrFn : fn;
|
|
12875
|
+
const savepointName = typeof nameOrFn === "string" ? nameOrFn : void 0;
|
|
12876
|
+
const wrappedSavepointCallback = self._wrapTransactionCallback(savepointCallback);
|
|
12877
|
+
if (savepointName) return originalSavepoint.call(transactionSql, savepointName, wrappedSavepointCallback);
|
|
12878
|
+
else return originalSavepoint.call(transactionSql, wrappedSavepointCallback);
|
|
12879
|
+
};
|
|
12880
|
+
}
|
|
12881
|
+
if (typeof transactionSql.prepare === "function") wrappedSql.prepare = transactionSql.prepare.bind(transactionSql);
|
|
12882
|
+
return transactionCallback(wrappedSql);
|
|
12883
|
+
};
|
|
12589
12884
|
}
|
|
12590
12885
|
_handleBeginTransaction(sqlInstance, originalBegin, options, transactionCallback) {
|
|
12591
12886
|
const inputValue = {
|
|
12592
12887
|
query: "BEGIN",
|
|
12593
12888
|
options: options ? { transactionOptions: options } : void 0
|
|
12594
12889
|
};
|
|
12890
|
+
const wrappedCallback = transactionCallback ? this._wrapTransactionCallback(transactionCallback) : void 0;
|
|
12595
12891
|
const executeBegin = () => {
|
|
12596
|
-
if (options &&
|
|
12597
|
-
else if (
|
|
12892
|
+
if (options && wrappedCallback) return originalBegin.call(sqlInstance, options, wrappedCallback);
|
|
12893
|
+
else if (wrappedCallback) return originalBegin.call(sqlInstance, wrappedCallback);
|
|
12598
12894
|
else return originalBegin.call(sqlInstance, options || void 0);
|
|
12599
12895
|
};
|
|
12600
12896
|
if (this.mode === TuskDriftMode.REPLAY) {
|
|
@@ -12611,9 +12907,9 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12611
12907
|
packageName: "postgres",
|
|
12612
12908
|
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12613
12909
|
inputValue,
|
|
12614
|
-
isPreAppStart: false
|
|
12910
|
+
isPreAppStart: this.tuskDrift.isAppReady() ? false : true
|
|
12615
12911
|
}, (spanInfo) => {
|
|
12616
|
-
return this._handleReplayBeginTransaction(spanInfo, options, stackTrace);
|
|
12912
|
+
return this._handleReplayBeginTransaction(spanInfo, options, stackTrace, wrappedCallback);
|
|
12617
12913
|
});
|
|
12618
12914
|
}
|
|
12619
12915
|
});
|
|
@@ -12638,151 +12934,672 @@ var PostgresInstrumentation = class extends TdInstrumentationBase {
|
|
|
12638
12934
|
else return executeBegin();
|
|
12639
12935
|
}
|
|
12640
12936
|
_handleRecordBeginTransaction(spanInfo, executeBegin) {
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12646
|
-
|
|
12647
|
-
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12937
|
+
return executeBegin().then((result) => {
|
|
12938
|
+
logger.debug(`[PostgresInstrumentation] Postgres transaction completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
12939
|
+
try {
|
|
12940
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12941
|
+
status: "committed",
|
|
12942
|
+
result
|
|
12943
|
+
} });
|
|
12944
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
12945
|
+
} catch (error) {
|
|
12946
|
+
logger.error(`[PostgresInstrumentation] error processing transaction response:`, error);
|
|
12947
|
+
}
|
|
12948
|
+
return result;
|
|
12949
|
+
}).catch((error) => {
|
|
12950
|
+
logger.debug(`[PostgresInstrumentation] Postgres transaction error (rolled back): ${error.message} (${SpanUtils.getTraceInfo()})`);
|
|
12951
|
+
try {
|
|
12952
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
12953
|
+
status: "rolled_back",
|
|
12954
|
+
error: error.message
|
|
12955
|
+
} });
|
|
12956
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
12957
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
12958
|
+
message: error.message
|
|
12959
|
+
});
|
|
12960
|
+
} catch (spanError) {
|
|
12961
|
+
logger.error(`[PostgresInstrumentation] error ending span:`, spanError);
|
|
12962
|
+
}
|
|
12963
|
+
throw error;
|
|
12964
|
+
});
|
|
12965
|
+
}
|
|
12966
|
+
async _handleReplayBeginTransaction(spanInfo, options, stackTrace, wrappedCallback) {
|
|
12967
|
+
logger.debug(`[PostgresInstrumentation] Replaying Postgres transaction`);
|
|
12968
|
+
const transactionInputValue = {
|
|
12969
|
+
query: "BEGIN",
|
|
12970
|
+
options: options ? { transactionOptions: options } : void 0
|
|
12971
|
+
};
|
|
12972
|
+
const mockData = await this._findMockData({
|
|
12973
|
+
spanInfo,
|
|
12974
|
+
name: "postgres.begin",
|
|
12975
|
+
inputValue: transactionInputValue,
|
|
12976
|
+
submoduleName: "transaction",
|
|
12977
|
+
stackTrace
|
|
12978
|
+
});
|
|
12979
|
+
if (!mockData) {
|
|
12980
|
+
logger.warn(`[PostgresInstrumentation] No mock data found for transaction BEGIN`);
|
|
12981
|
+
throw new Error(`[PostgresInstrumentation] No matching mock found for transaction BEGIN`);
|
|
12982
|
+
}
|
|
12983
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for transaction: ${JSON.stringify(mockData)}`);
|
|
12984
|
+
const transactionResult = mockData.result;
|
|
12985
|
+
const wasCommitted = transactionResult && typeof transactionResult === "object" && "status" in transactionResult && transactionResult.status === "committed";
|
|
12986
|
+
if (!wrappedCallback) if (wasCommitted) return transactionResult.result;
|
|
12987
|
+
else {
|
|
12988
|
+
const errorMessage = transactionResult && typeof transactionResult === "object" && "error" in transactionResult && transactionResult.error ? transactionResult.error : "Transaction rolled back";
|
|
12989
|
+
throw new Error(errorMessage);
|
|
12990
|
+
}
|
|
12991
|
+
try {
|
|
12992
|
+
const result = await wrappedCallback(this._createMockTransactionSql());
|
|
12993
|
+
logger.debug(`[PostgresInstrumentation] Replay transaction callback completed with result`);
|
|
12994
|
+
return result;
|
|
12995
|
+
} catch (error) {
|
|
12996
|
+
if (!wasCommitted) throw error;
|
|
12997
|
+
logger.error(`[PostgresInstrumentation] Unexpected error during transaction replay: ${error.message}`);
|
|
12998
|
+
throw error;
|
|
12999
|
+
}
|
|
13000
|
+
}
|
|
13001
|
+
/**
|
|
13002
|
+
* Creates a minimal mock SQL instance for transaction replay.
|
|
13003
|
+
* _wrapSqlInstance will wrap this and handle all the actual REPLAY logic.
|
|
13004
|
+
* The mock just needs to return objects with .then() methods that can be wrapped.
|
|
13005
|
+
*/
|
|
13006
|
+
_createMockTransactionSql() {
|
|
13007
|
+
const self = this;
|
|
13008
|
+
const createThenable = () => ({ then: (onFulfilled, onRejected) => Promise.resolve([]).then(onFulfilled, onRejected) });
|
|
13009
|
+
const mockSql = function() {
|
|
13010
|
+
return createThenable();
|
|
13011
|
+
};
|
|
13012
|
+
mockSql.unsafe = function() {
|
|
13013
|
+
return createThenable();
|
|
13014
|
+
};
|
|
13015
|
+
mockSql.savepoint = function(nameOrFn, fn) {
|
|
13016
|
+
const callback = typeof nameOrFn === "function" ? nameOrFn : fn;
|
|
13017
|
+
const nestedMockSql = self._createMockTransactionSql();
|
|
13018
|
+
return Promise.resolve(callback(nestedMockSql));
|
|
13019
|
+
};
|
|
13020
|
+
return mockSql;
|
|
13021
|
+
}
|
|
13022
|
+
/**
|
|
13023
|
+
* Generic helper to find mock data for replay operations.
|
|
13024
|
+
* Consolidates the common findMockResponseAsync pattern used across multiple handlers.
|
|
13025
|
+
*/
|
|
13026
|
+
async _findMockData({ spanInfo, name, inputValue, submoduleName, stackTrace }) {
|
|
13027
|
+
return findMockResponseAsync({
|
|
13028
|
+
mockRequestData: {
|
|
13029
|
+
traceId: spanInfo.traceId,
|
|
13030
|
+
spanId: spanInfo.spanId,
|
|
13031
|
+
name,
|
|
13032
|
+
inputValue: createMockInputValue(inputValue),
|
|
13033
|
+
packageName: "postgres",
|
|
13034
|
+
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
13035
|
+
submoduleName,
|
|
13036
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13037
|
+
stackTrace
|
|
13038
|
+
},
|
|
13039
|
+
tuskDrift: this.tuskDrift
|
|
13040
|
+
});
|
|
13041
|
+
}
|
|
13042
|
+
/**
|
|
13043
|
+
* Helper to end a cursor span with collected rows.
|
|
13044
|
+
* Consolidates common span ending logic used in cursor and forEach operations.
|
|
13045
|
+
*/
|
|
13046
|
+
_endCursorSpan(spanInfo, allRows, result, operation = "Cursor") {
|
|
13047
|
+
addOutputAttributesToSpan(spanInfo, Object.assign(allRows, {
|
|
13048
|
+
count: allRows.length,
|
|
13049
|
+
columns: result?.columns,
|
|
13050
|
+
state: result?.state,
|
|
13051
|
+
statement: result?.statement
|
|
13052
|
+
}));
|
|
13053
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13054
|
+
logger.debug(`[PostgresInstrumentation] ${operation} completed, recorded ${allRows.length} rows`);
|
|
13055
|
+
}
|
|
13056
|
+
/**
|
|
13057
|
+
* Generic helper to handle replay for query operations (sql, unsafe, file).
|
|
13058
|
+
* Consolidates common logic for finding mock data and processing results.
|
|
13059
|
+
*/
|
|
13060
|
+
async _handleReplayQueryOperation({ inputValue, spanInfo, submodule, name, stackTrace, operationType }) {
|
|
13061
|
+
logger.debug(`[PostgresInstrumentation] Replaying Postgres ${operationType} query`);
|
|
13062
|
+
const mockData = await this._findMockData({
|
|
13063
|
+
spanInfo,
|
|
13064
|
+
name,
|
|
13065
|
+
inputValue,
|
|
13066
|
+
submoduleName: submodule,
|
|
13067
|
+
stackTrace
|
|
13068
|
+
});
|
|
13069
|
+
if (!mockData) {
|
|
13070
|
+
const errorMsg = `[PostgresInstrumentation] No matching mock found for Postgres ${operationType} query: ${inputValue.query || "UNKNOWN_QUERY"}`;
|
|
13071
|
+
logger.warn(errorMsg);
|
|
13072
|
+
throw new Error(errorMsg);
|
|
13073
|
+
}
|
|
13074
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for Postgres ${operationType} query: ${JSON.stringify(mockData)}`);
|
|
13075
|
+
const processedResult = convertPostgresTypes(mockData.result);
|
|
13076
|
+
logger.debug(`[PostgresInstrumentation] ${operationType} query processed result: ${JSON.stringify(processedResult)}`);
|
|
13077
|
+
return processedResult;
|
|
13078
|
+
}
|
|
13079
|
+
_handleCursorCallbackRecord({ originalCursor, rows, inputValue, creationContext, userCallback }) {
|
|
13080
|
+
const self = this;
|
|
13081
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13082
|
+
return handleRecordMode({
|
|
13083
|
+
originalFunctionCall: () => originalCursor(rows, userCallback),
|
|
13084
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
13085
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalCursor(rows, userCallback), {
|
|
13086
|
+
name: "postgres.cursor",
|
|
13087
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13088
|
+
submodule: "cursor",
|
|
13089
|
+
packageType: PackageType.PG,
|
|
13090
|
+
packageName: "postgres",
|
|
13091
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13092
|
+
inputValue,
|
|
13093
|
+
isPreAppStart
|
|
13094
|
+
}, (spanInfo) => {
|
|
13095
|
+
return self._executeAndRecordCursorCallback({
|
|
13096
|
+
originalCursor,
|
|
13097
|
+
rows,
|
|
13098
|
+
userCallback,
|
|
13099
|
+
spanInfo
|
|
13100
|
+
});
|
|
13101
|
+
});
|
|
13102
|
+
},
|
|
13103
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
13104
|
+
});
|
|
13105
|
+
});
|
|
13106
|
+
}
|
|
13107
|
+
async _executeAndRecordCursorCallback({ originalCursor, rows, userCallback, spanInfo }) {
|
|
13108
|
+
const allRows = [];
|
|
13109
|
+
try {
|
|
13110
|
+
const wrappedCallback = (batchRows) => {
|
|
13111
|
+
allRows.push(...batchRows);
|
|
13112
|
+
return userCallback(batchRows);
|
|
13113
|
+
};
|
|
13114
|
+
const cursorPromise = originalCursor(rows, wrappedCallback);
|
|
13115
|
+
cursorPromise._tuskRecorded = true;
|
|
13116
|
+
const result = await cursorPromise;
|
|
13117
|
+
if (spanInfo) try {
|
|
13118
|
+
this._endCursorSpan(spanInfo, allRows, result, "Cursor callback");
|
|
13119
|
+
} catch (error) {
|
|
13120
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13121
|
+
}
|
|
13122
|
+
} catch (error) {
|
|
13123
|
+
logger.debug(`[PostgresInstrumentation] Cursor callback error: ${error.message}`);
|
|
13124
|
+
if (spanInfo) try {
|
|
13125
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13126
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13127
|
+
message: error.message
|
|
13128
|
+
});
|
|
13129
|
+
} catch (error$1) {
|
|
13130
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error$1);
|
|
13131
|
+
}
|
|
13132
|
+
throw error;
|
|
13133
|
+
}
|
|
13134
|
+
}
|
|
13135
|
+
_handleCursorCallbackReplay({ inputValue, creationContext, cursorBatchSize, userCallback }) {
|
|
13136
|
+
const self = this;
|
|
13137
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13138
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13139
|
+
return handleReplayMode({
|
|
13140
|
+
noOpRequestHandler: () => Promise.resolve(),
|
|
13141
|
+
isServerRequest: false,
|
|
13142
|
+
replayModeHandler: () => {
|
|
13143
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => Promise.resolve(), {
|
|
13144
|
+
name: "postgres.cursor",
|
|
13145
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13146
|
+
submodule: "cursor",
|
|
13147
|
+
packageType: PackageType.PG,
|
|
13148
|
+
packageName: "postgres",
|
|
13149
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13150
|
+
inputValue,
|
|
13151
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
13152
|
+
}, async (spanInfo) => {
|
|
13153
|
+
try {
|
|
13154
|
+
const mockData = await this._findMockData({
|
|
13155
|
+
spanInfo,
|
|
13156
|
+
name: "postgres.cursor",
|
|
13157
|
+
inputValue,
|
|
13158
|
+
submoduleName: "cursor",
|
|
13159
|
+
stackTrace
|
|
13160
|
+
});
|
|
13161
|
+
if (!mockData) throw new Error(`[PostgresInstrumentation] No matching mock found for cursor query: ${inputValue.query}`);
|
|
13162
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for cursor query: ${JSON.stringify(mockData)}`);
|
|
13163
|
+
const processedResult = convertPostgresTypes(mockData.result);
|
|
13164
|
+
const mockedData = Array.isArray(processedResult) ? processedResult : [];
|
|
13165
|
+
for (let i = 0; i < mockedData.length; i += cursorBatchSize) {
|
|
13166
|
+
const batch = mockedData.slice(i, i + cursorBatchSize);
|
|
13167
|
+
logger.debug(`[PostgresInstrumentation] Cursor replay calling callback with batch of ${batch.length} rows`);
|
|
13168
|
+
await userCallback(batch);
|
|
13169
|
+
}
|
|
13170
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13171
|
+
} catch (error) {
|
|
13172
|
+
logger.debug(`[PostgresInstrumentation] Cursor callback replay error: ${error.message}`);
|
|
13173
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13174
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13175
|
+
message: error.message
|
|
13176
|
+
});
|
|
13177
|
+
throw error;
|
|
13178
|
+
}
|
|
13179
|
+
});
|
|
12653
13180
|
}
|
|
12654
|
-
})
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
|
|
13181
|
+
});
|
|
13182
|
+
});
|
|
13183
|
+
}
|
|
13184
|
+
_handleCursorRecord({ originalCursor, rows, inputValue, creationContext, queryObject }) {
|
|
13185
|
+
const self = this;
|
|
13186
|
+
return { [Symbol.asyncIterator]() {
|
|
13187
|
+
const iterator = originalCursor(rows)[Symbol.asyncIterator]();
|
|
13188
|
+
let allRows = [];
|
|
13189
|
+
let result;
|
|
13190
|
+
let spanInfo = null;
|
|
13191
|
+
let spanStarted = false;
|
|
13192
|
+
return {
|
|
13193
|
+
async next() {
|
|
13194
|
+
return import_src$25.context.with(creationContext, async () => {
|
|
13195
|
+
if (!spanStarted) {
|
|
13196
|
+
spanStarted = true;
|
|
13197
|
+
let spanInputValue;
|
|
13198
|
+
try {
|
|
13199
|
+
spanInputValue = createSpanInputValue(inputValue);
|
|
13200
|
+
} catch (error) {
|
|
13201
|
+
logger.error(`[PostgresInstrumentation] error creating span input value:`, error);
|
|
13202
|
+
spanInputValue = void 0;
|
|
13203
|
+
}
|
|
13204
|
+
spanInfo = SpanUtils.createSpan({
|
|
13205
|
+
name: "postgres.cursor",
|
|
13206
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13207
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true,
|
|
13208
|
+
attributes: {
|
|
13209
|
+
[TdSpanAttributes.NAME]: "postgres.cursor",
|
|
13210
|
+
[TdSpanAttributes.PACKAGE_NAME]: "postgres",
|
|
13211
|
+
[TdSpanAttributes.SUBMODULE_NAME]: "cursor",
|
|
13212
|
+
[TdSpanAttributes.INSTRUMENTATION_NAME]: self.INSTRUMENTATION_NAME,
|
|
13213
|
+
[TdSpanAttributes.PACKAGE_TYPE]: PackageType.PG,
|
|
13214
|
+
[TdSpanAttributes.INPUT_VALUE]: spanInputValue,
|
|
13215
|
+
[TdSpanAttributes.IS_PRE_APP_START]: self.tuskDrift.isAppReady() ? false : true
|
|
13216
|
+
}
|
|
13217
|
+
});
|
|
13218
|
+
if (!spanInfo) logger.warn(`[PostgresInstrumentation] Failed to create cursor span in RECORD mode`);
|
|
13219
|
+
}
|
|
13220
|
+
try {
|
|
13221
|
+
result = await iterator.next();
|
|
13222
|
+
if (result.done) {
|
|
13223
|
+
if (spanInfo) try {
|
|
13224
|
+
self._endCursorSpan(spanInfo, allRows, queryObject, "Cursor");
|
|
13225
|
+
} catch (error) {
|
|
13226
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13227
|
+
}
|
|
13228
|
+
return {
|
|
13229
|
+
done: true,
|
|
13230
|
+
value: void 0
|
|
13231
|
+
};
|
|
13232
|
+
}
|
|
13233
|
+
if (Array.isArray(result.value)) allRows.push(...result.value);
|
|
13234
|
+
return {
|
|
13235
|
+
done: false,
|
|
13236
|
+
value: result.value
|
|
13237
|
+
};
|
|
13238
|
+
} catch (error) {
|
|
13239
|
+
if (spanInfo) try {
|
|
13240
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13241
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13242
|
+
message: error.message
|
|
13243
|
+
});
|
|
13244
|
+
} catch (error$1) {
|
|
13245
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error$1);
|
|
13246
|
+
}
|
|
13247
|
+
throw error;
|
|
13248
|
+
}
|
|
13249
|
+
});
|
|
13250
|
+
},
|
|
13251
|
+
async return() {
|
|
13252
|
+
if (spanInfo) try {
|
|
13253
|
+
self._endCursorSpan(spanInfo, allRows, queryObject, "Cursor terminated early");
|
|
13254
|
+
} catch (error) {
|
|
13255
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13256
|
+
}
|
|
13257
|
+
if (iterator.return) await iterator.return();
|
|
13258
|
+
return {
|
|
13259
|
+
done: true,
|
|
13260
|
+
value: void 0
|
|
13261
|
+
};
|
|
13262
|
+
}
|
|
13263
|
+
};
|
|
13264
|
+
} };
|
|
13265
|
+
}
|
|
13266
|
+
_handleCursorReplay({ inputValue, creationContext, cursorBatchSize }) {
|
|
13267
|
+
const self = this;
|
|
13268
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13269
|
+
return { [Symbol.asyncIterator]() {
|
|
13270
|
+
let mockedData = null;
|
|
13271
|
+
let currentIndex = 0;
|
|
13272
|
+
let spanInfo = null;
|
|
13273
|
+
let dataFetched = false;
|
|
13274
|
+
return {
|
|
13275
|
+
async next() {
|
|
13276
|
+
return import_src$25.context.with(creationContext, async () => {
|
|
13277
|
+
if (!dataFetched) {
|
|
13278
|
+
dataFetched = true;
|
|
13279
|
+
spanInfo = SpanUtils.createSpan({
|
|
13280
|
+
name: "postgres.cursor",
|
|
13281
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13282
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true,
|
|
13283
|
+
attributes: {
|
|
13284
|
+
[TdSpanAttributes.NAME]: "postgres.cursor",
|
|
13285
|
+
[TdSpanAttributes.PACKAGE_NAME]: "postgres",
|
|
13286
|
+
[TdSpanAttributes.SUBMODULE_NAME]: "cursor",
|
|
13287
|
+
[TdSpanAttributes.INSTRUMENTATION_NAME]: self.INSTRUMENTATION_NAME,
|
|
13288
|
+
[TdSpanAttributes.PACKAGE_TYPE]: PackageType.PG,
|
|
13289
|
+
[TdSpanAttributes.INPUT_VALUE]: createSpanInputValue(inputValue),
|
|
13290
|
+
[TdSpanAttributes.IS_PRE_APP_START]: self.tuskDrift.isAppReady() ? false : true
|
|
13291
|
+
}
|
|
13292
|
+
});
|
|
13293
|
+
if (!spanInfo) throw new Error(`[PostgresInstrumentation] Failed to create cursor span in REPLAY mode`);
|
|
13294
|
+
const mockData = await self._findMockData({
|
|
13295
|
+
spanInfo,
|
|
13296
|
+
name: "postgres.cursor",
|
|
13297
|
+
inputValue,
|
|
13298
|
+
submoduleName: "cursor",
|
|
13299
|
+
stackTrace
|
|
13300
|
+
});
|
|
13301
|
+
if (!mockData) {
|
|
13302
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13303
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13304
|
+
message: "No mock data found"
|
|
13305
|
+
});
|
|
13306
|
+
throw new Error(`[PostgresInstrumentation] No matching mock found for cursor query: ${inputValue.query}`);
|
|
13307
|
+
}
|
|
13308
|
+
logger.debug(`[PostgresInstrumentation] Found mock data for cursor query: ${JSON.stringify(mockData)}`);
|
|
13309
|
+
const processedResult = convertPostgresTypes(mockData.result);
|
|
13310
|
+
mockedData = Array.isArray(processedResult) ? processedResult : [];
|
|
13311
|
+
}
|
|
13312
|
+
if (currentIndex >= mockedData.length) {
|
|
13313
|
+
if (spanInfo) SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13314
|
+
return {
|
|
13315
|
+
done: true,
|
|
13316
|
+
value: void 0
|
|
13317
|
+
};
|
|
13318
|
+
}
|
|
13319
|
+
const batch = mockedData.slice(currentIndex, currentIndex + cursorBatchSize);
|
|
13320
|
+
currentIndex += batch.length;
|
|
13321
|
+
logger.debug(`[PostgresInstrumentation] Cursor replay returning batch of ${batch.length} rows`);
|
|
13322
|
+
return {
|
|
13323
|
+
done: false,
|
|
13324
|
+
value: batch
|
|
13325
|
+
};
|
|
13326
|
+
});
|
|
13327
|
+
},
|
|
13328
|
+
async return() {
|
|
13329
|
+
if (spanInfo) SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13330
|
+
return {
|
|
13331
|
+
done: true,
|
|
13332
|
+
value: void 0
|
|
13333
|
+
};
|
|
13334
|
+
}
|
|
13335
|
+
};
|
|
13336
|
+
} };
|
|
13337
|
+
}
|
|
13338
|
+
_handleForEachRecord({ originalForEach, inputValue, creationContext, userCallback }) {
|
|
13339
|
+
const self = this;
|
|
13340
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13341
|
+
return handleRecordMode({
|
|
13342
|
+
originalFunctionCall: () => originalForEach(userCallback),
|
|
13343
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
13344
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalForEach(userCallback), {
|
|
13345
|
+
name: "postgres.query",
|
|
13346
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13347
|
+
submodule: "query",
|
|
13348
|
+
packageType: PackageType.PG,
|
|
13349
|
+
packageName: "postgres",
|
|
13350
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13351
|
+
inputValue,
|
|
13352
|
+
isPreAppStart
|
|
13353
|
+
}, async (spanInfo) => {
|
|
13354
|
+
const allRows = [];
|
|
13355
|
+
const wrappedCallback = (row, result) => {
|
|
13356
|
+
allRows.push(row);
|
|
13357
|
+
return userCallback(row, result);
|
|
13358
|
+
};
|
|
13359
|
+
try {
|
|
13360
|
+
const result = await originalForEach(wrappedCallback);
|
|
13361
|
+
try {
|
|
13362
|
+
self._endCursorSpan(spanInfo, allRows, result, "forEach");
|
|
13363
|
+
} catch (error) {
|
|
13364
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error);
|
|
13365
|
+
}
|
|
13366
|
+
return result;
|
|
13367
|
+
} catch (error) {
|
|
13368
|
+
try {
|
|
13369
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13370
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13371
|
+
message: error.message
|
|
13372
|
+
});
|
|
13373
|
+
} catch (error$1) {
|
|
13374
|
+
logger.error(`[PostgresInstrumentation] error ending cursor span:`, error$1);
|
|
13375
|
+
}
|
|
13376
|
+
throw error;
|
|
13377
|
+
}
|
|
13378
|
+
});
|
|
13379
|
+
},
|
|
13380
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
13381
|
+
});
|
|
13382
|
+
});
|
|
13383
|
+
}
|
|
13384
|
+
_handleForEachReplay({ inputValue, creationContext, userCallback }) {
|
|
13385
|
+
const self = this;
|
|
13386
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13387
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13388
|
+
return handleReplayMode({
|
|
13389
|
+
noOpRequestHandler: () => Promise.resolve(Object.assign([], {
|
|
13390
|
+
count: 0,
|
|
13391
|
+
command: null
|
|
13392
|
+
})),
|
|
13393
|
+
isServerRequest: false,
|
|
13394
|
+
replayModeHandler: () => {
|
|
13395
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => Promise.resolve(Object.assign([], {
|
|
13396
|
+
count: 0,
|
|
13397
|
+
command: null
|
|
13398
|
+
})), {
|
|
13399
|
+
name: "postgres.query",
|
|
13400
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13401
|
+
submodule: "query",
|
|
13402
|
+
packageType: PackageType.PG,
|
|
13403
|
+
packageName: "postgres",
|
|
13404
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13405
|
+
inputValue,
|
|
13406
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
13407
|
+
}, async (spanInfo) => {
|
|
13408
|
+
try {
|
|
13409
|
+
const mockedResult = await self._handleReplayQueryOperation({
|
|
13410
|
+
inputValue,
|
|
13411
|
+
spanInfo,
|
|
13412
|
+
submodule: "query",
|
|
13413
|
+
name: "postgres.query",
|
|
13414
|
+
stackTrace,
|
|
13415
|
+
operationType: "forEach"
|
|
13416
|
+
});
|
|
13417
|
+
const mockedRows = Array.isArray(mockedResult) ? mockedResult : [];
|
|
13418
|
+
logger.debug(`[PostgresInstrumentation] forEach replay: calling callback with ${mockedRows.length} mocked rows`);
|
|
13419
|
+
for (const row of mockedRows) userCallback(row, mockedResult);
|
|
13420
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13421
|
+
return Object.assign([], {
|
|
13422
|
+
count: mockedRows.length,
|
|
13423
|
+
command: null
|
|
13424
|
+
});
|
|
13425
|
+
} catch (error) {
|
|
13426
|
+
logger.debug(`[PostgresInstrumentation] forEach replay error: ${error.message}`);
|
|
13427
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13428
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13429
|
+
message: error.message
|
|
13430
|
+
});
|
|
13431
|
+
throw error;
|
|
13432
|
+
}
|
|
13433
|
+
});
|
|
13434
|
+
}
|
|
13435
|
+
});
|
|
13436
|
+
});
|
|
13437
|
+
}
|
|
13438
|
+
/**
|
|
13439
|
+
* Wraps a query's .then() method to add instrumentation.
|
|
13440
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13441
|
+
*/
|
|
13442
|
+
_wrapThenMethod(query, originalThen, inputValue, creationContext, spanConfig) {
|
|
13443
|
+
const self = this;
|
|
13444
|
+
query.then = function(onFulfilled, onRejected) {
|
|
13445
|
+
if (query._forEachCalled) return originalThen(onFulfilled, onRejected);
|
|
13446
|
+
if (query._tuskRecorded) return originalThen(onFulfilled, onRejected);
|
|
13447
|
+
query._tuskRecorded = true;
|
|
13448
|
+
return import_src$25.context.with(creationContext, () => {
|
|
13449
|
+
if (self.mode === TuskDriftMode.RECORD) return handleRecordMode({
|
|
13450
|
+
originalFunctionCall: () => originalThen(onFulfilled, onRejected),
|
|
13451
|
+
recordModeHandler: ({ isPreAppStart }) => {
|
|
13452
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
13453
|
+
name: spanConfig.name,
|
|
13454
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13455
|
+
submodule: spanConfig.submodule,
|
|
13456
|
+
packageType: PackageType.PG,
|
|
13457
|
+
packageName: "postgres",
|
|
13458
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13459
|
+
inputValue,
|
|
13460
|
+
isPreAppStart
|
|
13461
|
+
}, (spanInfo) => {
|
|
13462
|
+
const wrappedOnFulfilled = (result) => {
|
|
13463
|
+
try {
|
|
13464
|
+
logger.debug(`[PostgresInstrumentation] Postgres ${spanConfig.operationType} query completed successfully (${SpanUtils.getTraceInfo()})`);
|
|
13465
|
+
addOutputAttributesToSpan(spanInfo, result);
|
|
13466
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$25.SpanStatusCode.OK });
|
|
13467
|
+
} catch (error) {
|
|
13468
|
+
logger.error(`[PostgresInstrumentation] error processing ${spanConfig.operationType} query response:`, error);
|
|
13469
|
+
}
|
|
13470
|
+
return onFulfilled ? onFulfilled(result) : result;
|
|
13471
|
+
};
|
|
13472
|
+
const wrappedOnRejected = (error) => {
|
|
13473
|
+
try {
|
|
13474
|
+
logger.debug(`[PostgresInstrumentation] Postgres ${spanConfig.operationType} query error: ${error.message}`);
|
|
13475
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
13476
|
+
code: import_src$25.SpanStatusCode.ERROR,
|
|
13477
|
+
message: error.message
|
|
13478
|
+
});
|
|
13479
|
+
} catch (spanError) {
|
|
13480
|
+
logger.error(`[PostgresInstrumentation] error ending span:`, spanError);
|
|
13481
|
+
}
|
|
13482
|
+
if (onRejected) return onRejected(error);
|
|
13483
|
+
throw error;
|
|
13484
|
+
};
|
|
13485
|
+
return originalThen(wrappedOnFulfilled, wrappedOnRejected);
|
|
13486
|
+
});
|
|
13487
|
+
},
|
|
13488
|
+
spanKind: import_src$25.SpanKind.CLIENT
|
|
13489
|
+
});
|
|
13490
|
+
else if (self.mode === TuskDriftMode.REPLAY) {
|
|
13491
|
+
const stackTrace = captureStackTrace(["PostgresInstrumentation"]);
|
|
13492
|
+
return handleReplayMode({
|
|
13493
|
+
noOpRequestHandler: () => Promise.resolve(Object.assign([], {
|
|
13494
|
+
count: 0,
|
|
13495
|
+
command: null
|
|
13496
|
+
})),
|
|
13497
|
+
isServerRequest: false,
|
|
13498
|
+
replayModeHandler: () => {
|
|
13499
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalThen(onFulfilled, onRejected), {
|
|
13500
|
+
name: spanConfig.name,
|
|
13501
|
+
kind: import_src$25.SpanKind.CLIENT,
|
|
13502
|
+
submodule: spanConfig.submodule,
|
|
13503
|
+
packageType: PackageType.PG,
|
|
13504
|
+
packageName: "postgres",
|
|
13505
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
13506
|
+
inputValue,
|
|
13507
|
+
isPreAppStart: self.tuskDrift.isAppReady() ? false : true
|
|
13508
|
+
}, async (spanInfo) => {
|
|
13509
|
+
const mockedResult = await self._handleReplayQueryOperation({
|
|
13510
|
+
inputValue,
|
|
13511
|
+
spanInfo,
|
|
13512
|
+
submodule: spanConfig.submodule,
|
|
13513
|
+
name: spanConfig.name,
|
|
13514
|
+
stackTrace,
|
|
13515
|
+
operationType: spanConfig.operationType
|
|
13516
|
+
});
|
|
13517
|
+
return onFulfilled ? onFulfilled(mockedResult) : mockedResult;
|
|
13518
|
+
});
|
|
13519
|
+
}
|
|
12664
13520
|
});
|
|
12665
|
-
}
|
|
12666
|
-
logger.error(`[PostgresInstrumentation] error ending span:`, spanError);
|
|
12667
|
-
}
|
|
13521
|
+
} else return originalThen(onFulfilled, onRejected);
|
|
12668
13522
|
});
|
|
12669
|
-
}
|
|
12670
|
-
return promise;
|
|
12671
|
-
}
|
|
12672
|
-
async _handleReplayBeginTransaction(spanInfo, options, stackTrace) {
|
|
12673
|
-
logger.debug(`[PostgresInstrumentation] Replaying Postgres transaction`);
|
|
12674
|
-
const mockData = await findMockResponseAsync({
|
|
12675
|
-
mockRequestData: {
|
|
12676
|
-
traceId: spanInfo.traceId,
|
|
12677
|
-
spanId: spanInfo.spanId,
|
|
12678
|
-
name: "postgres.begin",
|
|
12679
|
-
inputValue: createMockInputValue({
|
|
12680
|
-
query: "BEGIN",
|
|
12681
|
-
options: options ? { transactionOptions: options } : void 0
|
|
12682
|
-
}),
|
|
12683
|
-
packageName: "postgres",
|
|
12684
|
-
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12685
|
-
submoduleName: "transaction",
|
|
12686
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12687
|
-
stackTrace
|
|
12688
|
-
},
|
|
12689
|
-
tuskDrift: this.tuskDrift
|
|
12690
|
-
});
|
|
12691
|
-
if (!mockData) {
|
|
12692
|
-
logger.warn(`[PostgresInstrumentation] No mock data found for transaction BEGIN`);
|
|
12693
|
-
throw new Error(`[PostgresInstrumentation] No matching mock found for transaction BEGIN`);
|
|
12694
|
-
}
|
|
12695
|
-
logger.debug(`[PostgresInstrumentation] Found mock data for transaction: ${JSON.stringify(mockData)}`);
|
|
12696
|
-
const transactionResult = mockData.result;
|
|
12697
|
-
if (transactionResult && typeof transactionResult === "object" && "status" in transactionResult && transactionResult.status === "committed") return transactionResult.result;
|
|
12698
|
-
else {
|
|
12699
|
-
const errorMessage = transactionResult && typeof transactionResult === "object" && "error" in transactionResult && transactionResult.error ? transactionResult.error : "Transaction rolled back";
|
|
12700
|
-
throw new Error(errorMessage);
|
|
12701
|
-
}
|
|
12702
|
-
}
|
|
12703
|
-
async handleReplaySqlQuery({ inputValue, spanInfo, submodule, name, stackTrace }) {
|
|
12704
|
-
logger.debug(`[PostgresInstrumentation] Replaying Postgres sql query`);
|
|
12705
|
-
const mockData = await findMockResponseAsync({
|
|
12706
|
-
mockRequestData: {
|
|
12707
|
-
traceId: spanInfo.traceId,
|
|
12708
|
-
spanId: spanInfo.spanId,
|
|
12709
|
-
name,
|
|
12710
|
-
inputValue: createMockInputValue(inputValue),
|
|
12711
|
-
packageName: "postgres",
|
|
12712
|
-
instrumentationName: this.INSTRUMENTATION_NAME,
|
|
12713
|
-
submoduleName: submodule,
|
|
12714
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12715
|
-
stackTrace
|
|
12716
|
-
},
|
|
12717
|
-
tuskDrift: this.tuskDrift
|
|
12718
|
-
});
|
|
12719
|
-
if (!mockData) {
|
|
12720
|
-
const queryText = inputValue.query || "UNKNOWN_QUERY";
|
|
12721
|
-
logger.warn(`[PostgresInstrumentation] No mock data found for Postgres sql query: ${queryText}`);
|
|
12722
|
-
throw new Error(`[PostgresInstrumentation] No matching mock found for Postgres sql query: ${queryText}`);
|
|
12723
|
-
}
|
|
12724
|
-
logger.debug(`[PostgresInstrumentation] Found mock data for Postgres sql query: ${JSON.stringify(mockData)}`);
|
|
12725
|
-
const processedResult = this.convertPostgresTypes(mockData.result);
|
|
12726
|
-
logger.debug(`[PostgresInstrumentation] Sql query processed result: ${JSON.stringify(processedResult)}`);
|
|
12727
|
-
return processedResult;
|
|
13523
|
+
};
|
|
12728
13524
|
}
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
|
|
12739
|
-
|
|
12740
|
-
kind: import_src$25.SpanKind.CLIENT,
|
|
12741
|
-
stackTrace
|
|
12742
|
-
},
|
|
12743
|
-
tuskDrift: this.tuskDrift
|
|
12744
|
-
});
|
|
12745
|
-
if (!mockData) {
|
|
12746
|
-
const queryText = inputValue.query || "UNKNOWN_QUERY";
|
|
12747
|
-
logger.warn(`[PostgresInstrumentation] No mock data found for Postgres unsafe query: ${queryText}`);
|
|
12748
|
-
throw new Error(`[PostgresInstrumentation] No matching mock found for Postgres unsafe query: ${queryText}`);
|
|
12749
|
-
}
|
|
12750
|
-
logger.debug(`[PostgresInstrumentation] Found mock data for Postgres unsafe query: ${JSON.stringify(mockData)}`);
|
|
12751
|
-
const processedResult = this.convertPostgresTypes(mockData.result);
|
|
12752
|
-
logger.debug(`[PostgresInstrumentation] Unsafe query processed result: ${JSON.stringify(processedResult)}`);
|
|
12753
|
-
return processedResult;
|
|
13525
|
+
/**
|
|
13526
|
+
* Wraps a query's .execute() method to prevent TCP calls in REPLAY mode.
|
|
13527
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13528
|
+
*/
|
|
13529
|
+
_wrapExecuteMethod(query) {
|
|
13530
|
+
const self = this;
|
|
13531
|
+
const originalExecute = query.execute ? query.execute.bind(query) : void 0;
|
|
13532
|
+
if (originalExecute) query.execute = function() {
|
|
13533
|
+
if (self.mode === TuskDriftMode.REPLAY) return this;
|
|
13534
|
+
else return originalExecute.call(this);
|
|
13535
|
+
};
|
|
12754
13536
|
}
|
|
12755
|
-
|
|
12756
|
-
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
const
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
}
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
|
|
13537
|
+
/**
|
|
13538
|
+
* Wraps a query's cursor() method to add instrumentation.
|
|
13539
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13540
|
+
*/
|
|
13541
|
+
_wrapCursorMethod(query, inputValue, creationContext) {
|
|
13542
|
+
if (typeof query.cursor !== "function") return;
|
|
13543
|
+
const self = this;
|
|
13544
|
+
const originalCursor = query.cursor.bind(query);
|
|
13545
|
+
query.cursor = function(rows, fn) {
|
|
13546
|
+
if (typeof rows === "function") {
|
|
13547
|
+
fn = rows;
|
|
13548
|
+
rows = 1;
|
|
13549
|
+
}
|
|
13550
|
+
if (!rows) rows = 1;
|
|
13551
|
+
if (typeof fn === "function") if (self.mode === TuskDriftMode.RECORD) return self._handleCursorCallbackRecord({
|
|
13552
|
+
originalCursor,
|
|
13553
|
+
rows,
|
|
13554
|
+
inputValue,
|
|
13555
|
+
creationContext,
|
|
13556
|
+
userCallback: fn
|
|
13557
|
+
});
|
|
13558
|
+
else if (self.mode === TuskDriftMode.REPLAY) return self._handleCursorCallbackReplay({
|
|
13559
|
+
inputValue,
|
|
13560
|
+
creationContext,
|
|
13561
|
+
cursorBatchSize: rows,
|
|
13562
|
+
userCallback: fn
|
|
13563
|
+
});
|
|
13564
|
+
else return originalCursor(rows, fn);
|
|
13565
|
+
if (self.mode === TuskDriftMode.RECORD) return self._handleCursorRecord({
|
|
13566
|
+
originalCursor,
|
|
13567
|
+
rows,
|
|
13568
|
+
inputValue,
|
|
13569
|
+
creationContext,
|
|
13570
|
+
queryObject: this
|
|
13571
|
+
});
|
|
13572
|
+
else if (self.mode === TuskDriftMode.REPLAY) return self._handleCursorReplay({
|
|
13573
|
+
inputValue,
|
|
13574
|
+
creationContext,
|
|
13575
|
+
cursorBatchSize: rows
|
|
13576
|
+
});
|
|
13577
|
+
else return originalCursor(rows);
|
|
13578
|
+
};
|
|
12775
13579
|
}
|
|
12776
|
-
|
|
12777
|
-
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
13580
|
+
/**
|
|
13581
|
+
* Wraps a query's forEach() method to add instrumentation.
|
|
13582
|
+
* This is reusable for both sql template literals and unsafe() queries.
|
|
13583
|
+
*/
|
|
13584
|
+
_wrapForEachMethod(query, inputValue, creationContext) {
|
|
13585
|
+
if (typeof query.forEach !== "function") return;
|
|
13586
|
+
const self = this;
|
|
13587
|
+
const originalForEach = query.forEach.bind(query);
|
|
13588
|
+
query.forEach = function(fn) {
|
|
13589
|
+
query._forEachCalled = true;
|
|
13590
|
+
if (self.mode === TuskDriftMode.RECORD) return self._handleForEachRecord({
|
|
13591
|
+
originalForEach,
|
|
13592
|
+
inputValue,
|
|
13593
|
+
creationContext,
|
|
13594
|
+
userCallback: fn
|
|
13595
|
+
});
|
|
13596
|
+
else if (self.mode === TuskDriftMode.REPLAY) return self._handleForEachReplay({
|
|
13597
|
+
inputValue,
|
|
13598
|
+
creationContext,
|
|
13599
|
+
userCallback: fn
|
|
13600
|
+
});
|
|
13601
|
+
else return originalForEach(fn);
|
|
12784
13602
|
};
|
|
12785
|
-
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
12786
13603
|
}
|
|
12787
13604
|
_wrap(target, propertyName, wrapper) {
|
|
12788
13605
|
wrap(target, propertyName, wrapper);
|
|
@@ -12805,8 +13622,9 @@ function isMysqlOkPacket(result) {
|
|
|
12805
13622
|
* Extends EventEmitter to properly handle all connection methods and events
|
|
12806
13623
|
*/
|
|
12807
13624
|
var TdMysqlConnectionMock = class extends events.EventEmitter {
|
|
12808
|
-
constructor(mysqlInstrumentation, clientType = "poolConnection", spanInfo) {
|
|
13625
|
+
constructor(mysqlInstrumentation, clientType = "poolConnection", spanInfo, pool) {
|
|
12809
13626
|
super();
|
|
13627
|
+
this._pool = null;
|
|
12810
13628
|
this.threadId = null;
|
|
12811
13629
|
this.config = {
|
|
12812
13630
|
host: "localhost",
|
|
@@ -12818,6 +13636,7 @@ var TdMysqlConnectionMock = class extends events.EventEmitter {
|
|
|
12818
13636
|
this.spanInfo = spanInfo;
|
|
12819
13637
|
this.clientType = clientType;
|
|
12820
13638
|
this.threadId = 1;
|
|
13639
|
+
this._pool = pool;
|
|
12821
13640
|
}
|
|
12822
13641
|
query(...args) {
|
|
12823
13642
|
logger.debug(`[TdMysqlConnectionMock] Mock connection query intercepted in REPLAY mode`);
|
|
@@ -12825,7 +13644,13 @@ var TdMysqlConnectionMock = class extends events.EventEmitter {
|
|
|
12825
13644
|
let values;
|
|
12826
13645
|
let callback;
|
|
12827
13646
|
let options = {};
|
|
12828
|
-
|
|
13647
|
+
const firstArg = args[0];
|
|
13648
|
+
if (firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function") {
|
|
13649
|
+
sql = firstArg.sql;
|
|
13650
|
+
values = firstArg.values;
|
|
13651
|
+
callback = firstArg._callback;
|
|
13652
|
+
options = { nestTables: firstArg.nestTables };
|
|
13653
|
+
} else if (typeof args[0] === "string") {
|
|
12829
13654
|
sql = args[0];
|
|
12830
13655
|
if (typeof args[1] === "function") callback = args[1];
|
|
12831
13656
|
else if (Array.isArray(args[1])) {
|
|
@@ -12877,6 +13702,7 @@ var TdMysqlConnectionMock = class extends events.EventEmitter {
|
|
|
12877
13702
|
}
|
|
12878
13703
|
}
|
|
12879
13704
|
release() {
|
|
13705
|
+
if (this._pool) this._pool.emit("release", this);
|
|
12880
13706
|
this.emit("end");
|
|
12881
13707
|
}
|
|
12882
13708
|
destroy() {
|
|
@@ -12901,19 +13727,22 @@ var TdMysqlConnectionMock = class extends events.EventEmitter {
|
|
|
12901
13727
|
return;
|
|
12902
13728
|
}
|
|
12903
13729
|
}
|
|
12904
|
-
beginTransaction(
|
|
13730
|
+
beginTransaction(optionsOrCallback, callbackArg) {
|
|
13731
|
+
const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : callbackArg;
|
|
12905
13732
|
if (callback) {
|
|
12906
13733
|
process.nextTick(() => callback(null));
|
|
12907
13734
|
return;
|
|
12908
13735
|
}
|
|
12909
13736
|
}
|
|
12910
|
-
commit(
|
|
13737
|
+
commit(optionsOrCallback, callbackArg) {
|
|
13738
|
+
const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : callbackArg;
|
|
12911
13739
|
if (callback) {
|
|
12912
13740
|
process.nextTick(() => callback(null));
|
|
12913
13741
|
return;
|
|
12914
13742
|
}
|
|
12915
13743
|
}
|
|
12916
|
-
rollback(
|
|
13744
|
+
rollback(optionsOrCallback, callbackArg) {
|
|
13745
|
+
const callback = typeof optionsOrCallback === "function" ? optionsOrCallback : callbackArg;
|
|
12917
13746
|
if (callback) {
|
|
12918
13747
|
process.nextTick(() => callback(null));
|
|
12919
13748
|
return;
|
|
@@ -13109,6 +13938,11 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13109
13938
|
name: "mysql/lib/Pool.js",
|
|
13110
13939
|
supportedVersions: ["2.*"],
|
|
13111
13940
|
patch: (moduleExports) => this._patchPoolFile(moduleExports)
|
|
13941
|
+
}),
|
|
13942
|
+
new TdInstrumentationNodeModuleFile({
|
|
13943
|
+
name: "mysql/lib/PoolNamespace.js",
|
|
13944
|
+
supportedVersions: ["2.*"],
|
|
13945
|
+
patch: (moduleExports) => this._patchPoolNamespaceFile(moduleExports)
|
|
13112
13946
|
})
|
|
13113
13947
|
]
|
|
13114
13948
|
})];
|
|
@@ -13248,12 +14082,40 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13248
14082
|
return PoolClass;
|
|
13249
14083
|
}
|
|
13250
14084
|
/**
|
|
14085
|
+
* Patch PoolNamespace.prototype methods at the file level
|
|
14086
|
+
* This handles queries made via poolCluster.of("pattern").query()
|
|
14087
|
+
*/
|
|
14088
|
+
_patchPoolNamespaceFile(PoolNamespaceClass) {
|
|
14089
|
+
logger.debug(`[MysqlInstrumentation] Patching PoolNamespace class (file-based)`);
|
|
14090
|
+
if (this.isModulePatched(PoolNamespaceClass)) {
|
|
14091
|
+
logger.debug(`[MysqlInstrumentation] PoolNamespace class already patched, skipping`);
|
|
14092
|
+
return PoolNamespaceClass;
|
|
14093
|
+
}
|
|
14094
|
+
if (PoolNamespaceClass.prototype && PoolNamespaceClass.prototype.query) {
|
|
14095
|
+
if (!isWrapped$1(PoolNamespaceClass.prototype.query)) {
|
|
14096
|
+
this._wrap(PoolNamespaceClass.prototype, "query", this._getPoolNamespaceQueryPatchFn());
|
|
14097
|
+
logger.debug(`[MysqlInstrumentation] Wrapped PoolNamespace.prototype.query`);
|
|
14098
|
+
}
|
|
14099
|
+
}
|
|
14100
|
+
if (PoolNamespaceClass.prototype && PoolNamespaceClass.prototype.getConnection) {
|
|
14101
|
+
if (!isWrapped$1(PoolNamespaceClass.prototype.getConnection)) {
|
|
14102
|
+
this._wrap(PoolNamespaceClass.prototype, "getConnection", this._getPoolNamespaceGetConnectionPatchFn());
|
|
14103
|
+
logger.debug(`[MysqlInstrumentation] Wrapped PoolNamespace.prototype.getConnection`);
|
|
14104
|
+
}
|
|
14105
|
+
}
|
|
14106
|
+
this.markModuleAsPatched(PoolNamespaceClass);
|
|
14107
|
+
logger.debug(`[MysqlInstrumentation] PoolNamespace class patching complete`);
|
|
14108
|
+
return PoolNamespaceClass;
|
|
14109
|
+
}
|
|
14110
|
+
/**
|
|
13251
14111
|
* Get wrapper function for query method (prototype-level patching)
|
|
13252
14112
|
*/
|
|
13253
14113
|
_getQueryPatchFn() {
|
|
13254
14114
|
const self = this;
|
|
13255
14115
|
return (originalQuery) => {
|
|
13256
14116
|
return function query(...args) {
|
|
14117
|
+
const firstArg = args[0];
|
|
14118
|
+
const hasInternalCallback = firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function";
|
|
13257
14119
|
let sql;
|
|
13258
14120
|
let values;
|
|
13259
14121
|
let callback;
|
|
@@ -13264,6 +14126,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13264
14126
|
values = queryObj.values;
|
|
13265
14127
|
options = { nestTables: queryObj.nestTables };
|
|
13266
14128
|
callback = args.find((arg) => typeof arg === "function");
|
|
14129
|
+
if (!callback && hasInternalCallback) callback = firstArg._callback;
|
|
13267
14130
|
} catch (error) {
|
|
13268
14131
|
logger.debug(`[MysqlInstrumentation] Error using createQuery, falling back to manual parsing:`, error);
|
|
13269
14132
|
({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
@@ -13274,7 +14137,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13274
14137
|
values,
|
|
13275
14138
|
options: options.nestTables ? { nestTables: options.nestTables } : void 0
|
|
13276
14139
|
};
|
|
13277
|
-
const isEventEmitterMode = !callback;
|
|
14140
|
+
const isEventEmitterMode = !callback && !hasInternalCallback;
|
|
13278
14141
|
if (self.mode === TuskDriftMode.REPLAY) {
|
|
13279
14142
|
const stackTrace = captureStackTrace(["MysqlInstrumentation"]);
|
|
13280
14143
|
return handleReplayMode({
|
|
@@ -13370,11 +14233,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13370
14233
|
_getBeginTransactionPatchFn() {
|
|
13371
14234
|
const self = this;
|
|
13372
14235
|
return (originalBeginTransaction) => {
|
|
13373
|
-
return function beginTransaction(
|
|
14236
|
+
return function beginTransaction(optionsOrCallback, callbackArg) {
|
|
14237
|
+
let actualCallback;
|
|
14238
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14239
|
+
else actualCallback = callbackArg;
|
|
13374
14240
|
const inputValue = { query: "BEGIN" };
|
|
13375
14241
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13376
14242
|
noOpRequestHandler: () => {
|
|
13377
|
-
if (
|
|
14243
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13378
14244
|
},
|
|
13379
14245
|
isServerRequest: false,
|
|
13380
14246
|
replayModeHandler: () => {
|
|
@@ -13388,7 +14254,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13388
14254
|
inputValue,
|
|
13389
14255
|
isPreAppStart: false
|
|
13390
14256
|
}, (spanInfo) => {
|
|
13391
|
-
return self._handleReplayTransaction(inputValue,
|
|
14257
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13392
14258
|
});
|
|
13393
14259
|
}
|
|
13394
14260
|
});
|
|
@@ -13405,7 +14271,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13405
14271
|
inputValue,
|
|
13406
14272
|
isPreAppStart
|
|
13407
14273
|
}, (spanInfo) => {
|
|
13408
|
-
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, this, arguments,
|
|
14274
|
+
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, this, arguments, actualCallback);
|
|
13409
14275
|
});
|
|
13410
14276
|
},
|
|
13411
14277
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13420,11 +14286,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13420
14286
|
_getCommitPatchFn() {
|
|
13421
14287
|
const self = this;
|
|
13422
14288
|
return (originalCommit) => {
|
|
13423
|
-
return function commit(
|
|
14289
|
+
return function commit(optionsOrCallback, callbackArg) {
|
|
14290
|
+
let actualCallback;
|
|
14291
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14292
|
+
else actualCallback = callbackArg;
|
|
13424
14293
|
const inputValue = { query: "COMMIT" };
|
|
13425
14294
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13426
14295
|
noOpRequestHandler: () => {
|
|
13427
|
-
if (
|
|
14296
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13428
14297
|
},
|
|
13429
14298
|
isServerRequest: false,
|
|
13430
14299
|
replayModeHandler: () => {
|
|
@@ -13438,7 +14307,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13438
14307
|
inputValue,
|
|
13439
14308
|
isPreAppStart: false
|
|
13440
14309
|
}, (spanInfo) => {
|
|
13441
|
-
return self._handleReplayTransaction(inputValue,
|
|
14310
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13442
14311
|
});
|
|
13443
14312
|
}
|
|
13444
14313
|
});
|
|
@@ -13455,7 +14324,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13455
14324
|
inputValue,
|
|
13456
14325
|
isPreAppStart
|
|
13457
14326
|
}, (spanInfo) => {
|
|
13458
|
-
return self._handleRecordTransaction(spanInfo, originalCommit, this, arguments,
|
|
14327
|
+
return self._handleRecordTransaction(spanInfo, originalCommit, this, arguments, actualCallback);
|
|
13459
14328
|
});
|
|
13460
14329
|
},
|
|
13461
14330
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13470,11 +14339,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13470
14339
|
_getRollbackPatchFn() {
|
|
13471
14340
|
const self = this;
|
|
13472
14341
|
return (originalRollback) => {
|
|
13473
|
-
return function rollback(
|
|
14342
|
+
return function rollback(optionsOrCallback, callbackArg) {
|
|
14343
|
+
let actualCallback;
|
|
14344
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14345
|
+
else actualCallback = callbackArg;
|
|
13474
14346
|
const inputValue = { query: "ROLLBACK" };
|
|
13475
14347
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13476
14348
|
noOpRequestHandler: () => {
|
|
13477
|
-
if (
|
|
14349
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13478
14350
|
},
|
|
13479
14351
|
isServerRequest: false,
|
|
13480
14352
|
replayModeHandler: () => {
|
|
@@ -13488,7 +14360,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13488
14360
|
inputValue,
|
|
13489
14361
|
isPreAppStart: false
|
|
13490
14362
|
}, (spanInfo) => {
|
|
13491
|
-
return self._handleReplayTransaction(inputValue,
|
|
14363
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13492
14364
|
});
|
|
13493
14365
|
}
|
|
13494
14366
|
});
|
|
@@ -13505,7 +14377,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13505
14377
|
inputValue,
|
|
13506
14378
|
isPreAppStart
|
|
13507
14379
|
}, (spanInfo) => {
|
|
13508
|
-
return self._handleRecordTransaction(spanInfo, originalRollback, this, arguments,
|
|
14380
|
+
return self._handleRecordTransaction(spanInfo, originalRollback, this, arguments, actualCallback);
|
|
13509
14381
|
});
|
|
13510
14382
|
},
|
|
13511
14383
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13673,9 +14545,10 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13673
14545
|
return (originalGetConnection) => {
|
|
13674
14546
|
return function getConnection(callback) {
|
|
13675
14547
|
const inputValue = { clientType: "pool" };
|
|
14548
|
+
const pool = this;
|
|
13676
14549
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13677
14550
|
noOpRequestHandler: () => {
|
|
13678
|
-
return self._handleNoOpReplayGetConnection(callback);
|
|
14551
|
+
return self._handleNoOpReplayGetConnection(pool, callback);
|
|
13679
14552
|
},
|
|
13680
14553
|
isServerRequest: false,
|
|
13681
14554
|
replayModeHandler: () => {
|
|
@@ -13689,7 +14562,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13689
14562
|
inputValue,
|
|
13690
14563
|
isPreAppStart: false
|
|
13691
14564
|
}, (spanInfo) => {
|
|
13692
|
-
return self._handleReplayPoolGetConnection(spanInfo, callback);
|
|
14565
|
+
return self._handleReplayPoolGetConnection(pool, spanInfo, callback);
|
|
13693
14566
|
});
|
|
13694
14567
|
}
|
|
13695
14568
|
});
|
|
@@ -13719,6 +14592,8 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13719
14592
|
const self = this;
|
|
13720
14593
|
return (originalQuery) => {
|
|
13721
14594
|
return function query(...args) {
|
|
14595
|
+
const firstArg = args[0];
|
|
14596
|
+
const hasInternalCallback = firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function";
|
|
13722
14597
|
let sql;
|
|
13723
14598
|
let values;
|
|
13724
14599
|
let callback;
|
|
@@ -13729,6 +14604,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13729
14604
|
values = queryObj.values;
|
|
13730
14605
|
options = { nestTables: queryObj.nestTables };
|
|
13731
14606
|
callback = args.find((arg) => typeof arg === "function");
|
|
14607
|
+
if (!callback && hasInternalCallback) callback = firstArg._callback;
|
|
13732
14608
|
} catch (error) {
|
|
13733
14609
|
logger.debug(`[MysqlInstrumentation] Error using createQuery, falling back to manual parsing:`, error);
|
|
13734
14610
|
({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
@@ -13739,7 +14615,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13739
14615
|
values,
|
|
13740
14616
|
options: options.nestTables ? { nestTables: options.nestTables } : void 0
|
|
13741
14617
|
};
|
|
13742
|
-
const isEventEmitterMode = !callback;
|
|
14618
|
+
const isEventEmitterMode = !callback && !hasInternalCallback;
|
|
13743
14619
|
if (self.mode === TuskDriftMode.REPLAY) {
|
|
13744
14620
|
const stackTrace = captureStackTrace(["MysqlInstrumentation"]);
|
|
13745
14621
|
return handleReplayMode({
|
|
@@ -13841,6 +14717,33 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13841
14717
|
});
|
|
13842
14718
|
return queryEmitter;
|
|
13843
14719
|
} else {
|
|
14720
|
+
const queryObject = args[0];
|
|
14721
|
+
if (queryObject && typeof queryObject === "object" && typeof queryObject._callback === "function") {
|
|
14722
|
+
const originalCallback$1 = queryObject._callback;
|
|
14723
|
+
queryObject._callback = function(err, results, fields) {
|
|
14724
|
+
if (err) try {
|
|
14725
|
+
SpanUtils.endSpan(spanInfo.span, {
|
|
14726
|
+
code: import_src$23.SpanStatusCode.ERROR,
|
|
14727
|
+
message: err.message
|
|
14728
|
+
});
|
|
14729
|
+
} catch (error) {
|
|
14730
|
+
logger.error(`[MysqlInstrumentation] error ending span:`, error);
|
|
14731
|
+
}
|
|
14732
|
+
else try {
|
|
14733
|
+
const outputValue = {
|
|
14734
|
+
results,
|
|
14735
|
+
fields
|
|
14736
|
+
};
|
|
14737
|
+
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue });
|
|
14738
|
+
SpanUtils.endSpan(spanInfo.span, { code: import_src$23.SpanStatusCode.OK });
|
|
14739
|
+
} catch (error) {
|
|
14740
|
+
logger.error(`[MysqlInstrumentation] error ending span:`, error);
|
|
14741
|
+
}
|
|
14742
|
+
logger.debug(`[MysqlInstrumentation] Query completed`);
|
|
14743
|
+
originalCallback$1.call(this, err, results, fields);
|
|
14744
|
+
};
|
|
14745
|
+
return originalQuery.apply(connection, args);
|
|
14746
|
+
}
|
|
13844
14747
|
const originalCallback = callback;
|
|
13845
14748
|
const callbackIndex = args.findIndex((arg) => typeof arg === "function");
|
|
13846
14749
|
args[callbackIndex] = function(err, results, fields) {
|
|
@@ -13895,11 +14798,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13895
14798
|
_patchBeginTransaction(connection) {
|
|
13896
14799
|
const self = this;
|
|
13897
14800
|
return (originalBeginTransaction) => {
|
|
13898
|
-
return function beginTransaction(
|
|
14801
|
+
return function beginTransaction(optionsOrCallback, callbackArg) {
|
|
14802
|
+
let actualCallback;
|
|
14803
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14804
|
+
else actualCallback = callbackArg;
|
|
13899
14805
|
const inputValue = { query: "BEGIN" };
|
|
13900
14806
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13901
14807
|
noOpRequestHandler: () => {
|
|
13902
|
-
if (
|
|
14808
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13903
14809
|
},
|
|
13904
14810
|
isServerRequest: false,
|
|
13905
14811
|
replayModeHandler: () => {
|
|
@@ -13913,7 +14819,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13913
14819
|
inputValue,
|
|
13914
14820
|
isPreAppStart: false
|
|
13915
14821
|
}, (spanInfo) => {
|
|
13916
|
-
return self._handleReplayTransaction(inputValue,
|
|
14822
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13917
14823
|
});
|
|
13918
14824
|
}
|
|
13919
14825
|
});
|
|
@@ -13930,7 +14836,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13930
14836
|
inputValue,
|
|
13931
14837
|
isPreAppStart
|
|
13932
14838
|
}, (spanInfo) => {
|
|
13933
|
-
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, connection, arguments,
|
|
14839
|
+
return self._handleRecordTransaction(spanInfo, originalBeginTransaction, connection, arguments, actualCallback);
|
|
13934
14840
|
});
|
|
13935
14841
|
},
|
|
13936
14842
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13942,11 +14848,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13942
14848
|
_patchCommit(connection) {
|
|
13943
14849
|
const self = this;
|
|
13944
14850
|
return (originalCommit) => {
|
|
13945
|
-
return function commit(
|
|
14851
|
+
return function commit(optionsOrCallback, callbackArg) {
|
|
14852
|
+
let actualCallback;
|
|
14853
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14854
|
+
else actualCallback = callbackArg;
|
|
13946
14855
|
const inputValue = { query: "COMMIT" };
|
|
13947
14856
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13948
14857
|
noOpRequestHandler: () => {
|
|
13949
|
-
if (
|
|
14858
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13950
14859
|
},
|
|
13951
14860
|
isServerRequest: false,
|
|
13952
14861
|
replayModeHandler: () => {
|
|
@@ -13960,7 +14869,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13960
14869
|
inputValue,
|
|
13961
14870
|
isPreAppStart: false
|
|
13962
14871
|
}, (spanInfo) => {
|
|
13963
|
-
return self._handleReplayTransaction(inputValue,
|
|
14872
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
13964
14873
|
});
|
|
13965
14874
|
}
|
|
13966
14875
|
});
|
|
@@ -13977,7 +14886,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13977
14886
|
inputValue,
|
|
13978
14887
|
isPreAppStart
|
|
13979
14888
|
}, (spanInfo) => {
|
|
13980
|
-
return self._handleRecordTransaction(spanInfo, originalCommit, connection, arguments,
|
|
14889
|
+
return self._handleRecordTransaction(spanInfo, originalCommit, connection, arguments, actualCallback);
|
|
13981
14890
|
});
|
|
13982
14891
|
},
|
|
13983
14892
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -13989,11 +14898,14 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
13989
14898
|
_patchRollback(connection) {
|
|
13990
14899
|
const self = this;
|
|
13991
14900
|
return (originalRollback) => {
|
|
13992
|
-
return function rollback(
|
|
14901
|
+
return function rollback(optionsOrCallback, callbackArg) {
|
|
14902
|
+
let actualCallback;
|
|
14903
|
+
if (typeof optionsOrCallback === "function") actualCallback = optionsOrCallback;
|
|
14904
|
+
else actualCallback = callbackArg;
|
|
13993
14905
|
const inputValue = { query: "ROLLBACK" };
|
|
13994
14906
|
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
13995
14907
|
noOpRequestHandler: () => {
|
|
13996
|
-
if (
|
|
14908
|
+
if (actualCallback) setImmediate(() => actualCallback(null));
|
|
13997
14909
|
},
|
|
13998
14910
|
isServerRequest: false,
|
|
13999
14911
|
replayModeHandler: () => {
|
|
@@ -14007,7 +14919,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14007
14919
|
inputValue,
|
|
14008
14920
|
isPreAppStart: false
|
|
14009
14921
|
}, (spanInfo) => {
|
|
14010
|
-
return self._handleReplayTransaction(inputValue,
|
|
14922
|
+
return self._handleReplayTransaction(inputValue, actualCallback);
|
|
14011
14923
|
});
|
|
14012
14924
|
}
|
|
14013
14925
|
});
|
|
@@ -14024,7 +14936,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14024
14936
|
inputValue,
|
|
14025
14937
|
isPreAppStart
|
|
14026
14938
|
}, (spanInfo) => {
|
|
14027
|
-
return self._handleRecordTransaction(spanInfo, originalRollback, connection, arguments,
|
|
14939
|
+
return self._handleRecordTransaction(spanInfo, originalRollback, connection, arguments, actualCallback);
|
|
14028
14940
|
});
|
|
14029
14941
|
},
|
|
14030
14942
|
spanKind: import_src$23.SpanKind.CLIENT
|
|
@@ -14057,7 +14969,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14057
14969
|
const argsArray = Array.from(args);
|
|
14058
14970
|
const callbackIndex = argsArray.findIndex((arg) => typeof arg === "function");
|
|
14059
14971
|
if (callbackIndex !== -1) {
|
|
14060
|
-
const originalCallback =
|
|
14972
|
+
const originalCallback = argsArray[callbackIndex];
|
|
14061
14973
|
argsArray[callbackIndex] = function(err) {
|
|
14062
14974
|
if (err) try {
|
|
14063
14975
|
SpanUtils.endSpan(spanInfo.span, {
|
|
@@ -14086,7 +14998,7 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14086
14998
|
callback(null);
|
|
14087
14999
|
});
|
|
14088
15000
|
}
|
|
14089
|
-
_handleRecordPoolGetConnectionInSpan(spanInfo, originalGetConnection, callback,
|
|
15001
|
+
_handleRecordPoolGetConnectionInSpan(spanInfo, originalGetConnection, callback, poolContext) {
|
|
14090
15002
|
const self = this;
|
|
14091
15003
|
if (callback) {
|
|
14092
15004
|
const wrappedCallback = (error, connection) => {
|
|
@@ -14111,11 +15023,11 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14111
15023
|
} });
|
|
14112
15024
|
SpanUtils.endSpan(spanInfo.span, { code: import_src$23.SpanStatusCode.OK });
|
|
14113
15025
|
}
|
|
14114
|
-
return callback(error, connection);
|
|
15026
|
+
return import_src$23.context.bind(spanInfo.context, callback)(error, connection);
|
|
14115
15027
|
};
|
|
14116
|
-
return originalGetConnection.call(
|
|
15028
|
+
return originalGetConnection.call(poolContext, wrappedCallback);
|
|
14117
15029
|
} else try {
|
|
14118
|
-
const result = originalGetConnection.call(
|
|
15030
|
+
const result = originalGetConnection.call(poolContext);
|
|
14119
15031
|
SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
|
|
14120
15032
|
connected: true,
|
|
14121
15033
|
hasConnection: true
|
|
@@ -14130,20 +15042,28 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14130
15042
|
throw error;
|
|
14131
15043
|
}
|
|
14132
15044
|
}
|
|
14133
|
-
_handleNoOpReplayGetConnection(callback) {
|
|
15045
|
+
_handleNoOpReplayGetConnection(pool, callback) {
|
|
14134
15046
|
logger.debug(`[MysqlInstrumentation] Background getConnection detected, returning mock connection`);
|
|
14135
|
-
const mockConnection = new TdMysqlConnectionMock(this, "pool");
|
|
15047
|
+
const mockConnection = new TdMysqlConnectionMock(this, "pool", void 0, pool);
|
|
14136
15048
|
if (callback) {
|
|
14137
|
-
process.nextTick(() =>
|
|
15049
|
+
process.nextTick(() => {
|
|
15050
|
+
pool.emit("connection", mockConnection);
|
|
15051
|
+
pool.emit("acquire", mockConnection);
|
|
15052
|
+
callback(null, mockConnection);
|
|
15053
|
+
});
|
|
14138
15054
|
return;
|
|
14139
15055
|
}
|
|
14140
15056
|
return mockConnection;
|
|
14141
15057
|
}
|
|
14142
|
-
_handleReplayPoolGetConnection(spanInfo, callback) {
|
|
15058
|
+
_handleReplayPoolGetConnection(pool, spanInfo, callback) {
|
|
14143
15059
|
logger.debug(`[MysqlInstrumentation] Replaying MySQL Pool getConnection`);
|
|
14144
|
-
const mockConnection = new TdMysqlConnectionMock(this, "pool", spanInfo);
|
|
15060
|
+
const mockConnection = new TdMysqlConnectionMock(this, "pool", spanInfo, pool);
|
|
14145
15061
|
if (callback) {
|
|
14146
|
-
process.nextTick(() =>
|
|
15062
|
+
process.nextTick(() => {
|
|
15063
|
+
pool.emit("connection", mockConnection);
|
|
15064
|
+
pool.emit("acquire", mockConnection);
|
|
15065
|
+
callback(null, mockConnection);
|
|
15066
|
+
});
|
|
14147
15067
|
return;
|
|
14148
15068
|
}
|
|
14149
15069
|
return mockConnection;
|
|
@@ -14376,6 +15296,122 @@ var MysqlInstrumentation = class extends TdInstrumentationBase {
|
|
|
14376
15296
|
});
|
|
14377
15297
|
return readableStream;
|
|
14378
15298
|
}
|
|
15299
|
+
/**
|
|
15300
|
+
* Get wrapper function for PoolNamespace.query method
|
|
15301
|
+
* This handles queries made via poolCluster.of("pattern").query()
|
|
15302
|
+
*/
|
|
15303
|
+
_getPoolNamespaceQueryPatchFn() {
|
|
15304
|
+
const self = this;
|
|
15305
|
+
return (originalQuery) => {
|
|
15306
|
+
return function query(...args) {
|
|
15307
|
+
const firstArg = args[0];
|
|
15308
|
+
const hasInternalCallback = firstArg && typeof firstArg === "object" && typeof firstArg._callback === "function";
|
|
15309
|
+
if (self.mode === TuskDriftMode.REPLAY) {
|
|
15310
|
+
let sql;
|
|
15311
|
+
let values;
|
|
15312
|
+
let callback;
|
|
15313
|
+
let options = {};
|
|
15314
|
+
if (self.createQuery) try {
|
|
15315
|
+
const queryObj = self.createQuery(...args);
|
|
15316
|
+
sql = queryObj.sql;
|
|
15317
|
+
values = queryObj.values;
|
|
15318
|
+
options = { nestTables: queryObj.nestTables };
|
|
15319
|
+
callback = args.find((arg) => typeof arg === "function");
|
|
15320
|
+
if (!callback && hasInternalCallback) callback = firstArg._callback;
|
|
15321
|
+
} catch (error) {
|
|
15322
|
+
({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
15323
|
+
}
|
|
15324
|
+
else ({sql, values, callback, options} = self._parseQueryArgs(args));
|
|
15325
|
+
const inputValue = {
|
|
15326
|
+
sql,
|
|
15327
|
+
values,
|
|
15328
|
+
options: options.nestTables ? { nestTables: options.nestTables } : void 0
|
|
15329
|
+
};
|
|
15330
|
+
const stackTrace = captureStackTrace(["MysqlInstrumentation"]);
|
|
15331
|
+
return handleReplayMode({
|
|
15332
|
+
noOpRequestHandler: () => {
|
|
15333
|
+
return self.queryMock.handleNoOpReplayQuery({
|
|
15334
|
+
sql,
|
|
15335
|
+
values,
|
|
15336
|
+
callback,
|
|
15337
|
+
options
|
|
15338
|
+
});
|
|
15339
|
+
},
|
|
15340
|
+
isServerRequest: false,
|
|
15341
|
+
replayModeHandler: () => {
|
|
15342
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalQuery.apply(this, args), {
|
|
15343
|
+
name: "mysql.query",
|
|
15344
|
+
kind: import_src$23.SpanKind.CLIENT,
|
|
15345
|
+
submodule: "query",
|
|
15346
|
+
packageType: PackageType.MYSQL,
|
|
15347
|
+
packageName: "mysql",
|
|
15348
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
15349
|
+
inputValue,
|
|
15350
|
+
isPreAppStart: false
|
|
15351
|
+
}, (spanInfo) => {
|
|
15352
|
+
const queryEmitter = self.queryMock.handleReplayQuery({
|
|
15353
|
+
sql,
|
|
15354
|
+
values,
|
|
15355
|
+
callback,
|
|
15356
|
+
options
|
|
15357
|
+
}, inputValue, spanInfo, stackTrace);
|
|
15358
|
+
if (queryEmitter && typeof queryEmitter === "object") queryEmitter.stream = function(streamOptions) {
|
|
15359
|
+
return self._createReplayStreamForQuery(inputValue, spanInfo, stackTrace, queryEmitter, streamOptions);
|
|
15360
|
+
};
|
|
15361
|
+
return queryEmitter;
|
|
15362
|
+
});
|
|
15363
|
+
}
|
|
15364
|
+
});
|
|
15365
|
+
} else if (self.mode === TuskDriftMode.RECORD) return originalQuery.apply(this, args);
|
|
15366
|
+
else return originalQuery.apply(this, args);
|
|
15367
|
+
};
|
|
15368
|
+
};
|
|
15369
|
+
}
|
|
15370
|
+
/**
|
|
15371
|
+
* Get wrapper function for PoolNamespace.getConnection method
|
|
15372
|
+
* This handles connections obtained via poolCluster.of("pattern").getConnection()
|
|
15373
|
+
*/
|
|
15374
|
+
_getPoolNamespaceGetConnectionPatchFn() {
|
|
15375
|
+
const self = this;
|
|
15376
|
+
return (originalGetConnection) => {
|
|
15377
|
+
return function getConnection(callback) {
|
|
15378
|
+
const namespace = this;
|
|
15379
|
+
const inputValue = { clientType: "poolNamespace" };
|
|
15380
|
+
if (self.mode === TuskDriftMode.REPLAY) return handleReplayMode({
|
|
15381
|
+
noOpRequestHandler: () => {
|
|
15382
|
+
const mockConnection = new TdMysqlConnectionMock(self, "pool", void 0, void 0);
|
|
15383
|
+
if (callback) {
|
|
15384
|
+
process.nextTick(() => callback(null, mockConnection));
|
|
15385
|
+
return;
|
|
15386
|
+
}
|
|
15387
|
+
return mockConnection;
|
|
15388
|
+
},
|
|
15389
|
+
isServerRequest: false,
|
|
15390
|
+
replayModeHandler: () => {
|
|
15391
|
+
return SpanUtils.createAndExecuteSpan(self.mode, () => originalGetConnection.apply(namespace, [callback]), {
|
|
15392
|
+
name: `mysql.poolNamespace.getConnection`,
|
|
15393
|
+
kind: import_src$23.SpanKind.CLIENT,
|
|
15394
|
+
submodule: "getConnection",
|
|
15395
|
+
packageName: "mysql",
|
|
15396
|
+
packageType: PackageType.MYSQL,
|
|
15397
|
+
instrumentationName: self.INSTRUMENTATION_NAME,
|
|
15398
|
+
inputValue,
|
|
15399
|
+
isPreAppStart: false
|
|
15400
|
+
}, (spanInfo) => {
|
|
15401
|
+
const mockConnection = new TdMysqlConnectionMock(self, "pool", spanInfo, void 0);
|
|
15402
|
+
if (callback) {
|
|
15403
|
+
process.nextTick(() => callback(null, mockConnection));
|
|
15404
|
+
return;
|
|
15405
|
+
}
|
|
15406
|
+
return mockConnection;
|
|
15407
|
+
});
|
|
15408
|
+
}
|
|
15409
|
+
});
|
|
15410
|
+
else if (self.mode === TuskDriftMode.RECORD) return originalGetConnection.apply(namespace, [callback]);
|
|
15411
|
+
else return originalGetConnection.apply(namespace, [callback]);
|
|
15412
|
+
};
|
|
15413
|
+
};
|
|
15414
|
+
}
|
|
14379
15415
|
_wrap(target, propertyName, wrapper) {
|
|
14380
15416
|
wrap(target, propertyName, wrapper);
|
|
14381
15417
|
}
|
|
@@ -31946,7 +32982,7 @@ var require_src = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/sdk-
|
|
|
31946
32982
|
//#endregion
|
|
31947
32983
|
//#region package.json
|
|
31948
32984
|
var import_src$1 = /* @__PURE__ */ __toESM(require_src(), 1);
|
|
31949
|
-
var version = "0.1.
|
|
32985
|
+
var version = "0.1.19";
|
|
31950
32986
|
|
|
31951
32987
|
//#endregion
|
|
31952
32988
|
//#region src/version.ts
|