Skip to content

Commit 5030825

Browse files
authored
fix(pg-instrumentation): capture query values when passed as second argument for prepared statements (#3196)
1 parent e0cf3e7 commit 5030825

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

packages/instrumentation-pg/src/instrumentation.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,12 @@ export class PgInstrumentation extends InstrumentationBase<PgInstrumentationConf
339339
values: Array.isArray(args[1]) ? args[1] : undefined,
340340
}
341341
: firstArgIsQueryObjectWithText
342-
? (arg0 as utils.ObjectWithText)
342+
? {
343+
...(arg0 as any),
344+
values:
345+
(arg0 as any).values ??
346+
(Array.isArray(args[1]) ? args[1] : undefined),
347+
}
343348
: undefined;
344349

345350
const attributes: Attributes = {

packages/instrumentation-pg/test/pg.test.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,59 @@ describe('pg', () => {
581581
});
582582
});
583583
});
584+
585+
it('should record query and values for prepared statements', done => {
586+
const queryConfig = {
587+
name: 'get_pg_tables',
588+
text: 'SELECT * FROM pg_tables WHERE schemaname = $1',
589+
};
590+
const values = ['public'];
591+
592+
const expectedAttributes = {
593+
...DEFAULT_ATTRIBUTES,
594+
[ATTR_DB_STATEMENT]: queryConfig.text,
595+
[AttributeNames.PG_PLAN]: queryConfig.name,
596+
[AttributeNames.PG_VALUES]: values,
597+
};
598+
599+
const events: TimedEvent[] = [];
600+
const span = tracer.startSpan('prepared statement span');
601+
602+
context.with(trace.setSpan(context.active(), span), () => {
603+
const resNoPromise = (client.query as any)(
604+
queryConfig,
605+
values,
606+
(err: Error | null, res: any) => {
607+
assert.strictEqual(err, null);
608+
assert.ok(res);
609+
assert.ok(Array.isArray(res.rows));
610+
611+
const spans = memoryExporter.getFinishedSpans();
612+
const pgSpan = spans[spans.length - 1];
613+
const recordedAttributes = pgSpan.attributes;
614+
615+
assert.strictEqual(
616+
recordedAttributes[ATTR_DB_STATEMENT],
617+
queryConfig.text
618+
);
619+
620+
assert.ok(
621+
!recordedAttributes[ATTR_DB_STATEMENT].includes(values[0]),
622+
'Query text should NOT contain parameter value'
623+
);
624+
625+
assert.deepStrictEqual(
626+
recordedAttributes[AttributeNames.PG_VALUES],
627+
['public']
628+
);
629+
630+
runCallbackTest(span, expectedAttributes, events);
631+
done();
632+
}
633+
);
634+
assert.strictEqual(resNoPromise, undefined);
635+
});
636+
});
584637
});
585638

586639
describe('when specifying a requestHook configuration', () => {

0 commit comments

Comments
 (0)