Skip to content

Commit bdcc8fc

Browse files
committed
feat: node-mysql tracing integration
1 parent c15967e commit bdcc8fc

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { Express } from './express';
2+
export { Mysql } from './mysql';
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { Hub } from '@sentry/hub';
2+
import { EventProcessor, Integration } from '@sentry/types';
3+
import { dynamicRequire, fill, logger } from '@sentry/utils';
4+
5+
interface MysqlConnection {
6+
end: () => void;
7+
prototype: {
8+
query: () => void;
9+
};
10+
}
11+
12+
/** Tracing integration for node-mysql package */
13+
export class Mysql implements Integration {
14+
/**
15+
* @inheritDoc
16+
*/
17+
public static id: string = 'Mysql';
18+
19+
/**
20+
* @inheritDoc
21+
*/
22+
public name: string = Mysql.id;
23+
24+
/**
25+
* @inheritDoc
26+
*/
27+
public setupOnce(_: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
28+
let connection: MysqlConnection;
29+
30+
try {
31+
const mysqlModule = dynamicRequire(module, 'mysql') as {
32+
createConnection: (options: unknown) => MysqlConnection;
33+
};
34+
const conn = mysqlModule.createConnection({});
35+
connection = (conn.constructor as unknown) as MysqlConnection;
36+
conn.end();
37+
} catch (e) {
38+
logger.error('Mysql Integration was unable to require `mysql` package.');
39+
return;
40+
}
41+
42+
/**
43+
* function (query, callback) => void
44+
* function (query, params, callback) => void
45+
* function (query) => Promise
46+
* function (query, params) => Promise
47+
*/
48+
fill(connection, 'query', function(orig: () => void | Promise<unknown>) {
49+
return function(this: unknown, options: unknown, values: unknown, callback: unknown) {
50+
const scope = getCurrentHub().getScope();
51+
const transaction = scope?.getTransaction();
52+
const span = transaction?.startChild({
53+
description: typeof options === 'string' ? options : (options as { sql: string }).sql,
54+
op: `query`,
55+
});
56+
57+
if (typeof callback === 'function') {
58+
return orig.call(this, options, values, function(err: Error, result: unknown, fields: unknown) {
59+
span?.finish();
60+
callback(err, result, fields);
61+
});
62+
}
63+
64+
if (typeof values === 'function') {
65+
return orig.call(this, options, function(err: Error, result: unknown, fields: unknown) {
66+
span?.finish();
67+
values(err, result, fields);
68+
});
69+
}
70+
71+
return orig.call(this, options, values, callback);
72+
};
73+
});
74+
}
75+
}

0 commit comments

Comments
 (0)