Skip to content

Commit 9dc55da

Browse files
david-lunapichlermarc
andauthoredJul 3, 2024··
fix(instr-mongodb): fix function patch missing one argument introduced in v6.8.0 (#2314)
Co-authored-by: Marc Pichler <marc.pichler@dynatrace.com>
1 parent 0c46dfe commit 9dc55da

File tree

5 files changed

+53
-57
lines changed

5 files changed

+53
-57
lines changed
 

‎package-lock.json

+16-38
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎plugins/node/opentelemetry-instrumentation-mongodb/package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,9 @@
5656
"@opentelemetry/sdk-trace-node": "^1.8.0",
5757
"@types/bson": "4.0.5",
5858
"@types/mocha": "7.0.2",
59-
"@types/mongodb": "3.6.20",
6059
"@types/node": "18.6.5",
6160
"mocha": "7.2.0",
62-
"mongodb": "6.5.0",
61+
"mongodb": "6.8.0",
6362
"nyc": "15.1.0",
6463
"rimraf": "5.0.5",
6564
"test-all-versions": "6.1.0",

‎plugins/node/opentelemetry-instrumentation-mongodb/src/instrumentation.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
ServerSession,
4545
MongodbCommandType,
4646
MongoInternalCommand,
47+
MongodbNamespace,
4748
MongoInternalTopology,
4849
WireProtocolInternal,
4950
V4Connection,
@@ -529,7 +530,7 @@ export class MongoDBInstrumentation extends InstrumentationBase {
529530
return (original: V4Connection['commandCallback']) => {
530531
return function patchedV4ServerCommand(
531532
this: any,
532-
ns: any,
533+
ns: MongodbNamespace,
533534
cmd: any,
534535
options: undefined | unknown,
535536
callback: any
@@ -577,16 +578,15 @@ export class MongoDBInstrumentation extends InstrumentationBase {
577578
return (original: V4Connection['commandPromise']) => {
578579
return function patchedV4ServerCommand(
579580
this: any,
580-
ns: any,
581-
cmd: any,
582-
options: undefined | unknown
581+
...args: Parameters<V4Connection['commandPromise']>
583582
) {
583+
const [ns, cmd] = args;
584584
const currentSpan = trace.getSpan(context.active());
585585
const commandType = Object.keys(cmd)[0];
586586
const resultHandler = () => undefined;
587587

588588
if (typeof cmd !== 'object' || cmd.ismaster || cmd.hello) {
589-
return original.call(this, ns, cmd, options);
589+
return original.apply(this, args);
590590
}
591591

592592
let span = undefined;
@@ -610,7 +610,7 @@ export class MongoDBInstrumentation extends InstrumentationBase {
610610
commandType
611611
);
612612

613-
const result = original.call(this, ns, cmd, options);
613+
const result = original.apply(this, args);
614614
result.then(
615615
(res: any) => patchedCallback(null, res),
616616
(err: any) => patchedCallback(err)
@@ -792,7 +792,7 @@ export class MongoDBInstrumentation extends InstrumentationBase {
792792
private _populateV4Attributes(
793793
span: Span,
794794
connectionCtx: any,
795-
ns: any,
795+
ns: MongodbNamespace,
796796
command?: any,
797797
operation?: string
798798
) {

‎plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -176,19 +176,28 @@ export type Document = {
176176
[key: string]: any;
177177
};
178178

179+
// https://github.com/mongodb/node-mongodb-native/blob/v6.4.0/src/utils.ts#L281
180+
export interface MongodbNamespace {
181+
db: string;
182+
collection?: string;
183+
}
184+
179185
export type V4Connection = {
180186
command: Function;
181187
// From version 6.4.0 the method does not expect a callback and returns a promise
182188
// https://github.com/mongodb/node-mongodb-native/blob/v6.4.2/src/cmap/connection.ts
183189
commandPromise(
184-
ns: any,
190+
ns: MongodbNamespace,
185191
cmd: Document,
186-
options: undefined | unknown
192+
options: undefined | unknown,
193+
// From v6.6.0 we have this new param which is a constructor function
194+
// https://github.com/mongodb/node-mongodb-native/blob/v6.6.0/src/cmap/connection.ts#L588
195+
responseType: undefined | unknown
187196
): Promise<any>;
188197
// Earlier versions expect a callback param and return void
189198
// https://github.com/mongodb/node-mongodb-native/blob/v4.2.2/src/cmap/connection.ts
190199
commandCallback(
191-
ns: any,
200+
ns: MongodbNamespace,
192201
cmd: Document,
193202
options: undefined | unknown,
194203
callback: any

‎plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v5-v6.test.ts

+17-7
Original file line numberDiff line numberDiff line change
@@ -499,12 +499,23 @@ describe('MongoDBInstrumentation-Tracing-v5', () => {
499499
});
500500

501501
describe('when specifying a responseHook configuration', () => {
502-
const dataAttributeName = 'mongodb_data';
503502
describe('with a valid function', () => {
504503
beforeEach(() => {
505504
create({
506-
responseHook: (span: Span, result: MongoResponseHookInformation) => {
507-
span.setAttribute(dataAttributeName, JSON.stringify(result.data));
505+
responseHook: (span: Span, result: any) => {
506+
const { data } = result;
507+
if (data.n) {
508+
span.setAttribute('mongodb_insert_count', result.data.n);
509+
}
510+
// from v6.8.0 the cursor property is not an object but an instance of
511+
// `CursorResponse`. We need to use the `toObject` method to be able to inspect the data
512+
const cursorObj = data.cursor.firstBatch
513+
? data.cursor
514+
: data.cursor.toObject();
515+
span.setAttribute(
516+
'mongodb_first_result',
517+
JSON.stringify(cursorObj.firstBatch[0])
518+
);
508519
},
509520
});
510521
});
@@ -520,8 +531,7 @@ describe('MongoDBInstrumentation-Tracing-v5', () => {
520531
const spans = getTestSpans();
521532
const insertSpan = spans[0];
522533
assert.deepStrictEqual(
523-
JSON.parse(insertSpan.attributes[dataAttributeName] as string)
524-
.n,
534+
insertSpan.attributes['mongodb_insert_count'],
525535
results?.insertedCount
526536
);
527537

@@ -544,12 +554,12 @@ describe('MongoDBInstrumentation-Tracing-v5', () => {
544554
const spans = getTestSpans();
545555
const findSpan = spans[0];
546556
const hookAttributeValue = JSON.parse(
547-
findSpan.attributes[dataAttributeName] as string
557+
findSpan.attributes['mongodb_first_result'] as string
548558
);
549559

550560
if (results) {
551561
assert.strictEqual(
552-
hookAttributeValue?.cursor?.firstBatch[0]._id,
562+
hookAttributeValue?._id,
553563
results[0]._id.toString()
554564
);
555565
} else {

0 commit comments

Comments
 (0)
Please sign in to comment.