Skip to content

Commit 0e3ed6e

Browse files
committed
Add requestHook, cleanup
1 parent 29ee356 commit 0e3ed6e

File tree

8 files changed

+371
-54
lines changed

8 files changed

+371
-54
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const Sentry = require('@sentry/node');
2+
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
3+
4+
Sentry.init({
5+
dsn: 'https://[email protected]/1337',
6+
release: '1.0',
7+
tracesSampleRate: 1.0,
8+
transport: loggingTransport,
9+
integrations: [
10+
Sentry.postgresJsIntegration({
11+
requestHook: (span, sanitizedSqlQuery, connectionContext) => {
12+
// Add custom attributes to demonstrate requestHook functionality
13+
span.setAttribute('custom.requestHook', 'called');
14+
15+
// Set context information as extras for test validation
16+
Sentry.setExtra('requestHookCalled', {
17+
sanitizedQuery: sanitizedSqlQuery,
18+
database: connectionContext?.database,
19+
host: connectionContext?.host,
20+
port: connectionContext?.port,
21+
});
22+
},
23+
}),
24+
],
25+
});
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import * as Sentry from '@sentry/node';
2+
import { loggingTransport } from '@sentry-internal/node-integration-tests';
3+
4+
Sentry.init({
5+
dsn: 'https://[email protected]/1337',
6+
release: '1.0',
7+
tracesSampleRate: 1.0,
8+
transport: loggingTransport,
9+
integrations: [
10+
Sentry.postgresJsIntegration({
11+
requestHook: (span, sanitizedSqlQuery, connectionContext) => {
12+
// Add custom attributes to demonstrate requestHook functionality
13+
span.setAttribute('custom.requestHook', 'called');
14+
15+
// Set context information as extras for test validation
16+
Sentry.setExtra('requestHookCalled', {
17+
sanitizedQuery: sanitizedSqlQuery,
18+
database: connectionContext?.database,
19+
host: connectionContext?.host,
20+
port: connectionContext?.port,
21+
});
22+
},
23+
}),
24+
],
25+
});
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
2+
const Sentry = require('@sentry/node');
3+
4+
Sentry.init({
5+
dsn: 'https://[email protected]/1337',
6+
release: '1.0',
7+
tracesSampleRate: 1.0,
8+
transport: loggingTransport,
9+
});
10+
11+
// Stop the process from exiting before the transaction is sent
12+
setInterval(() => {}, 1000);
13+
14+
const postgres = require('postgres');
15+
16+
const sql = postgres({ port: 5444, user: 'test', password: 'test', database: 'test_db' });
17+
18+
async function run() {
19+
await Sentry.startSpan(
20+
{
21+
name: 'Test Transaction',
22+
op: 'transaction',
23+
},
24+
async () => {
25+
try {
26+
await sql`
27+
CREATE TABLE "User" ("id" SERIAL NOT NULL,"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" TEXT NOT NULL,"name" TEXT,CONSTRAINT "User_pkey" PRIMARY KEY ("id"));
28+
`;
29+
30+
await sql`
31+
INSERT INTO "User" ("email", "name") VALUES ('Foo', '[email protected]');
32+
`;
33+
34+
await sql`
35+
SELECT * FROM "User" WHERE "email" = '[email protected]';
36+
`;
37+
38+
await sql`
39+
DROP TABLE "User";
40+
`;
41+
} finally {
42+
await sql.end();
43+
}
44+
},
45+
);
46+
}
47+
48+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
49+
run();
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as Sentry from '@sentry/node';
2+
import postgres from 'postgres';
3+
4+
// Stop the process from exiting before the transaction is sent
5+
setInterval(() => {}, 1000);
6+
7+
const sql = postgres({ port: 5444, user: 'test', password: 'test', database: 'test_db' });
8+
9+
async function run() {
10+
await Sentry.startSpan(
11+
{
12+
name: 'Test Transaction',
13+
op: 'transaction',
14+
},
15+
async () => {
16+
try {
17+
await sql`
18+
CREATE TABLE "User" ("id" SERIAL NOT NULL,"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" TEXT NOT NULL,"name" TEXT,CONSTRAINT "User_pkey" PRIMARY KEY ("id"));
19+
`;
20+
21+
await sql`
22+
INSERT INTO "User" ("email", "name") VALUES ('Foo', '[email protected]');
23+
`;
24+
25+
await sql`
26+
SELECT * FROM "User" WHERE "email" = '[email protected]';
27+
`;
28+
29+
await sql`
30+
DROP TABLE "User";
31+
`;
32+
} finally {
33+
await sql.end();
34+
}
35+
},
36+
);
37+
}
38+
39+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
40+
run();

