From 2eb3cb3257b3d449e914a31d38c19dfff2c787db Mon Sep 17 00:00:00 2001 From: David Luna Date: Tue, 2 Jul 2024 17:11:04 +0200 Subject: [PATCH 1/6] fix(instr-mongodb): fix function patch missing one argument introduced in v6.6.0 --- package-lock.json | 54 ++++++------------- .../package.json | 3 +- .../src/instrumentation.ts | 14 ++--- .../src/internal-types.ts | 13 +++-- 4 files changed, 34 insertions(+), 50 deletions(-) diff --git a/package-lock.json b/package-lock.json index 01ffdcf014..744b3b9d87 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..3f1930001c 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..e968a3b586 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts @@ -176,19 +176,26 @@ export type Document = { [key: string]: any; }; +// https://github.com/mongodb/node-mongodb-native/blob/v6.4.0/src/utils.ts#L281 +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, + 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 From f989b653ab1b75bd85e675e8c2c8bbdb56c20d15 Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 3 Jul 2024 15:08:05 +0200 Subject: [PATCH 2/6] chore(instr-mongodb): update tests related to operations with cursors --- package-lock.json | 4 ++-- .../package.json | 2 +- .../src/internal-types.ts | 4 +++- .../test/mongodb-v5-v6.test.ts | 21 ++++++++++++------- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 744b3b9d87..b6d37ff4b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38962,7 +38962,7 @@ "@types/mocha": "7.0.2", "@types/node": "18.6.5", "mocha": "7.2.0", - "mongodb": "^6.8.0", + "mongodb": "6.8.0", "nyc": "15.1.0", "rimraf": "5.0.5", "test-all-versions": "6.1.0", @@ -52616,7 +52616,7 @@ "@types/mocha": "7.0.2", "@types/node": "18.6.5", "mocha": "7.2.0", - "mongodb": "^6.8.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/package.json b/plugins/node/opentelemetry-instrumentation-mongodb/package.json index 3f1930001c..cc844f7741 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/package.json +++ b/plugins/node/opentelemetry-instrumentation-mongodb/package.json @@ -58,7 +58,7 @@ "@types/mocha": "7.0.2", "@types/node": "18.6.5", "mocha": "7.2.0", - "mongodb": "^6.8.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/internal-types.ts b/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts index e968a3b586..7a281574da 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts @@ -177,7 +177,7 @@ export type Document = { }; // https://github.com/mongodb/node-mongodb-native/blob/v6.4.0/src/utils.ts#L281 -interface MongodbNamespace { +export interface MongodbNamespace { db: string; collection?: string; } @@ -190,6 +190,8 @@ export type V4Connection = { ns: MongodbNamespace, cmd: Document, 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 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..728f5d69e6 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,18 @@ 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 preoperty is not an object but an intance of + // `CursoResponse`. 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 +526,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 ); @@ -533,7 +538,7 @@ describe('MongoDBInstrumentation-Tracing-v5', () => { }); }); - it('should attach response hook data to the resulting span for find function', done => { + it.only('should attach response hook data to the resulting span for find function', done => { const span = trace.getTracer('default').startSpan('findRootSpan'); context.with(trace.setSpan(context.active(), span), () => { collection @@ -544,12 +549,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 { From f36c008e0c0ce9153bf6a9c5962ed6412fac19bf Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 3 Jul 2024 15:28:51 +0200 Subject: [PATCH 3/6] chore(instr-mongodb): fix lint errors --- .../test/mongodb-v5-v6.test.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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 728f5d69e6..5b48e721d8 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 @@ -509,8 +509,13 @@ describe('MongoDBInstrumentation-Tracing-v5', () => { } // from v6.8.0 the cursor preoperty is not an object but an intance of // `CursoResponse`. 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])); + const cursorObj = data.cursor.firstBatch + ? data.cursor + : data.cursor.toObject(); + span.setAttribute( + 'mongodb_first_result', + JSON.stringify(cursorObj.firstBatch[0]) + ); }, }); }); From 8a1b3e8fa0a5048bbdfcabe3b8de62311c4567ae Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 3 Jul 2024 16:44:10 +0200 Subject: [PATCH 4/6] Update plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v5-v6.test.ts Co-authored-by: Marc Pichler --- .../test/mongodb-v5-v6.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5b48e721d8..697c179f90 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 @@ -508,7 +508,7 @@ describe('MongoDBInstrumentation-Tracing-v5', () => { span.setAttribute('mongodb_insert_count', result.data.n); } // from v6.8.0 the cursor preoperty is not an object but an intance of - // `CursoResponse`. We need to use the `toObject` method to be able to inspect the data + // `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(); From 46c91696c7c57c3873e045823adeabae903c8f87 Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 3 Jul 2024 16:44:17 +0200 Subject: [PATCH 5/6] Update plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v5-v6.test.ts Co-authored-by: Marc Pichler --- .../test/mongodb-v5-v6.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 697c179f90..8b420dcc82 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 @@ -507,7 +507,7 @@ describe('MongoDBInstrumentation-Tracing-v5', () => { if (data.n) { span.setAttribute('mongodb_insert_count', result.data.n); } - // from v6.8.0 the cursor preoperty is not an object but an intance of + // 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 From 5c09e1589151206eb52b69c12b10f88e18092ceb Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 3 Jul 2024 16:44:23 +0200 Subject: [PATCH 6/6] Update plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v5-v6.test.ts Co-authored-by: Marc Pichler --- .../test/mongodb-v5-v6.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8b420dcc82..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 @@ -543,7 +543,7 @@ describe('MongoDBInstrumentation-Tracing-v5', () => { }); }); - it.only('should attach response hook data to the resulting span for find function', done => { + it('should attach response hook data to the resulting span for find function', done => { const span = trace.getTracer('default').startSpan('findRootSpan'); context.with(trace.setSpan(context.active(), span), () => { collection