Skip to content

Commit

Permalink
feat(node): Add generic-pool integration (#13465)
Browse files Browse the repository at this point in the history
Resolves #13308 

Implement genericPool OTL instrumentation in `packages/node`

- [x] If you've added code that should be tested, please add tests.
- [x] Ensure your code lints and the test suite passes (`yarn lint`) &
(`yarn test`).

---------

Signed-off-by: Kaung Zin Hein <[email protected]>
  • Loading branch information
Zen-cronic authored Sep 3, 2024
1 parent ce8579c commit 4774399
Show file tree
Hide file tree
Showing 15 changed files with 166 additions and 1 deletion.
1 change: 1 addition & 0 deletions dev-packages/node-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"cors": "^2.8.5",
"cron": "^3.1.6",
"express": "^4.17.3",
"generic-pool": "^3.9.0",
"graphql": "^16.3.0",
"http-terminator": "^3.2.0",
"ioredis": "^5.4.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
const Sentry = require('@sentry/node');

Sentry.init({
dsn: 'https://[email protected]/1337',
release: '1.0',
tracesSampleRate: 1.0,
transport: loggingTransport,
});

// Stop the process from exiting before the transaction is sent
setInterval(() => {}, 1000);

const mysql = require('mysql');
const genericPool = require('generic-pool');

const factory = {
create: function () {
return mysql.createConnection({
user: 'root',
password: 'docker',
});
},
destroy: function (client) {
client.end(err => {
if (err) {
// eslint-disable-next-line no-console
console.error('Error while disconnecting MySQL:', err);
}
});
},
};

const opts = {
max: 10,
min: 2,
};

const myPool = genericPool.createPool(factory, opts);

async function run() {
await Sentry.startSpan(
{
op: 'transaction',
name: 'Test Transaction',
},
async () => {
try {
const client1 = await myPool.acquire();
const client2 = await myPool.acquire();

client1.query('SELECT NOW()', function () {
myPool.release(client1);
});

client2.query('SELECT 1 + 1 AS solution', function () {
myPool.release(client2);
});
} catch (err) {
// eslint-disable-next-line no-console
console.error('Error while pooling MySQL:', err);
} finally {
await myPool.drain();
await myPool.clear();
}
},
);
}

// eslint-disable-next-line @typescript-eslint/no-floating-promises
run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';

describe('genericPool auto instrumentation', () => {
afterAll(() => {
cleanupChildProcesses();
});

test('should auto-instrument `genericPool` package when calling pool.require()', done => {
const EXPECTED_TRANSACTION = {
transaction: 'Test Transaction',
spans: expect.arrayContaining([
expect.objectContaining({
description: expect.stringMatching(/^generic-pool\.ac?quire/),
origin: 'auto.db.otel.generic-pool',
data: {
'sentry.origin': 'auto.db.otel.generic-pool',
},
status: 'ok',
}),

expect.objectContaining({
description: expect.stringMatching(/^generic-pool\.ac?quire/),
origin: 'auto.db.otel.generic-pool',
data: {
'sentry.origin': 'auto.db.otel.generic-pool',
},
status: 'ok',
}),
]),
};

createRunner(__dirname, 'scenario.js').expect({ transaction: EXPECTED_TRANSACTION }).start(done);
});
});
1 change: 1 addition & 0 deletions packages/astro/src/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export {
fsIntegration,
functionToStringIntegration,
generateInstrumentOnce,
genericPoolIntegration,
getActiveSpan,
getAutoPerformanceIntegrations,
getClient,
Expand Down
1 change: 1 addition & 0 deletions packages/aws-serverless/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export {
setupConnectErrorHandler,
fastifyIntegration,
fsIntegration,
genericPoolIntegration,
graphqlIntegration,
mongoIntegration,
mongooseIntegration,
Expand Down
1 change: 1 addition & 0 deletions packages/bun/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export {
setupKoaErrorHandler,
connectIntegration,
setupConnectErrorHandler,
genericPoolIntegration,
graphqlIntegration,
mongoIntegration,
mongooseIntegration,
Expand Down
1 change: 1 addition & 0 deletions packages/google-cloud-serverless/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export {
connectIntegration,
setupConnectErrorHandler,
fastifyIntegration,
genericPoolIntegration,
graphqlIntegration,
mongoIntegration,
mongooseIntegration,
Expand Down
1 change: 1 addition & 0 deletions packages/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"@opentelemetry/instrumentation-express": "0.41.1",
"@opentelemetry/instrumentation-fastify": "0.38.0",
"@opentelemetry/instrumentation-fs": "0.14.0",
"@opentelemetry/instrumentation-generic-pool": "0.38.0",
"@opentelemetry/instrumentation-graphql": "0.42.0",
"@opentelemetry/instrumentation-hapi": "0.40.0",
"@opentelemetry/instrumentation-http": "0.52.1",
Expand Down
1 change: 1 addition & 0 deletions packages/node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export { hapiIntegration, setupHapiErrorHandler } from './integrations/tracing/h
export { koaIntegration, setupKoaErrorHandler } from './integrations/tracing/koa';
export { connectIntegration, setupConnectErrorHandler } from './integrations/tracing/connect';
export { spotlightIntegration } from './integrations/spotlight';
export { genericPoolIntegration } from './integrations/tracing/genericPool';

export { SentryContextManager } from './otel/contextManager';
export { generateInstrumentOnce } from './otel/instrument';
Expand Down
40 changes: 40 additions & 0 deletions packages/node/src/integrations/tracing/genericPool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { GenericPoolInstrumentation } from '@opentelemetry/instrumentation-generic-pool';
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core';
import type { IntegrationFn } from '@sentry/types';
import { generateInstrumentOnce } from '../../otel/instrument';

const INTEGRATION_NAME = 'GenericPool';

export const instrumentGenericPool = generateInstrumentOnce(INTEGRATION_NAME, () => new GenericPoolInstrumentation({}));

const _genericPoolIntegration = (() => {
return {
name: INTEGRATION_NAME,
setupOnce() {
instrumentGenericPool();
},

setup(client) {
client.on('spanStart', span => {
const spanJSON = spanToJSON(span);

const spanDescription = spanJSON.description;

// typo in emitted span for version <= 0.38.0 of @opentelemetry/instrumentation-generic-pool
const isGenericPoolSpan =
spanDescription === 'generic-pool.aquire' || spanDescription === 'generic-pool.acquire';

if (isGenericPoolSpan) {
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.generic-pool');
}
});
},
};
}) satisfies IntegrationFn;

/**
* GenericPool integration
*
* Capture tracing data for GenericPool.
*/
export const genericPoolIntegration = defineIntegration(_genericPoolIntegration);
3 changes: 3 additions & 0 deletions packages/node/src/integrations/tracing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { instrumentHttp } from '../http';
import { connectIntegration, instrumentConnect } from './connect';
import { expressIntegration, instrumentExpress } from './express';
import { fastifyIntegration, instrumentFastify } from './fastify';
import { genericPoolIntegration, instrumentGenericPool } from './genericPool';
import { graphqlIntegration, instrumentGraphql } from './graphql';
import { hapiIntegration, instrumentHapi } from './hapi';
import { instrumentKoa, koaIntegration } from './koa';
Expand Down Expand Up @@ -37,6 +38,7 @@ export function getAutoPerformanceIntegrations(): Integration[] {
hapiIntegration(),
koaIntegration(),
connectIntegration(),
genericPoolIntegration(),
];
}

Expand All @@ -61,5 +63,6 @@ export function getOpenTelemetryInstrumentationToPreload(): (((options?: any) =>
instrumentHapi,
instrumentGraphql,
instrumentRedis,
instrumentGenericPool,
];
}
1 change: 1 addition & 0 deletions packages/remix/src/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export {
flush,
functionToStringIntegration,
generateInstrumentOnce,
genericPoolIntegration,
getActiveSpan,
getAutoPerformanceIntegrations,
getClient,
Expand Down
1 change: 1 addition & 0 deletions packages/solidstart/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export {
flush,
functionToStringIntegration,
generateInstrumentOnce,
genericPoolIntegration,
getActiveSpan,
getAutoPerformanceIntegrations,
getClient,
Expand Down
1 change: 1 addition & 0 deletions packages/sveltekit/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export {
fastifyIntegration,
flush,
functionToStringIntegration,
genericPoolIntegration,
generateInstrumentOnce,
getActiveSpan,
getAutoPerformanceIntegrations,
Expand Down
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7113,6 +7113,13 @@
"@opentelemetry/core" "^1.8.0"
"@opentelemetry/instrumentation" "^0.52.0"

"@opentelemetry/[email protected]":
version "0.38.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.38.0.tgz#9ea4d82da23541cda613d553bd405b2cbc0da184"
integrity sha512-0/ULi6pIco1fEnDPmmAul8ZoudFL7St0hjgBbWZlZPBCSyslDll1J7DFeEbjiRSSyUd+0tu73ae0DOKVKNd7VA==
dependencies:
"@opentelemetry/instrumentation" "^0.52.0"

"@opentelemetry/[email protected]":
version "0.42.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.42.0.tgz#588a18c39e3b3f655bc09243566172ab0b638d35"
Expand Down Expand Up @@ -19084,7 +19091,7 @@ generate-function@^2.3.1:
dependencies:
is-property "^1.0.2"

[email protected]:
[email protected], generic-pool@^3.9.0:
version "3.9.0"
resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.9.0.tgz#36f4a678e963f4fdb8707eab050823abc4e8f5e4"
integrity sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==
Expand Down

0 comments on commit 4774399

Please sign in to comment.