dev-packages/node-integration-tests/suites/tracing/postgresjs/scenario.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,31 @@ async function run() {
3939
SELECT * FROM "User" WHERE "email" = '[email protected]';
4040
`;
4141

42+
// Test parameterized queries
43+
await sql`
44+
SELECT * FROM "User" WHERE "email" = ${'[email protected]'} AND "name" = ${'Foo'};
45+
`;
46+
47+
// Test DELETE operation
48+
await sql`
49+
DELETE FROM "User" WHERE "email" = '[email protected]';
50+
`;
51+
52+
// Test INSERT with RETURNING
53+
await sql`
54+
INSERT INTO "User" ("email", "name") VALUES ('[email protected]', 'Test User') RETURNING *;
55+
`;
56+
57+
// Test cursor-based queries
4258
await sql`SELECT * from generate_series(1,1000) as x `.cursor(10, async rows => {
4359
await Promise.all(rows);
4460
});
4561

62+
// Test multiple rows at once
63+
await sql`
64+
SELECT * FROM "User" LIMIT 10;
65+
`;
66+
4667
await sql`
4768
DROP TABLE "User";
4869
`;

dev-packages/node-integration-tests/suites/tracing/postgresjs/scenario.mjs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,31 @@ async function run() {
3030
SELECT * FROM "User" WHERE "email" = '[email protected]';
3131
`;
3232

33+
// Test parameterized queries
34+
await sql`
35+
SELECT * FROM "User" WHERE "email" = ${'[email protected]'} AND "name" = ${'Foo'};
36+
`;
37+
38+
// Test DELETE operation
39+
await sql`
40+
DELETE FROM "User" WHERE "email" = '[email protected]';
41+
`;
42+
43+
// Test INSERT with RETURNING
44+
await sql`
45+
INSERT INTO "User" ("email", "name") VALUES ('[email protected]', 'Test User') RETURNING *;
46+
`;
47+
48+
// Test cursor-based queries
3349
await sql`SELECT * from generate_series(1,1000) as x `.cursor(10, async rows => {
3450
await Promise.all(rows);
3551
});
3652

53+
// Test multiple rows at once
54+
await sql`
55+
SELECT * FROM "User" LIMIT 10;
56+
`;
57+
3758
await sql`
3859
DROP TABLE "User";
3960
`;

dev-packages/node-integration-tests/suites/tracing/postgresjs/test.ts

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,4 +399,156 @@ describe('postgresjs auto instrumentation', () => {
399399
.start()
400400
.completed();
401401
});
402+
403+
test('should call requestHook when provided (CJS)', { timeout: 60_000 }, async () => {
404+
const EXPECTED_TRANSACTION = {
405+
transaction: 'Test Transaction',
406+
spans: expect.arrayContaining([
407+
expect.objectContaining({
408+
data: expect.objectContaining({
409+
'db.namespace': 'test_db',
410+
'db.system.name': 'postgres',
411+
'db.operation.name': 'CREATE TABLE',
412+
'db.query.text':
413+
'CREATE TABLE "User" ("id" SERIAL NOT NULL,"createdAt" TIMESTAMP(?) NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" TEXT NOT NULL,"name" TEXT,CONSTRAINT "User_pkey" PRIMARY KEY ("id"))',
414+
'custom.requestHook': 'called',
415+
'sentry.op': 'db',
416+
'sentry.origin': 'auto.db.otel.postgresjs',
417+
'server.address': 'localhost',
418+
'server.port': 5444,
419+
}),
420+
description:
421+
'CREATE TABLE "User" ("id" SERIAL NOT NULL,"createdAt" TIMESTAMP(?) NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" TEXT NOT NULL,"name" TEXT,CONSTRAINT "User_pkey" PRIMARY KEY ("id"))',
422+
op: 'db',
423+
status: 'ok',
424+
origin: 'auto.db.otel.postgresjs',
425+
}),
426+
expect.objectContaining({
427+
data: expect.objectContaining({
428+
'db.namespace': 'test_db',
429+
'db.system.name': 'postgres',
430+
'db.operation.name': 'INSERT',
431+
'db.query.text': `INSERT INTO "User" ("email", "name") VALUES ('Foo', '${EXISTING_TEST_EMAIL}')`,
432+
'custom.requestHook': 'called',
433+
'sentry.op': 'db',
434+
'sentry.origin': 'auto.db.otel.postgresjs',
435+
'server.address': 'localhost',
436+
'server.port': 5444,
437+
}),
438+
description: `INSERT INTO "User" ("email", "name") VALUES ('Foo', '${EXISTING_TEST_EMAIL}')`,
439+
op: 'db',
440+
status: 'ok',
441+
origin: 'auto.db.otel.postgresjs',
442+
}),
443+
expect.objectContaining({
444+
data: expect.objectContaining({
445+
'db.namespace': 'test_db',
446+
'db.system.name': 'postgres',
447+
'db.operation.name': 'SELECT',
448+
'db.query.text': `SELECT * FROM "User" WHERE "email" = '${EXISTING_TEST_EMAIL}'`,
449+
'custom.requestHook': 'called',
450+
'sentry.op': 'db',
451+
'sentry.origin': 'auto.db.otel.postgresjs',
452+
'server.address': 'localhost',
453+
'server.port': 5444,
454+
}),
455+
description: `SELECT * FROM "User" WHERE "email" = '${EXISTING_TEST_EMAIL}'`,
456+
op: 'db',
457+
status: 'ok',
458+
origin: 'auto.db.otel.postgresjs',
459+
}),
460+
]),
461+
extra: expect.objectContaining({
462+
requestHookCalled: expect.objectContaining({
463+
database: 'test_db',
464+
host: 'localhost',
465+
port: 5444,
466+
sanitizedQuery: expect.any(String),
467+
}),
468+
}),
469+
};
470+
471+
await createRunner(__dirname, 'scenario-requestHook.js')
472+
.withFlags('--require', `${__dirname}/instrument-requestHook.cjs`)
473+
.withDockerCompose({ workingDirectory: [__dirname], readyMatches: ['port 5432'] })
474+
.expect({ transaction: EXPECTED_TRANSACTION })
475+
.start()
476+
.completed();
477+
});
478+
479+
test('should call requestHook when provided (ESM)', { timeout: 60_000 }, async () => {
480+
const EXPECTED_TRANSACTION = {
481+
transaction: 'Test Transaction',
482+
spans: expect.arrayContaining([
483+
expect.objectContaining({
484+
data: expect.objectContaining({
485+
'db.namespace': 'test_db',
486+
'db.system.name': 'postgres',
487+
'db.operation.name': 'CREATE TABLE',
488+
'db.query.text':
489+
'CREATE TABLE "User" ("id" SERIAL NOT NULL,"createdAt" TIMESTAMP(?) NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" TEXT NOT NULL,"name" TEXT,CONSTRAINT "User_pkey" PRIMARY KEY ("id"))',
490+
'custom.requestHook': 'called',
491+
'sentry.op': 'db',
492+
'sentry.origin': 'auto.db.otel.postgresjs',
493+
'server.address': 'localhost',
494+
'server.port': 5444,
495+
}),
496+
description:
497+
'CREATE TABLE "User" ("id" SERIAL NOT NULL,"createdAt" TIMESTAMP(?) NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" TEXT NOT NULL,"name" TEXT,CONSTRAINT "User_pkey" PRIMARY KEY ("id"))',
498+
op: 'db',
499+
status: 'ok',
500+
origin: 'auto.db.otel.postgresjs',
501+
}),
502+
expect.objectContaining({
503+
data: expect.objectContaining({
504+
'db.namespace': 'test_db',
505+
'db.system.name': 'postgres',
506+
'db.operation.name': 'INSERT',
507+
'db.query.text': `INSERT INTO "User" ("email", "name") VALUES ('Foo', '${EXISTING_TEST_EMAIL}')`,
508+
'custom.requestHook': 'called',
509+
'sentry.op': 'db',
510+
'sentry.origin': 'auto.db.otel.postgresjs',
511+
'server.address': 'localhost',
512+
'server.port': 5444,
513+
}),
514+
description: `INSERT INTO "User" ("email", "name") VALUES ('Foo', '${EXISTING_TEST_EMAIL}')`,
515+
op: 'db',
516+
status: 'ok',
517+
origin: 'auto.db.otel.postgresjs',
518+
}),
519+
expect.objectContaining({
520+
data: expect.objectContaining({
521+
'db.namespace': 'test_db',
522+
'db.system.name': 'postgres',
523+
'db.operation.name': 'SELECT',
524+
'db.query.text': `SELECT * FROM "User" WHERE "email" = '${EXISTING_TEST_EMAIL}'`,
525+
'custom.requestHook': 'called',
526+
'sentry.op': 'db',
527+
'sentry.origin': 'auto.db.otel.postgresjs',
528+
'server.address': 'localhost',
529+
'server.port': 5444,
530+
}),
531+
description: `SELECT * FROM "User" WHERE "email" = '${EXISTING_TEST_EMAIL}'`,
532+
op: 'db',
533+
status: 'ok',
534+
origin: 'auto.db.otel.postgresjs',
535+
}),
536+
]),
537+
extra: expect.objectContaining({
538+
requestHookCalled: expect.objectContaining({
539+
database: 'test_db',
540+
host: 'localhost',
541+
port: 5444,
542+
sanitizedQuery: expect.any(String),
543+
}),
544+
}),
545+
};
546+
547+
await createRunner(__dirname, 'scenario-requestHook.mjs')
548+
.withFlags('--import', `${__dirname}/instrument-requestHook.mjs`)
549+
.withDockerCompose({ workingDirectory: [__dirname], readyMatches: ['port 5432'] })
550+
.expect({ transaction: EXPECTED_TRANSACTION })
551+
.start()
552+
.completed();
553+
});
402554
});

0 commit comments

Comments
 (0)