Skip to content

Commit 2f54673

Browse files
committed
feat: node-postgres tracing integration
1 parent a00b021 commit 2f54673

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { Express } from './express';
2+
export { Postgres } from './postgres';
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { Hub } from '@sentry/hub';
2+
import { EventProcessor, Integration } from '@sentry/types';
3+
import { fill, logger } from '@sentry/utils';
4+
5+
interface PgClient {
6+
prototype: {
7+
query: () => void | Promise<unknown>;
8+
};
9+
}
10+
11+
interface PostgresOptions {
12+
client?: PgClient;
13+
}
14+
15+
/** Tracing integration for node-postgres package */
16+
export class Postgres implements Integration {
17+
/**
18+
* @inheritDoc
19+
*/
20+
public static id: string = 'Postgres';
21+
22+
/**
23+
* @inheritDoc
24+
*/
25+
public name: string = Postgres.id;
26+
27+
private _client?: PgClient;
28+
29+
/**
30+
* @inheritDoc
31+
*/
32+
public constructor(options: PostgresOptions = {}) {
33+
this._client = options.client;
34+
}
35+
36+
/**
37+
* @inheritDoc
38+
*/
39+
public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
40+
if (!this._client) {
41+
logger.error('PostgresIntegration is missing a Postgres.Client constructor');
42+
return;
43+
}
44+
45+
/**
46+
* function (query, callback) => void
47+
* function (query, params, callback) => void
48+
* function (query) => Promise
49+
* function (query, params) => Promise
50+
*/
51+
fill(this._client.prototype, 'query', function(orig: () => void | Promise<unknown>) {
52+
return function(this: unknown, config: unknown, values: unknown, callback: unknown) {
53+
const scope = getCurrentHub().getScope();
54+
const transaction = scope?.getTransaction();
55+
const span = transaction?.startChild({
56+
description: typeof config === 'string' ? config : (config as { text: string }).text,
57+
op: `query`,
58+
});
59+
60+
if (typeof callback === 'function') {
61+
return orig.call(this, config, values, function(err: Error, result: unknown) {
62+
if (span) span.finish();
63+
callback(err, result);
64+
});
65+
}
66+
67+
if (typeof values === 'function') {
68+
return orig.call(this, config, function(err: Error, result: unknown) {
69+
if (span) span.finish();
70+
values(err, result);
71+
});
72+
}
73+
74+
return (orig.call(this, config, values) as Promise<unknown>).then((res: unknown) => {
75+
if (span) span.finish();
76+
return res;
77+
});
78+
};
79+
});
80+
}
81+
}

0 commit comments

Comments
 (0)