diff --git a/package-lock.json b/package-lock.json index 01ffdcf014..b6d37ff4b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12988,16 +12988,6 @@ "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", "dev": true }, - "node_modules/@types/mongodb": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", - "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", - "dev": true, - "dependencies": { - "@types/bson": "*", - "@types/node": "*" - } - }, "node_modules/@types/mysql": { "version": "2.15.22", "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.22.tgz", @@ -38970,10 +38960,9 @@ "@opentelemetry/sdk-trace-node": "^1.8.0", "@types/bson": "4.0.5", "@types/mocha": "7.0.2", - "@types/mongodb": "3.6.20", "@types/node": "18.6.5", "mocha": "7.2.0", - "mongodb": "6.5.0", + "mongodb": "6.8.0", "nyc": "15.1.0", "rimraf": "5.0.5", "test-all-versions": "6.1.0", @@ -39011,9 +39000,9 @@ } }, "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/bson": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.4.0.tgz", - "integrity": "sha512-6/gSSEdbkuFlSb+ufj5jUSU4+wo8xQOwm2bDSqwmxiPE17JTpsP63eAwoN8iF8Oy4gJYj+PAL3zdRCTdaw5Y1g==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", + "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", "dev": true, "engines": { "node": ">=16.20.1" @@ -39067,13 +39056,13 @@ } }, "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/mongodb": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", - "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.8.0.tgz", + "integrity": "sha512-HGQ9NWDle5WvwMnrvUxsFYPd3JEbqD3RgABHBQRuoCEND0qzhsd0iH5ypHsf1eJ+sXmvmyKpP+FLOKY8Il7jMw==", "dev": true, "dependencies": { "@mongodb-js/saslprep": "^1.1.5", - "bson": "^6.4.0", + "bson": "^6.7.0", "mongodb-connection-string-url": "^3.0.0" }, "engines": { @@ -52625,10 +52614,9 @@ "@opentelemetry/semantic-conventions": "^1.22.0", "@types/bson": "4.0.5", "@types/mocha": "7.0.2", - "@types/mongodb": "3.6.20", "@types/node": "18.6.5", "mocha": "7.2.0", - "mongodb": "6.5.0", + "mongodb": "6.8.0", "nyc": "15.1.0", "rimraf": "5.0.5", "test-all-versions": "6.1.0", @@ -52657,9 +52645,9 @@ } }, "bson": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.4.0.tgz", - "integrity": "sha512-6/gSSEdbkuFlSb+ufj5jUSU4+wo8xQOwm2bDSqwmxiPE17JTpsP63eAwoN8iF8Oy4gJYj+PAL3zdRCTdaw5Y1g==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", + "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", "dev": true }, "gaxios": { @@ -52701,13 +52689,13 @@ } }, "mongodb": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", - "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.8.0.tgz", + "integrity": "sha512-HGQ9NWDle5WvwMnrvUxsFYPd3JEbqD3RgABHBQRuoCEND0qzhsd0iH5ypHsf1eJ+sXmvmyKpP+FLOKY8Il7jMw==", "dev": true, "requires": { "@mongodb-js/saslprep": "^1.1.5", - "bson": "^6.4.0", + "bson": "^6.7.0", "mongodb-connection-string-url": "^3.0.0" } }, @@ -57163,16 +57151,6 @@ "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", "dev": true }, - "@types/mongodb": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", - "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", - "dev": true, - "requires": { - "@types/bson": "*", - "@types/node": "*" - } - }, "@types/mysql": { "version": "2.15.22", "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.22.tgz", diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/package.json b/plugins/node/opentelemetry-instrumentation-mongodb/package.json index 1621791ec9..cc844f7741 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/package.json +++ b/plugins/node/opentelemetry-instrumentation-mongodb/package.json @@ -56,10 +56,9 @@ "@opentelemetry/sdk-trace-node": "^1.8.0", "@types/bson": "4.0.5", "@types/mocha": "7.0.2", - "@types/mongodb": "3.6.20", "@types/node": "18.6.5", "mocha": "7.2.0", - "mongodb": "6.5.0", + "mongodb": "6.8.0", "nyc": "15.1.0", "rimraf": "5.0.5", "test-all-versions": "6.1.0", diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-mongodb/src/instrumentation.ts index 62086bc6bd..3408f77bb9 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/src/instrumentation.ts @@ -44,6 +44,7 @@ import { ServerSession, MongodbCommandType, MongoInternalCommand, + MongodbNamespace, MongoInternalTopology, WireProtocolInternal, V4Connection, @@ -529,7 +530,7 @@ export class MongoDBInstrumentation extends InstrumentationBase { return (original: V4Connection['commandCallback']) => { return function patchedV4ServerCommand( this: any, - ns: any, + ns: MongodbNamespace, cmd: any, options: undefined | unknown, callback: any @@ -577,16 +578,15 @@ export class MongoDBInstrumentation extends InstrumentationBase { return (original: V4Connection['commandPromise']) => { return function patchedV4ServerCommand( this: any, - ns: any, - cmd: any, - options: undefined | unknown + ...args: Parameters ) { + const [ns, cmd] = args; const currentSpan = trace.getSpan(context.active()); const commandType = Object.keys(cmd)[0]; const resultHandler = () => undefined; if (typeof cmd !== 'object' || cmd.ismaster || cmd.hello) { - return original.call(this, ns, cmd, options); + return original.apply(this, args); } let span = undefined; @@ -610,7 +610,7 @@ export class MongoDBInstrumentation extends InstrumentationBase { commandType ); - const result = original.call(this, ns, cmd, options); + const result = original.apply(this, args); result.then( (res: any) => patchedCallback(null, res), (err: any) => patchedCallback(err) @@ -792,7 +792,7 @@ export class MongoDBInstrumentation extends InstrumentationBase { private _populateV4Attributes( span: Span, connectionCtx: any, - ns: any, + ns: MongodbNamespace, command?: any, operation?: string ) { diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts b/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts index b660ae879c..7a281574da 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts @@ -176,19 +176,28 @@ export type Document = { [key: string]: any; }; +// https://github.com/mongodb/node-mongodb-native/blob/v6.4.0/src/utils.ts#L281 +export interface MongodbNamespace { + db: string; + collection?: string; +} + export type V4Connection = { command: Function; // From version 6.4.0 the method does not expect a callback and returns a promise // https://github.com/mongodb/node-mongodb-native/blob/v6.4.2/src/cmap/connection.ts commandPromise( - ns: any, + ns: MongodbNamespace, cmd: Document, - options: undefined | unknown + options: undefined | unknown, + // From v6.6.0 we have this new param which is a constructor function + // https://github.com/mongodb/node-mongodb-native/blob/v6.6.0/src/cmap/connection.ts#L588 + responseType: undefined | unknown ): Promise; // Earlier versions expect a callback param and return void // https://github.com/mongodb/node-mongodb-native/blob/v4.2.2/src/cmap/connection.ts commandCallback( - ns: any, + ns: MongodbNamespace, cmd: Document, options: undefined | unknown, callback: any diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v5-v6.test.ts b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v5-v6.test.ts index bac9b6d17e..debe84dbdc 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v5-v6.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v5-v6.test.ts @@ -499,12 +499,23 @@ describe('MongoDBInstrumentation-Tracing-v5', () => { }); describe('when specifying a responseHook configuration', () => { - const dataAttributeName = 'mongodb_data'; describe('with a valid function', () => { beforeEach(() => { create({ - responseHook: (span: Span, result: MongoResponseHookInformation) => { - span.setAttribute(dataAttributeName, JSON.stringify(result.data)); + responseHook: (span: Span, result: any) => { + const { data } = result; + if (data.n) { + span.setAttribute('mongodb_insert_count', result.data.n); + } + // from v6.8.0 the cursor property is not an object but an instance of + // `CursorResponse`. We need to use the `toObject` method to be able to inspect the data + const cursorObj = data.cursor.firstBatch + ? data.cursor + : data.cursor.toObject(); + span.setAttribute( + 'mongodb_first_result', + JSON.stringify(cursorObj.firstBatch[0]) + ); }, }); }); @@ -520,8 +531,7 @@ describe('MongoDBInstrumentation-Tracing-v5', () => { const spans = getTestSpans(); const insertSpan = spans[0]; assert.deepStrictEqual( - JSON.parse(insertSpan.attributes[dataAttributeName] as string) - .n, + insertSpan.attributes['mongodb_insert_count'], results?.insertedCount ); @@ -544,12 +554,12 @@ describe('MongoDBInstrumentation-Tracing-v5', () => { const spans = getTestSpans(); const findSpan = spans[0]; const hookAttributeValue = JSON.parse( - findSpan.attributes[dataAttributeName] as string + findSpan.attributes['mongodb_first_result'] as string ); if (results) { assert.strictEqual( - hookAttributeValue?.cursor?.firstBatch[0]._id, + hookAttributeValue?._id, results[0]._id.toString() ); } else {