Skip to content

Commit

Permalink
feat(instrumentation-mongoose): Support v7 and v8 (#2353)
Browse files Browse the repository at this point in the history
Co-authored-by: Trent Mick <trentm@gmail.com>
  • Loading branch information
onurtemizkan and trentm authored Aug 12, 2024
1 parent 60a99c9 commit 770130a
Show file tree
Hide file tree
Showing 8 changed files with 546 additions and 269 deletions.
32 changes: 16 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 15 additions & 5 deletions plugins/node/instrumentation-mongoose/.tav.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
'mongoose':
# Test all the latest minor versions in the range ">=5.9.7 <7".
versions: "5.9.7 || 5.9.29 || 5.10.19 || 5.11.20 || 5.12.15 || 5.13.21 || 6.0.15 || 6.1.10 || 6.2.11 || 6.3.9 || 6.4.7 || 6.5.5 || 6.6.7 || 6.7.5 || 6.8.4 || 6.9.3 || 6.10.5 || 6.11.6 || ^6.12.3"
commands:
- npm run test
mongoose:
- versions:
include: ">=5.9.7 <7"
mode: latest-minors
commands: npm run test-v5-v6
- versions:
include: ">=7 <8"
mode: latest-minors
node: '>=14.20.1'
commands: npm run test-v7-v8
- versions:
include: ">=8 <9"
mode: latest-minors
node: '>=16.20.1'
commands: npm run test-v7-v8
2 changes: 1 addition & 1 deletion plugins/node/instrumentation-mongoose/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ npm install --save @opentelemetry/instrumentation-mongoose

## Supported Versions

- [`mongoose`](https://www.npmjs.com/package/mongoose) versions `>=5.9.7 <7`
- [`mongoose`](https://www.npmjs.com/package/mongoose) versions `>=5.9.7 <9`

## Usage

Expand Down
6 changes: 4 additions & 2 deletions plugins/node/instrumentation-mongoose/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"repository": "open-telemetry/opentelemetry-js-contrib",
"scripts": {
"docker:start": "docker run -e MONGODB_DB=opentelemetry-tests -e MONGODB_PORT=27017 -e MONGODB_HOST=127.0.0.1 -p 27017:27017 --rm mongo",
"test": "ts-mocha -p tsconfig.json --require '@opentelemetry/contrib-test-utils' 'test/**/*.test.ts'",
"test": "npm run test-v5-v6",
"test-v5-v6": "nyc ts-mocha -p tsconfig.json --require '@opentelemetry/contrib-test-utils' 'test/mongoose-common.test.ts' 'test/**/mongoose-v5-v6.test.ts'",
"test-v7-v8": "nyc ts-mocha -p tsconfig.json --require '@opentelemetry/contrib-test-utils' 'test/mongoose-common.test.ts' 'test/**/mongoose-v7-v8.test.ts'",
"test-all-versions": "tav",
"tdd": "npm run test -- --watch-extensions ts --watch",
"clean": "rimraf build/*",
Expand Down Expand Up @@ -53,7 +55,7 @@
"@types/node": "18.6.5",
"expect": "29.2.0",
"mocha": "7.2.0",
"mongoose": "6.12.3",
"mongoose": "6.13.0",
"nyc": "15.1.0",
"rimraf": "5.0.5",
"test-all-versions": "6.1.0",
Expand Down
69 changes: 58 additions & 11 deletions plugins/node/instrumentation-mongoose/src/mongoose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,56 @@ import {
SEMATTRS_DB_SYSTEM,
} from '@opentelemetry/semantic-conventions';

const contextCaptureFunctions = [
'remove',
const contextCaptureFunctionsCommon = [
'deleteOne',
'deleteMany',
'find',
'findOne',
'estimatedDocumentCount',
'countDocuments',
'count',
'distinct',
'where',
'$where',
'findOneAndUpdate',
'findOneAndDelete',
'findOneAndReplace',
];

const contextCaptureFunctions6 = [
'remove',
'count',
'findOneAndRemove',
...contextCaptureFunctionsCommon,
];
const contextCaptureFunctions7 = [
'count',
'findOneAndRemove',
...contextCaptureFunctionsCommon,
];
const contextCaptureFunctions8 = [...contextCaptureFunctionsCommon];

function getContextCaptureFunctions(
moduleVersion: string | undefined
): string[] {
/* istanbul ignore next */
if (!moduleVersion) {
return contextCaptureFunctionsCommon;
} else if (moduleVersion.startsWith('6.') || moduleVersion.startsWith('5.')) {
return contextCaptureFunctions6;
} else if (moduleVersion.startsWith('7.')) {
return contextCaptureFunctions7;
} else {
return contextCaptureFunctions8;
}
}

function instrumentRemove(moduleVersion: string | undefined): boolean {
return (
(moduleVersion &&
(moduleVersion.startsWith('5.') || moduleVersion.startsWith('6.'))) ||
false
);
}

// when mongoose functions are called, we store the original call context
// and then set it as the parent for the spans created by Query/Aggregate exec()
Expand All @@ -65,7 +98,7 @@ export class MongooseInstrumentation extends InstrumentationBase<MongooseInstrum
protected init(): InstrumentationModuleDefinition {
const module = new InstrumentationNodeModuleDefinition(
'mongoose',
['>=5.9.7 <7'],
['>=5.9.7 <9'],
this.patch.bind(this),
this.unpatch.bind(this)
);
Expand All @@ -87,11 +120,14 @@ export class MongooseInstrumentation extends InstrumentationBase<MongooseInstrum
// so we need to apply the same logic after instrumenting the save function.
moduleExports.Model.prototype.$save = moduleExports.Model.prototype.save;

this._wrap(
moduleExports.Model.prototype,
'remove',
this.patchOnModelMethods('remove', moduleVersion)
);
if (instrumentRemove(moduleVersion)) {
this._wrap(
moduleExports.Model.prototype,
'remove',
this.patchOnModelMethods('remove', moduleVersion)
);
}

this._wrap(
moduleExports.Query.prototype,
'exec',
Expand All @@ -103,6 +139,8 @@ export class MongooseInstrumentation extends InstrumentationBase<MongooseInstrum
this.patchAggregateExec(moduleVersion)
);

const contextCaptureFunctions = getContextCaptureFunctions(moduleVersion);

contextCaptureFunctions.forEach((funcName: string) => {
this._wrap(
moduleExports.Query.prototype,
Expand All @@ -115,11 +153,20 @@ export class MongooseInstrumentation extends InstrumentationBase<MongooseInstrum
return moduleExports;
}

private unpatch(moduleExports: typeof mongoose): void {
private unpatch(
moduleExports: typeof mongoose,
moduleVersion: string | undefined
): void {
const contextCaptureFunctions = getContextCaptureFunctions(moduleVersion);

this._unwrap(moduleExports.Model.prototype, 'save');
// revert the patch for $save which we applied by aliasing it to patched `save`
moduleExports.Model.prototype.$save = moduleExports.Model.prototype.save;
this._unwrap(moduleExports.Model.prototype, 'remove');

if (instrumentRemove(moduleVersion)) {
this._unwrap(moduleExports.Model.prototype, 'remove');
}

this._unwrap(moduleExports.Query.prototype, 'exec');
this._unwrap(moduleExports.Aggregate.prototype, 'exec');

Expand Down
Loading

0 comments on commit 770130a

Please sign in to comment.