From 9557de151327665e1523ea2d503122d95073f1b7 Mon Sep 17 00:00:00 2001 From: Arya Date: Mon, 11 May 2026 16:34:13 +0530 Subject: [PATCH 1/9] test: added mysql adapter --- .../currencies/databases/prisma/app.js | 11 ++++++++++ .../currencies/databases/prisma/modes.json | 1 + .../databases/prisma/package.json.template.v7 | 1 + .../databases/prisma/prisma-mysql.config.js | 19 ++++++++++++++++++ .../20221020125804_init/migration.sql | 6 ++++++ .../migrations-mysql/migration_lock.toml | 3 +++ .../prisma/prisma/schema.prisma.mysql | 17 ++++++++++++++++ .../currencies/databases/prisma/test_base.js | 20 ++++++++++++++++--- .../instrumentation/databases/prisma.js | 1 + 9 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 packages/collector/test/integration/currencies/databases/prisma/prisma-mysql.config.js create mode 100644 packages/collector/test/integration/currencies/databases/prisma/prisma/migrations-mysql/20221020125804_init/migration.sql create mode 100644 packages/collector/test/integration/currencies/databases/prisma/prisma/migrations-mysql/migration_lock.toml create mode 100644 packages/collector/test/integration/currencies/databases/prisma/prisma/schema.prisma.mysql diff --git a/packages/collector/test/integration/currencies/databases/prisma/app.js b/packages/collector/test/integration/currencies/databases/prisma/app.js index f2b5ebbdc4..173a7120d8 100644 --- a/packages/collector/test/integration/currencies/databases/prisma/app.js +++ b/packages/collector/test/integration/currencies/databases/prisma/app.js @@ -46,6 +46,17 @@ try { const { PrismaPg } = require('@prisma/adapter-pg'); adapter = new PrismaPg({ connectionString: process.env.INSTANA_CONNECT_POSTGRES_PRISMA_URL }); log(`Initialized Prisma ${version} with PostgreSQL adapter`); + } else if (provider === 'mysql') { + const { PrismaMariaDb } = require('@prisma/adapter-mariadb'); + adapter = new PrismaMariaDb({ + host: process.env.INSTANA_CONNECT_MYSQL_HOST, + port: Number(process.env.INSTANA_CONNECT_MYSQL_PORT), + user: process.env.INSTANA_CONNECT_MYSQL_USER, + password: process.env.INSTANA_CONNECT_MYSQL_PW, + database: process.env.INSTANA_CONNECT_MYSQL_DB, + connectionLimit: 5 + }); + log(`Initialized Prisma ${version} with MariaDB adapter`); } else { const { PrismaBetterSqlite3 } = require('@prisma/adapter-better-sqlite3'); const dbPath = path.join(__dirname, 'dev.db'); diff --git a/packages/collector/test/integration/currencies/databases/prisma/modes.json b/packages/collector/test/integration/currencies/databases/prisma/modes.json index 5a2c99745d..e791113251 100644 --- a/packages/collector/test/integration/currencies/databases/prisma/modes.json +++ b/packages/collector/test/integration/currencies/databases/prisma/modes.json @@ -1,4 +1,5 @@ [ "sqlite", + "mysql", "postgresql" ] \ No newline at end of file diff --git a/packages/collector/test/integration/currencies/databases/prisma/package.json.template.v7 b/packages/collector/test/integration/currencies/databases/prisma/package.json.template.v7 index c078754374..ca1e4cc49d 100644 --- a/packages/collector/test/integration/currencies/databases/prisma/package.json.template.v7 +++ b/packages/collector/test/integration/currencies/databases/prisma/package.json.template.v7 @@ -2,6 +2,7 @@ "dependencies": { "@prisma/client": "{{CURRENCY_VERSION}}", "@prisma/adapter-pg": "{{CURRENCY_VERSION}}", + "@prisma/adapter-mariadb": "{{CURRENCY_VERSION}}", "@prisma/adapter-better-sqlite3": "{{CURRENCY_VERSION}}" } } \ No newline at end of file diff --git a/packages/collector/test/integration/currencies/databases/prisma/prisma-mysql.config.js b/packages/collector/test/integration/currencies/databases/prisma/prisma-mysql.config.js new file mode 100644 index 0000000000..101eae073d --- /dev/null +++ b/packages/collector/test/integration/currencies/databases/prisma/prisma-mysql.config.js @@ -0,0 +1,19 @@ +/* + * (c) Copyright IBM Corp. 2026 + */ + +'use strict'; + +const { defineConfig } = require('prisma/config'); + +const host = process.env.INSTANA_CONNECT_MYSQL_HOST; +const port = process.env.INSTANA_CONNECT_MYSQL_PORT; +const user = process.env.INSTANA_CONNECT_MYSQL_USER; +const password = process.env.INSTANA_CONNECT_MYSQL_PW; +const database = process.env.INSTANA_CONNECT_MYSQL_DB; + +module.exports = defineConfig({ + datasource: { + url: `mysql://${user}:${password}@${host}:${port}/${database}` + } +}); diff --git a/packages/collector/test/integration/currencies/databases/prisma/prisma/migrations-mysql/20221020125804_init/migration.sql b/packages/collector/test/integration/currencies/databases/prisma/prisma/migrations-mysql/20221020125804_init/migration.sql new file mode 100644 index 0000000000..61d45a06dc --- /dev/null +++ b/packages/collector/test/integration/currencies/databases/prisma/prisma/migrations-mysql/20221020125804_init/migration.sql @@ -0,0 +1,6 @@ +CREATE TABLE `Person` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `name` VARCHAR(191) NULL, + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/packages/collector/test/integration/currencies/databases/prisma/prisma/migrations-mysql/migration_lock.toml b/packages/collector/test/integration/currencies/databases/prisma/prisma/migrations-mysql/migration_lock.toml new file mode 100644 index 0000000000..9bee74de58 --- /dev/null +++ b/packages/collector/test/integration/currencies/databases/prisma/prisma/migrations-mysql/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "mysql" diff --git a/packages/collector/test/integration/currencies/databases/prisma/prisma/schema.prisma.mysql b/packages/collector/test/integration/currencies/databases/prisma/prisma/schema.prisma.mysql new file mode 100644 index 0000000000..8306bde5c9 --- /dev/null +++ b/packages/collector/test/integration/currencies/databases/prisma/prisma/schema.prisma.mysql @@ -0,0 +1,17 @@ +// This is your Prisma schema file, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +generator client { + // prisma-client-js provider will be removed in future releases of Prisma ORM. + provider = "prisma-client-js" +} + +datasource db { + provider = "mysql" +} + +model Person { + id Int @id @default(autoincrement()) + name String? +} + diff --git a/packages/collector/test/integration/currencies/databases/prisma/test_base.js b/packages/collector/test/integration/currencies/databases/prisma/test_base.js index 48062c5195..da521a834a 100644 --- a/packages/collector/test/integration/currencies/databases/prisma/test_base.js +++ b/packages/collector/test/integration/currencies/databases/prisma/test_base.js @@ -198,6 +198,17 @@ module.exports = function (name, version, isLatest, mode) { case 'postgresql': expectedUrl = process.env.INSTANA_CONNECT_POSTGRES_PRISMA_URL.replace('nodepw', '_redacted_'); break; + case 'mysql': { + const { + INSTANA_CONNECT_MYSQL_HOST: host, + INSTANA_CONNECT_MYSQL_PORT: port, + INSTANA_CONNECT_MYSQL_USER: user, + INSTANA_CONNECT_MYSQL_DB: database + } = process.env; + + expectedUrl = `mysql://${user}:_redacted_@${host}:${port}/${database}`; + break; + } default: throw new Error(`Unknown provider: ${provider}`); } @@ -212,13 +223,16 @@ module.exports = function (name, version, isLatest, mode) { span => expect(span.data.prisma.action).to.equal(action), span => // URL is unavailable between Prisma 4.10 and 5.1 (getConfig removed) - // In v7, SQLite adapter doesn't expose the URL - !(urlUnavailable || (provider === 'sqlite' && isV7)) + // In v7, SQLite and Mariadb adapters don't expose the URL + !(urlUnavailable || ((provider === 'sqlite' || provider === 'mysql') && isV7)) ? expect(span.data.prisma.url).to.equal(expectedUrl) : expect(span.data.prisma.url).to.equal(''), span => { - if (provider !== 'sqlite' && !urlUnavailable) { + if (provider !== 'sqlite' && provider !== 'mysql' && !urlUnavailable) { expect(span.data.prisma.url).to.contain('_redacted_'); + } else if ((provider === 'mysql' || provider === 'sqlite') && isV7) { + // MySQL/Mariadb and SQLite adapters in v7 don't expose URL + expect(span.data.prisma.url).to.equal(''); } }, span => expect(span.data.prisma.provider).to.equal(provider), diff --git a/packages/core/src/tracing/instrumentation/databases/prisma.js b/packages/core/src/tracing/instrumentation/databases/prisma.js index e621c0b53a..2d4213b6e0 100644 --- a/packages/core/src/tracing/instrumentation/databases/prisma.js +++ b/packages/core/src/tracing/instrumentation/databases/prisma.js @@ -91,6 +91,7 @@ function instrumentClientConstructor(prismaClientModule) { } else if (adapter?.externalPool?.options?.connectionString) { dataSourceUrl = redactPassword(provider, adapter.externalPool.options.connectionString); } + // Note: MariaDB adapter doesn't expose connection details due to private fields } catch (err) { logger.debug('[Instana] Cannot extract URL from Prisma adapter config:', err); } From 7b43b42fc0069fea27585f588c59dfe189a581d6 Mon Sep 17 00:00:00 2001 From: Arya Date: Tue, 12 May 2026 13:41:07 +0530 Subject: [PATCH 2/9] chore: updated --- .../collector-27-postgres-task.yaml | 33 +++++++++++++++++-- .../currencies/databases/prisma/app.mjs | 16 +++++++++ .../currencies/databases/prisma/test_base.js | 7 +++- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/.tekton/tasks/test-groups/collector-27-postgres-task.yaml b/.tekton/tasks/test-groups/collector-27-postgres-task.yaml index abd686caa0..7ac172e204 100644 --- a/.tekton/tasks/test-groups/collector-27-postgres-task.yaml +++ b/.tekton/tasks/test-groups/collector-27-postgres-task.yaml @@ -27,6 +27,35 @@ spec: initialDelaySeconds: 3 periodSeconds: 2 timeoutSeconds: 10 + - name: mysql + image: public.ecr.aws/docker/library/mysql:8.0.26 + imagePullPolicy: IfNotPresent + resources: + requests: + cpu: "500m" + memory: "1Gi" + args: + - "--default-authentication-plugin=mysql_native_password" + env: + - name: "MYSQL_ROOT_PASSWORD" + value: "nodepw" + - name: "MYSQL_DATABASE" + value: "nodedb" + - name: "MYSQL_USER" + value: "node" + - name: "MYSQL_PASSWORD" + value: "nodepw" + - name: "MYSQL_ROOT_HOST" + value: "0.0.0.0" + readinessProbe: + exec: + command: + - "sh" + - "-c" + - "mysql -h 0.0.0.0 -u node -p'nodepw' -e 'SELECT 1'" + initialDelaySeconds: 3 + periodSeconds: 2 + timeoutSeconds: 10 envFrom: - configMapRef: name: environment-properties @@ -102,8 +131,8 @@ spec: memory: "8Gi" script: | #!/bin/bash - AVAILABLE_SIDECARS="postgres" - SIDECAR_COUNTS="redis=20,redis-slave=20,redis-sentinel=20,zookeeper=6,kafka=6,kafka-topics=6,postgres=3,elasticsearch=2,mongodb=1,couchbase=1,rabbitmq=1,nats=1,nats-streaming=1,nats-streaming-2=1,mysql=1,localstack=1,memcached=1,oracledb=1" + AVAILABLE_SIDECARS="postgres,mysql" + SIDECAR_COUNTS="redis=20,redis-slave=20,redis-sentinel=20,zookeeper=6,kafka=6,kafka-topics=6,postgres=3,elasticsearch=2,mongodb=1,couchbase=1,rabbitmq=1,nats=1,nats-streaming=1,nats-streaming-2=1,mysql=1,localstack=1,memcached=1,oracledb=1,mariadb=1" ARTIFACTS_PATH="$(workspaces.output.path)" cd $ARTIFACTS_PATH BASE_REVISION=$(git rev-parse origin/main) diff --git a/packages/collector/test/integration/currencies/databases/prisma/app.mjs b/packages/collector/test/integration/currencies/databases/prisma/app.mjs index 516730d605..6e80facbda 100644 --- a/packages/collector/test/integration/currencies/databases/prisma/app.mjs +++ b/packages/collector/test/integration/currencies/databases/prisma/app.mjs @@ -47,6 +47,22 @@ try { const { PrismaPg } = await import('@prisma/adapter-pg'); adapter = new PrismaPg({ connectionString: process.env.INSTANA_CONNECT_POSTGRES_PRISMA_URL }); console.log(`Initialized Prisma ${version} with PostgreSQL adapter`); + } else if (provider === 'mysql') { + const { PrismaMySQL } = await import('@prisma/adapter-mysql'); + const host = process.env.INSTANA_CONNECT_MYSQL_HOST || '127.0.0.1'; + const port = process.env.INSTANA_CONNECT_MYSQL_PORT || '3306'; + const user = process.env.INSTANA_CONNECT_MYSQL_USER || 'node'; + const password = process.env.INSTANA_CONNECT_MYSQL_PW || 'nodepw'; + const database = process.env.INSTANA_CONNECT_MYSQL_DB || 'nodedb'; + adapter = new PrismaMySQL({ + host, + port: parseInt(port, 10), + user, + password, + database + }); + console.log(`Initialized Prisma ${version} with MySQL adapter`); + } } else { const { PrismaBetterSqlite3 } = await import('@prisma/adapter-better-sqlite3'); const __dirname = path.dirname(fileURLToPath(import.meta.url)); diff --git a/packages/collector/test/integration/currencies/databases/prisma/test_base.js b/packages/collector/test/integration/currencies/databases/prisma/test_base.js index da521a834a..df850f4de7 100644 --- a/packages/collector/test/integration/currencies/databases/prisma/test_base.js +++ b/packages/collector/test/integration/currencies/databases/prisma/test_base.js @@ -22,9 +22,14 @@ const migrationsTargetDir = path.join(appDir, 'prisma', 'migrations'); module.exports = function (name, version, isLatest, mode) { this.timeout(Math.max(config.getTestTimeout() * 3, 20000)); - const provider = mode; // mode is either 'sqlite' or 'postgresql' + const provider = mode; const majorVersion = parseInt(version, 10); const isV7 = majorVersion >= 7; + + if (provider === 'mysql' && !isV7) { + return; + } + // Getting the URL is not possible between Prisma 4.10 and 5.1 (getConfig was removed) const urlUnavailable = semver.gte(version, '4.10.0') && semver.lt(version, '5.2.0'); From 95b596dde051b88a038aa32695511e738abdf105 Mon Sep 17 00:00:00 2001 From: Arya Date: Tue, 12 May 2026 13:43:46 +0530 Subject: [PATCH 3/9] chore: updated --- .tekton/tasks/test-groups/collector-27-postgres-task.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.tekton/tasks/test-groups/collector-27-postgres-task.yaml b/.tekton/tasks/test-groups/collector-27-postgres-task.yaml index 7ac172e204..5f3b524f2d 100644 --- a/.tekton/tasks/test-groups/collector-27-postgres-task.yaml +++ b/.tekton/tasks/test-groups/collector-27-postgres-task.yaml @@ -132,7 +132,7 @@ spec: script: | #!/bin/bash AVAILABLE_SIDECARS="postgres,mysql" - SIDECAR_COUNTS="redis=20,redis-slave=20,redis-sentinel=20,zookeeper=6,kafka=6,kafka-topics=6,postgres=3,elasticsearch=2,mongodb=1,couchbase=1,rabbitmq=1,nats=1,nats-streaming=1,nats-streaming-2=1,mysql=1,localstack=1,memcached=1,oracledb=1,mariadb=1" + SIDECAR_COUNTS="redis=20,redis-slave=20,redis-sentinel=20,zookeeper=6,kafka=6,kafka-topics=6,postgres=3,elasticsearch=2,mongodb=1,couchbase=1,rabbitmq=1,nats=1,nats-streaming=1,nats-streaming-2=1,mysql=1,localstack=1,memcached=1,oracledb=1" ARTIFACTS_PATH="$(workspaces.output.path)" cd $ARTIFACTS_PATH BASE_REVISION=$(git rev-parse origin/main) From c79c33fef5c1b5b1e470b17dc7b93ff5ba5f5d37 Mon Sep 17 00:00:00 2001 From: Arya Date: Tue, 12 May 2026 14:25:37 +0530 Subject: [PATCH 4/9] chore: updated --- .../currencies/databases/prisma/app.mjs | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/collector/test/integration/currencies/databases/prisma/app.mjs b/packages/collector/test/integration/currencies/databases/prisma/app.mjs index 6e80facbda..9326572961 100644 --- a/packages/collector/test/integration/currencies/databases/prisma/app.mjs +++ b/packages/collector/test/integration/currencies/databases/prisma/app.mjs @@ -48,18 +48,14 @@ try { adapter = new PrismaPg({ connectionString: process.env.INSTANA_CONNECT_POSTGRES_PRISMA_URL }); console.log(`Initialized Prisma ${version} with PostgreSQL adapter`); } else if (provider === 'mysql') { - const { PrismaMySQL } = await import('@prisma/adapter-mysql'); - const host = process.env.INSTANA_CONNECT_MYSQL_HOST || '127.0.0.1'; - const port = process.env.INSTANA_CONNECT_MYSQL_PORT || '3306'; - const user = process.env.INSTANA_CONNECT_MYSQL_USER || 'node'; - const password = process.env.INSTANA_CONNECT_MYSQL_PW || 'nodepw'; - const database = process.env.INSTANA_CONNECT_MYSQL_DB || 'nodedb'; - adapter = new PrismaMySQL({ - host, - port: parseInt(port, 10), - user, - password, - database + const { PrismaMariaDb } = await impor("@prisma/adapter-mariadb") ; + adapter = new PrismaMariaDb({ + host: process.env.INSTANA_CONNECT_MYSQL_HOST, + port: Number(process.env.INSTANA_CONNECT_MYSQL_PORT), + user: process.env.INSTANA_CONNECT_MYSQL_USER, + password: process.env.INSTANA_CONNECT_MYSQL_PW, + database: process.env.INSTANA_CONNECT_MYSQL_DB, + connectionLimit: 5 }); console.log(`Initialized Prisma ${version} with MySQL adapter`); } From 6fac13a4f50f2d4d34560801cfea4c111fea5a6f Mon Sep 17 00:00:00 2001 From: Arya Date: Tue, 12 May 2026 19:32:35 +0530 Subject: [PATCH 5/9] chore: corrected --- .../test/integration/currencies/databases/prisma/app.mjs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/collector/test/integration/currencies/databases/prisma/app.mjs b/packages/collector/test/integration/currencies/databases/prisma/app.mjs index 9326572961..b38af5a144 100644 --- a/packages/collector/test/integration/currencies/databases/prisma/app.mjs +++ b/packages/collector/test/integration/currencies/databases/prisma/app.mjs @@ -48,8 +48,8 @@ try { adapter = new PrismaPg({ connectionString: process.env.INSTANA_CONNECT_POSTGRES_PRISMA_URL }); console.log(`Initialized Prisma ${version} with PostgreSQL adapter`); } else if (provider === 'mysql') { - const { PrismaMariaDb } = await impor("@prisma/adapter-mariadb") ; - adapter = new PrismaMariaDb({ + const { PrismaMariaDb } = await import('@prisma/adapter-mariadb'); + adapter = new PrismaMariaDb({ host: process.env.INSTANA_CONNECT_MYSQL_HOST, port: Number(process.env.INSTANA_CONNECT_MYSQL_PORT), user: process.env.INSTANA_CONNECT_MYSQL_USER, @@ -58,7 +58,6 @@ try { connectionLimit: 5 }); console.log(`Initialized Prisma ${version} with MySQL adapter`); - } } else { const { PrismaBetterSqlite3 } = await import('@prisma/adapter-better-sqlite3'); const __dirname = path.dirname(fileURLToPath(import.meta.url)); From feb72612521201b6ec95f082e064d119fe6d0e19 Mon Sep 17 00:00:00 2001 From: Arya Date: Wed, 13 May 2026 13:41:11 +0530 Subject: [PATCH 6/9] chore: updated --- .../currencies/databases/prisma/test_base.js | 10 ++-- .../instrumentation/databases/prisma.js | 50 ++++++++++++++++++- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/packages/collector/test/integration/currencies/databases/prisma/test_base.js b/packages/collector/test/integration/currencies/databases/prisma/test_base.js index df850f4de7..6736b1797c 100644 --- a/packages/collector/test/integration/currencies/databases/prisma/test_base.js +++ b/packages/collector/test/integration/currencies/databases/prisma/test_base.js @@ -228,15 +228,15 @@ module.exports = function (name, version, isLatest, mode) { span => expect(span.data.prisma.action).to.equal(action), span => // URL is unavailable between Prisma 4.10 and 5.1 (getConfig removed) - // In v7, SQLite and Mariadb adapters don't expose the URL - !(urlUnavailable || ((provider === 'sqlite' || provider === 'mysql') && isV7)) + // In v7, SQLite adapter doesn't expose the URL directly + !(urlUnavailable || (provider === 'sqlite' && isV7)) ? expect(span.data.prisma.url).to.equal(expectedUrl) : expect(span.data.prisma.url).to.equal(''), span => { - if (provider !== 'sqlite' && provider !== 'mysql' && !urlUnavailable) { + if (provider !== 'sqlite' && !urlUnavailable) { expect(span.data.prisma.url).to.contain('_redacted_'); - } else if ((provider === 'mysql' || provider === 'sqlite') && isV7) { - // MySQL/Mariadb and SQLite adapters in v7 don't expose URL + } else if (provider === 'sqlite' && isV7) { + // SQLite adapter in v7 doesn't expose URL expect(span.data.prisma.url).to.equal(''); } }, diff --git a/packages/core/src/tracing/instrumentation/databases/prisma.js b/packages/core/src/tracing/instrumentation/databases/prisma.js index 2d4213b6e0..80036c9fb0 100644 --- a/packages/core/src/tracing/instrumentation/databases/prisma.js +++ b/packages/core/src/tracing/instrumentation/databases/prisma.js @@ -14,12 +14,55 @@ let logger; let isActive = false; const providerAndDataSourceUriMap = new WeakMap(); +const mariadbAdapterConfigMap = new WeakMap(); exports.init = function init(config) { logger = config.logger; + + hook.onModuleLoad('@prisma/adapter-mariadb', instrumentMariaDbAdapter); hook.onModuleLoad('@prisma/client', instrumentPrismaClient); }; +function instrumentMariaDbAdapter(mariadbAdapterModule) { + if (typeof mariadbAdapterModule.PrismaMariaDb === 'function') { + const OriginalPrismaMariaDb = mariadbAdapterModule.PrismaMariaDb; + + class InstanaPrismaMariaDb extends OriginalPrismaMariaDb { + constructor(config) { + super(config); + + if (config && typeof config === 'object') { + const host = config.host || 'localhost'; + const port = config.port || 3306; + const user = config.user || ''; + const database = config.database || ''; + + if (user && database) { + const sanitizedUrl = `mysql://${user}:_redacted_@${host}:${port}/${database}`; + mariadbAdapterConfigMap.set(this, { + provider: 'mysql', + url: sanitizedUrl + }); + } + } + } + } + + Object.getOwnPropertyNames(OriginalPrismaMariaDb).forEach(prop => { + if (prop !== 'length' && prop !== 'name' && prop !== 'prototype') { + try { + InstanaPrismaMariaDb[prop] = OriginalPrismaMariaDb[prop]; + } catch (e) { + // ignore + } + } + }); + return { + PrismaMariaDb: InstanaPrismaMariaDb + }; + } +} + function instrumentPrismaClient(prismaClientModule) { instrumentClientConstructor(prismaClientModule); shimRequest(prismaClientModule); @@ -86,12 +129,15 @@ function instrumentClientConstructor(prismaClientModule) { if (this._engineConfig.adapter) { const adapter = this._engineConfig.adapter; try { - if (adapter?.config?.connectionString) { + // Capture config during adapter construction for MariaDB adapter + const capturedConfig = mariadbAdapterConfigMap.get(adapter); + if (capturedConfig) { + dataSourceUrl = capturedConfig.url; + } else if (adapter?.config?.connectionString) { dataSourceUrl = redactPassword(provider, adapter.config.connectionString); } else if (adapter?.externalPool?.options?.connectionString) { dataSourceUrl = redactPassword(provider, adapter.externalPool.options.connectionString); } - // Note: MariaDB adapter doesn't expose connection details due to private fields } catch (err) { logger.debug('[Instana] Cannot extract URL from Prisma adapter config:', err); } From a34fc0142993d48c564c3d91170ef3a2b09ec959 Mon Sep 17 00:00:00 2001 From: Arya Date: Wed, 13 May 2026 15:10:45 +0530 Subject: [PATCH 7/9] chore: updated --- .../instrumentation/databases/prisma.js | 62 +++++++++---------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/packages/core/src/tracing/instrumentation/databases/prisma.js b/packages/core/src/tracing/instrumentation/databases/prisma.js index 80036c9fb0..8c5519ec9b 100644 --- a/packages/core/src/tracing/instrumentation/databases/prisma.js +++ b/packages/core/src/tracing/instrumentation/databases/prisma.js @@ -24,43 +24,39 @@ exports.init = function init(config) { }; function instrumentMariaDbAdapter(mariadbAdapterModule) { - if (typeof mariadbAdapterModule.PrismaMariaDb === 'function') { - const OriginalPrismaMariaDb = mariadbAdapterModule.PrismaMariaDb; - - class InstanaPrismaMariaDb extends OriginalPrismaMariaDb { - constructor(config) { - super(config); - - if (config && typeof config === 'object') { - const host = config.host || 'localhost'; - const port = config.port || 3306; - const user = config.user || ''; - const database = config.database || ''; - - if (user && database) { - const sanitizedUrl = `mysql://${user}:_redacted_@${host}:${port}/${database}`; - mariadbAdapterConfigMap.set(this, { - provider: 'mysql', - url: sanitizedUrl - }); - } - } + const OriginalPrismaMariaDb = mariadbAdapterModule?.PrismaMariaDb; + + if (typeof OriginalPrismaMariaDb !== 'function') { + return mariadbAdapterModule; + } + + class InstanaPrismaMariaDb extends OriginalPrismaMariaDb { + constructor(config) { + super(config); + + if (!config || typeof config !== 'object') { + return; } - } + const { host = 'localhost', port = 3306, user = '', database = '' } = config; - Object.getOwnPropertyNames(OriginalPrismaMariaDb).forEach(prop => { - if (prop !== 'length' && prop !== 'name' && prop !== 'prototype') { - try { - InstanaPrismaMariaDb[prop] = OriginalPrismaMariaDb[prop]; - } catch (e) { - // ignore - } + if (!user || !database) { + return; } - }); - return { - PrismaMariaDb: InstanaPrismaMariaDb - }; + + const sanitizedUrl = `mysql://${user}:_redacted_@${host}:${port}/${database}`; + + mariadbAdapterConfigMap.set(this, { + // Prisma MariaDB adapter reports mysql as provider + provider: 'mysql', + url: sanitizedUrl + }); + } } + + return { + ...mariadbAdapterModule, + PrismaMariaDb: InstanaPrismaMariaDb + }; } function instrumentPrismaClient(prismaClientModule) { From 6b5226fb097372a591b77244ee69d828e5a159d1 Mon Sep 17 00:00:00 2001 From: Arya Date: Wed, 13 May 2026 15:20:24 +0530 Subject: [PATCH 8/9] chore: updated --- .../integration/currencies/databases/prisma/test_base.js | 5 +---- .../core/src/tracing/instrumentation/databases/prisma.js | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/collector/test/integration/currencies/databases/prisma/test_base.js b/packages/collector/test/integration/currencies/databases/prisma/test_base.js index 6736b1797c..4e4ca41843 100644 --- a/packages/collector/test/integration/currencies/databases/prisma/test_base.js +++ b/packages/collector/test/integration/currencies/databases/prisma/test_base.js @@ -228,16 +228,13 @@ module.exports = function (name, version, isLatest, mode) { span => expect(span.data.prisma.action).to.equal(action), span => // URL is unavailable between Prisma 4.10 and 5.1 (getConfig removed) - // In v7, SQLite adapter doesn't expose the URL directly + // In v7, SQLite adapter doesn't expose the URL !(urlUnavailable || (provider === 'sqlite' && isV7)) ? expect(span.data.prisma.url).to.equal(expectedUrl) : expect(span.data.prisma.url).to.equal(''), span => { if (provider !== 'sqlite' && !urlUnavailable) { expect(span.data.prisma.url).to.contain('_redacted_'); - } else if (provider === 'sqlite' && isV7) { - // SQLite adapter in v7 doesn't expose URL - expect(span.data.prisma.url).to.equal(''); } }, span => expect(span.data.prisma.provider).to.equal(provider), diff --git a/packages/core/src/tracing/instrumentation/databases/prisma.js b/packages/core/src/tracing/instrumentation/databases/prisma.js index 8c5519ec9b..2d836fe5d5 100644 --- a/packages/core/src/tracing/instrumentation/databases/prisma.js +++ b/packages/core/src/tracing/instrumentation/databases/prisma.js @@ -31,9 +31,9 @@ function instrumentMariaDbAdapter(mariadbAdapterModule) { } class InstanaPrismaMariaDb extends OriginalPrismaMariaDb { - constructor(config) { - super(config); - + constructor(...args) { + super(...args); + const [config] = args; if (!config || typeof config !== 'object') { return; } From e21e1d3e6b7ad3da8292c79cdae35a3a8a8ec274 Mon Sep 17 00:00:00 2001 From: Arya Date: Wed, 13 May 2026 15:59:35 +0530 Subject: [PATCH 9/9] chore: comments --- .../src/tracing/instrumentation/databases/prisma.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/core/src/tracing/instrumentation/databases/prisma.js b/packages/core/src/tracing/instrumentation/databases/prisma.js index 2d836fe5d5..8243b16485 100644 --- a/packages/core/src/tracing/instrumentation/databases/prisma.js +++ b/packages/core/src/tracing/instrumentation/databases/prisma.js @@ -13,7 +13,18 @@ const cls = require('../../cls'); let logger; let isActive = false; +// Maps database connection info to Prisma instances for span creation +// Key: engine instance (accessible during span creation via ctx._engine) +// Value: { provider: string, dataSourceUrl: string } const providerAndDataSourceUriMap = new WeakMap(); + +// Temporary storage for MariaDB adapter connection URLs +// Key: adapter instance +// Value: { provider: string, dataSourceUrl: string } +// Why two maps? Adapter config is only accessible during construction, but spans only have access to the engine. +// Flow: 1) Adapter constructor captures URL → mariadbAdapterConfigMap +// 2) PrismaClient constructor transfers URL → providerAndDataSourceUriMap (keyed by engine) +// 3) Span creation retrieves URL using engine instance const mariadbAdapterConfigMap = new WeakMap(); exports.init = function init(config) { @@ -125,7 +136,7 @@ function instrumentClientConstructor(prismaClientModule) { if (this._engineConfig.adapter) { const adapter = this._engineConfig.adapter; try { - // Capture config during adapter construction for MariaDB adapter + // Get URL captured during MariaDB adapter construction const capturedConfig = mariadbAdapterConfigMap.get(adapter); if (capturedConfig) { dataSourceUrl = capturedConfig.url;