Skip to content

Commit

Permalink
feat: added support for mysql2 v3.11.5 (#1467)
Browse files Browse the repository at this point in the history
ref INSTA-20850

Co-authored-by: Arya Mohanan <[email protected]>
  • Loading branch information
instanacd and aryamohanan authored Dec 3, 2024
1 parent e38a15a commit 45414f5
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 15 deletions.
53 changes: 51 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@
"mssql": "^11.0.1",
"mssql-v10": "npm:mssql@^10.0.4",
"mysql": "^2.18.1",
"mysql2": "^3.11.4",
"mysql2": "^3.11.5",
"mysql2-v3114": "npm:[email protected]",
"nan": "^2.22.0",
"nats": "^2.28.2",
"nats-v1": "npm:nats@^1.4.12",
Expand Down
3 changes: 3 additions & 0 deletions packages/collector/test/tracing/database/mysql/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ process.on('SIGTERM', () => {
});

const agentPort = process.env.INSTANA_AGENT_PORT;
if (process.env.MYSQL2_VERSION) {
require('./mockVersion');
}
const instana = require('../../../..')();

const accessFunction = process.env.USE_EXECUTE ? 'execute' : 'query';
Expand Down
13 changes: 13 additions & 0 deletions packages/collector/test/tracing/database/mysql/mockVersion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* (c) Copyright IBM Corp. 2024
*/

'use strict';

const mock = require('mock-require');
const MYSQL2_VERSION = process.env.MYSQL2_VERSION;
const MYSQL2_REQUIRE = process.env.MYSQL2_VERSION === 'latest' ? 'mysql2' : `mysql2-${MYSQL2_VERSION}`;

if (MYSQL2_REQUIRE !== 'mysql2') {
mock('mysql2', MYSQL2_REQUIRE);
}
35 changes: 26 additions & 9 deletions packages/collector/test/tracing/database/mysql/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,39 @@ mochaSuiteFn('tracing/mysql', function () {
globalAgent.setUpCleanUpHooks();
const agentControls = globalAgent.instance;

['mysql', 'mysql-cluster', 'mysql2', 'mysql2/promises'].forEach(driverMode => {
[false, true].forEach(function (useExecute) {
// connection.query or connection.execute
registerSuite.bind(this)(agentControls, driverMode, useExecute);
});
const drivers = ['mysql', 'mysql-cluster', 'mysql2', 'mysql2/promises'];
const mysql2Versions = ['latest', 'v3114'];
const executionModes = [false, true];

drivers.forEach(driverMode => {
if (driverMode === 'mysql2') {
// Handling for 'mysql2' with different versions
mysql2Versions.forEach(version => {
executionModes.forEach(useExecute => {
registerSuite.call(this, agentControls, driverMode, useExecute, version);
});
});
} else {
// Generic handling for other drivers
executionModes.forEach(useExecute => {
registerSuite.call(this, agentControls, driverMode, useExecute);
});
}
});
});

function registerSuite(agentControls, driverMode, useExecute) {
function registerSuite(agentControls, driverMode, useExecute, mysql2Version) {
if ((driverMode === 'mysql' || driverMode === 'mysql-cluster') && useExecute) {
// Not applicable, mysql does not provide an execute function, only the query function whereas mysql2 provides both.
return;
}

describe(`driver mode: ${driverMode}, access function: ${useExecute ? 'execute' : 'query'}`, () => {
describe(`driver mode: ${driverMode} version: ${mysql2Version || 'default'}, access function: ${
useExecute ? 'execute' : 'query'
}`, () => {
const env = {
DRIVER_MODE: driverMode
DRIVER_MODE: driverMode,
MYSQL2_VERSION: mysql2Version
};

if (useExecute) {
Expand All @@ -51,7 +67,8 @@ function registerSuite(agentControls, driverMode, useExecute) {

describe('suppressed', function () {
const env = {
DRIVER_MODE: driverMode
DRIVER_MODE: driverMode,
MYSQL2_VERSION: mysql2Version
};
if (useExecute) {
env.USE_EXECUTE = 'true';
Expand Down
23 changes: 20 additions & 3 deletions packages/core/src/tracing/instrumentation/database/mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,26 @@ function instrumentMysql(mysql) {
}

function instrumentMysql2(mysql) {
instrumentConnection(mysql.Connection.prototype, true);
if (mysql.Pool) {
instrumentPool(mysql.Pool.prototype);
/**
* In mysql2 version 3.11.5 and later, the internal structure of the `Connection` and `Pool` classes was reorganized.
* Methods like `query` and `execute` were moved into the `BaseConnection` class located in `lib/base/connection.js`,
* and similar changes were applied to the `Pool` class. See: https://github.com/sidorares/node-mysql2/pull/3081
*
* Prior to v3.11.5, the `Connection` and `Pool` prototypes were directly used for instrumentation.
*/
const connectionPrototype =
Object.getPrototypeOf(mysql.Connection.prototype)?.constructor?.name === 'BaseConnection'
? Object.getPrototypeOf(mysql.Connection.prototype)
: mysql.Connection.prototype;

const poolPrototype =
mysql.Pool && Object.getPrototypeOf(mysql.Pool.prototype)?.constructor?.name === 'BasePool'
? Object.getPrototypeOf(mysql.Pool.prototype)
: mysql.Pool?.prototype;

instrumentConnection(connectionPrototype, true);
if (poolPrototype) {
instrumentPool(poolPrototype);
}
}

Expand Down

0 comments on commit 45414f5

Please sign in to comment.