Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion .tekton/tasks/test-groups/collector-27-postgres-task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -102,7 +131,7 @@ spec:
memory: "8Gi"
script: |
#!/bin/bash
AVAILABLE_SIDECARS="postgres"
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"
ARTIFACTS_PATH="$(workspaces.output.path)"
cd $ARTIFACTS_PATH
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ 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') {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to call the provider mariadb.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I understand the mariadb adapter can also work with mysql, but the adapter is called mariadb lol

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,
password: process.env.INSTANA_CONNECT_MYSQL_PW,
database: process.env.INSTANA_CONNECT_MYSQL_DB,
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));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[
"sqlite",
"mysql",
"postgresql"
]
Original file line number Diff line number Diff line change
Expand Up @@ -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}}"
}
}
Original file line number Diff line number Diff line change
@@ -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}`
}
});
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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"
Original file line number Diff line number Diff line change
@@ -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?
}

Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -198,6 +203,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}`);
}
Expand Down
56 changes: 55 additions & 1 deletion packages/core/src/tracing/instrumentation/databases/prisma.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,63 @@ 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) {
logger = config.logger;

hook.onModuleLoad('@prisma/adapter-mariadb', instrumentMariaDbAdapter);
hook.onModuleLoad('@prisma/client', instrumentPrismaClient);
};

function instrumentMariaDbAdapter(mariadbAdapterModule) {
const OriginalPrismaMariaDb = mariadbAdapterModule?.PrismaMariaDb;

if (typeof OriginalPrismaMariaDb !== 'function') {
return mariadbAdapterModule;
}

class InstanaPrismaMariaDb extends OriginalPrismaMariaDb {
constructor(...args) {
super(...args);
const [config] = args;
if (!config || typeof config !== 'object') {
return;
}
const { host = 'localhost', port = 3306, user = '', database = '' } = config;

if (!user || !database) {
return;
}

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) {
instrumentClientConstructor(prismaClientModule);
shimRequest(prismaClientModule);
Expand Down Expand Up @@ -86,7 +136,11 @@ function instrumentClientConstructor(prismaClientModule) {
if (this._engineConfig.adapter) {
const adapter = this._engineConfig.adapter;
try {
if (adapter?.config?.connectionString) {
// Get URL captured during MariaDB adapter construction
const capturedConfig = mariadbAdapterConfigMap.get(adapter);
Comment thread
aryamohanan marked this conversation as resolved.
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);
Expand Down