diff --git a/package.json b/package.json index bdbf825c..2f25467e 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "compile-all": "./scripts/oneach.sh npm run --if-present compile", "clean": "rm -rf node_modules build", "oneach": "./scripts/oneach.sh", - "lint": "npm run lint:eslint && ls -d packages/* | while read d; do (cd $d; npm run lint); done", + "lint": "npm run lint:eslint && (set -e; ls -d packages/* | while read d; do (cd $d; npm run lint); done)", "lint:eslint": "eslint --ext=js,mjs,cjs scripts examples # requires node >=16.0.0", "lint:fix": "eslint --ext=js,mjs,cjs .eslintrc.js scripts examples --fix && ls -d packages/* | while read d; do (cd $d; npm run lint:fix); done" }, diff --git a/packages/mockotlpserver/lib/waterfall.js b/packages/mockotlpserver/lib/waterfall.js index d75ac15b..3dbf2292 100644 --- a/packages/mockotlpserver/lib/waterfall.js +++ b/packages/mockotlpserver/lib/waterfall.js @@ -77,7 +77,11 @@ function renderSpan(span, prefix = '') { BigInt(span.startTimeUnixNano) - BigInt(lastRenderedSpan.startTimeUnixNano) ) / 1e6; + let sign = startOffset >= 0 ? '+' : '-'; let unit = 'ms'; + + // Use the absolute value to do the proper unit transform + startOffset = Math.abs(startOffset); if (startOffset >= 1000) { startOffset /= 1000; unit = 's'; @@ -95,7 +99,7 @@ function renderSpan(span, prefix = '') { startOffset /= 24; unit = 'd'; } - gutter = `${startOffset >= 0 ? '+' : '-'}${Math.floor(startOffset)}`; + gutter = `${sign}${Math.floor(startOffset)}`; gutter = `${' '.repeat(4 - gutter.length)}${gutter}${unit}`; } else { gutter = ' '.repeat(6); diff --git a/packages/opentelemetry-node/docs/supported-technologies.md b/packages/opentelemetry-node/docs/supported-technologies.md index 38134a7a..b2571279 100644 --- a/packages/opentelemetry-node/docs/supported-technologies.md +++ b/packages/opentelemetry-node/docs/supported-technologies.md @@ -50,6 +50,7 @@ requires: | `@opentelemetry/instrumentation-lru-memoizer` | `lru-memoizer` version range `>=1.3 <3` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/instrumentation-lru-memoizer#readme) | | `@opentelemetry/instrumentation-memcached` | `memcached` version range `>=2.2` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-memcached#readme) | | `@opentelemetry/instrumentation-mongodb` | `mongodb` version range `>=3.3 <7` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-mongodb#readme) | +| `@opentelemetry/instrumentation-mongoose` | `mongoose` version range `>=5.9.7 <9` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/instrumentation-mongoose#readme) | | `@opentelemetry/instrumentation-mysql` | `mysql` version range `>=2.0.0 <3` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/plugins/node/opentelemetry-instrumentation-mysql#readme) | | `@opentelemetry/instrumentation-mysql2` | `mysql2` version range `>=1.4.2 <4` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/plugins/node/opentelemetry-instrumentation-mysql2#readme) | | `@opentelemetry/instrumentation-nestjs-core` | `@nestjs/core` version range `>=4.0.0` | [README](https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-nestjs-core#readme) | diff --git a/packages/opentelemetry-node/lib/instrumentations.js b/packages/opentelemetry-node/lib/instrumentations.js index 56f7729f..2599ab17 100644 --- a/packages/opentelemetry-node/lib/instrumentations.js +++ b/packages/opentelemetry-node/lib/instrumentations.js @@ -43,6 +43,7 @@ * "@opentelemetry/instrumentation-lru-memoizer": import('@opentelemetry/instrumentation').InstrumentationConfig | InstrumentationFactory, * "@opentelemetry/instrumentation-memcached": import('@opentelemetry/instrumentation-memcached').InstrumentationConfig | InstrumentationFactory, * "@opentelemetry/instrumentation-mongodb": import('@opentelemetry/instrumentation-mongodb').MongoDBInstrumentationConfig | InstrumentationFactory, + * "@opentelemetry/instrumentation-mongoose": import('@opentelemetry/instrumentation-mongoose').MongooseInstrumentationConfig | InstrumentationFactory, * "@opentelemetry/instrumentation-mysql": import('@opentelemetry/instrumentation-mysql').MySQLInstrumentation | InstrumentationFactory, * "@opentelemetry/instrumentation-mysql2": import('@opentelemetry/instrumentation-mysql2').MySQL2Instrumentation | InstrumentationFactory, * "@opentelemetry/instrumentation-nestjs-core": import('@opentelemetry/instrumentation').InstrumentationConfig | InstrumentationFactory, @@ -81,6 +82,7 @@ const {KoaInstrumentation} = require('@opentelemetry/instrumentation-koa'); const {LruMemoizerInstrumentation} = require('@opentelemetry/instrumentation-lru-memoizer'); const {MemcachedInstrumentation} = require('@opentelemetry/instrumentation-memcached'); const {MongoDBInstrumentation} = require('@opentelemetry/instrumentation-mongodb'); +const {MongooseInstrumentation} = require('@opentelemetry/instrumentation-mongoose'); const {MySQLInstrumentation} = require('@opentelemetry/instrumentation-mysql'); const {MySQL2Instrumentation} = require('@opentelemetry/instrumentation-mysql2'); const {NestInstrumentation} = require('@opentelemetry/instrumentation-nestjs-core'); @@ -128,6 +130,7 @@ const INSTRUMENTATIONS = { '@opentelemetry/instrumentation-lru-memoizer': (cfg) => new LruMemoizerInstrumentation(cfg), '@opentelemetry/instrumentation-memcached': (cfg) => new MemcachedInstrumentation(cfg), '@opentelemetry/instrumentation-mongodb': (cfg) => new MongoDBInstrumentation(cfg), + '@opentelemetry/instrumentation-mongoose': (cfg) => new MongooseInstrumentation(cfg), '@opentelemetry/instrumentation-mysql': (cfg) => new MySQLInstrumentation(cfg), '@opentelemetry/instrumentation-mysql2': (cfg) => new MySQL2Instrumentation(cfg), '@opentelemetry/instrumentation-nestjs-core': (cfg) => new NestInstrumentation(cfg), diff --git a/packages/opentelemetry-node/package-lock.json b/packages/opentelemetry-node/package-lock.json index df4a7362..3adf8231 100644 --- a/packages/opentelemetry-node/package-lock.json +++ b/packages/opentelemetry-node/package-lock.json @@ -38,6 +38,7 @@ "@opentelemetry/instrumentation-lru-memoizer": "^0.44.0", "@opentelemetry/instrumentation-memcached": "^0.43.0", "@opentelemetry/instrumentation-mongodb": "^0.51.0", + "@opentelemetry/instrumentation-mongoose": "^0.46.0", "@opentelemetry/instrumentation-mysql": "^0.45.0", "@opentelemetry/instrumentation-mysql2": "^0.45.0", "@opentelemetry/instrumentation-nestjs-core": "^0.44.0", @@ -81,6 +82,7 @@ "ioredis": "^5.4.1", "module-details-from-path": "^1.0.3", "mongodb": "^6.9.0", + "mongoose": "^8.9.4", "mysql": "^2.18.1", "mysql2": "^3.11.5", "openai": "^4.76.3", @@ -3000,6 +3002,52 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.46.0.tgz", + "integrity": "sha512-mtVv6UeaaSaWTeZtLo4cx4P5/ING2obSqfWGItIFSunQBrYROfhuVe7wdIrFUs2RH1tn2YYpAJyMaRe/bnTTIQ==", + "dependencies": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/api-logs": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.0.tgz", + "integrity": "sha512-l1aJ30CXeauVYaI+btiynHpw341LthkMTv3omi1VJDX14werY2Wmv9n1yudMsq9HuY0m8PvXEVX4d8zxEb+WRg==", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose/node_modules/@opentelemetry/instrumentation": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.0.tgz", + "integrity": "sha512-qIKp+tSCLqofneUWRc5XHtr9jHIq0N0BJfaJamM9gjEFO8sthV4SDXDGNOSAx16PxkbrQJ5/AxMPAGCXl8W/Hg==", + "dependencies": { + "@opentelemetry/api-logs": "0.57.0", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, "node_modules/@opentelemetry/instrumentation-mysql": { "version": "0.45.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.45.0.tgz", @@ -7202,6 +7250,15 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/kareem": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", @@ -7529,6 +7586,78 @@ "whatwg-url": "^13.0.0" } }, + "node_modules/mongoose": { + "version": "8.9.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.4.tgz", + "integrity": "sha512-DndoI01aV/q40P9DiYDXsYjhj8vZjmmuFwcC3Tro5wFznoE1z6Fe2JgMnbLR6ghglym5ziYizSfAJykp+UPZWg==", + "dev": true, + "dependencies": { + "bson": "^6.10.1", + "kareem": "2.6.3", + "mongodb": "~6.12.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dev": true, + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mquery/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -8615,6 +8744,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "dev": true + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -11703,6 +11838,39 @@ "@opentelemetry/semantic-conventions": "^1.27.0" } }, + "@opentelemetry/instrumentation-mongoose": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.46.0.tgz", + "integrity": "sha512-mtVv6UeaaSaWTeZtLo4cx4P5/ING2obSqfWGItIFSunQBrYROfhuVe7wdIrFUs2RH1tn2YYpAJyMaRe/bnTTIQ==", + "requires": { + "@opentelemetry/core": "^1.8.0", + "@opentelemetry/instrumentation": "^0.57.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "dependencies": { + "@opentelemetry/api-logs": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.0.tgz", + "integrity": "sha512-l1aJ30CXeauVYaI+btiynHpw341LthkMTv3omi1VJDX14werY2Wmv9n1yudMsq9HuY0m8PvXEVX4d8zxEb+WRg==", + "requires": { + "@opentelemetry/api": "^1.3.0" + } + }, + "@opentelemetry/instrumentation": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.0.tgz", + "integrity": "sha512-qIKp+tSCLqofneUWRc5XHtr9jHIq0N0BJfaJamM9gjEFO8sthV4SDXDGNOSAx16PxkbrQJ5/AxMPAGCXl8W/Hg==", + "requires": { + "@opentelemetry/api-logs": "0.57.0", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + } + } + } + }, "@opentelemetry/instrumentation-mysql": { "version": "0.45.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.45.0.tgz", @@ -14838,6 +15006,12 @@ "safe-buffer": "^5.0.1" } }, + "kareem": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "dev": true + }, "kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", @@ -15078,6 +15252,61 @@ "whatwg-url": "^13.0.0" } }, + "mongoose": { + "version": "8.9.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.4.tgz", + "integrity": "sha512-DndoI01aV/q40P9DiYDXsYjhj8vZjmmuFwcC3Tro5wFznoE1z6Fe2JgMnbLR6ghglym5ziYizSfAJykp+UPZWg==", + "dev": true, + "requires": { + "bson": "^6.10.1", + "kareem": "2.6.3", + "mongodb": "~6.12.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "dev": true + }, + "mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dev": true, + "requires": { + "debug": "4.x" + }, + "dependencies": { + "debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -15900,6 +16129,12 @@ "object-inspect": "^1.13.1" } }, + "sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "dev": true + }, "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", diff --git a/packages/opentelemetry-node/package.json b/packages/opentelemetry-node/package.json index 76ff25ac..16855137 100644 --- a/packages/opentelemetry-node/package.json +++ b/packages/opentelemetry-node/package.json @@ -96,6 +96,7 @@ "@opentelemetry/instrumentation-lru-memoizer": "^0.44.0", "@opentelemetry/instrumentation-memcached": "^0.43.0", "@opentelemetry/instrumentation-mongodb": "^0.51.0", + "@opentelemetry/instrumentation-mongoose": "^0.46.0", "@opentelemetry/instrumentation-mysql": "^0.45.0", "@opentelemetry/instrumentation-mysql2": "^0.45.0", "@opentelemetry/instrumentation-nestjs-core": "^0.44.0", @@ -139,6 +140,7 @@ "ioredis": "^5.4.1", "module-details-from-path": "^1.0.3", "mongodb": "^6.9.0", + "mongoose": "^8.9.4", "mysql": "^2.18.1", "mysql2": "^3.11.5", "openai": "^4.76.3", diff --git a/packages/opentelemetry-node/test/fixtures/use-mongoose.js b/packages/opentelemetry-node/test/fixtures/use-mongoose.js new file mode 100644 index 00000000..83342219 --- /dev/null +++ b/packages/opentelemetry-node/test/fixtures/use-mongoose.js @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// Usage: node -r @elastic/opentelemetry-node use-mongoose.js + +const otel = require('@opentelemetry/api'); +const {Schema, connect, model} = require('mongoose'); + +const host = process.env.MONGODB_HOST; +const port = process.env.MONGODB_PORT || '27017'; + +async function main() { + const User = model( + 'User', + new Schema({ + email: {type: String, required: true, unique: true}, + name: {type: String, required: true}, + age: {type: Number, required: false}, + }) + ); + + const user = new User({ + email: 'john.doe@example.com', + name: 'John Doe', + age: 18, + }); + + const connection = await connect(`mongodb://${host}:${port}`, { + dbName: 'edot_test', + }); + + await user.save(); + console.log('user saved', user.toJSON()); + await User.collection.drop(); + await connection.disconnect(); +} + +const tracer = otel.trace.getTracer('test'); +tracer.startActiveSpan('manual-parent-span', async (span) => { + await main(); + span.end(); +}); diff --git a/packages/opentelemetry-node/test/instr-mongoose.test.js b/packages/opentelemetry-node/test/instr-mongoose.test.js new file mode 100644 index 00000000..c4ae061f --- /dev/null +++ b/packages/opentelemetry-node/test/instr-mongoose.test.js @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// Test that 'mongoose' instrumentation generates the telemetry we expect. + +const test = require('tape'); +const {filterOutDnsNetSpans, runTestFixtures} = require('./testutils'); + +let skip = process.env.MONGODB_HOST === undefined; +if (skip) { + console.log( + '# SKIP mongodb tests: MONGODB_HOST is not set (try with `MONGODB_HOST=localhost`)' + ); +} + +/** @type {import('./testutils').TestFixture[]} */ +const testFixtures = [ + { + name: 'use-mongoose', + args: ['./fixtures/use-mongoose.js'], + cwd: __dirname, + env: { + NODE_OPTIONS: '--require=@elastic/opentelemetry-node', + }, + versionRanges: { + // Since `mongoose` has a dependency on `mongodb` we will keep the same version ranges for testing + // Ref: https://github.com/mongodb/node-mongodb-native/blob/a8370367f7470962a834ddf36f9a6c62621d6345/package.json#L118 + node: '>=16.20.1', + }, + // verbose: true, + checkTelemetry: (t, col) => { + // We expect spans like this + // ------ trace 5527d1 (13 spans) ------ + // span 58cce4 "manual-parent-span" (39.0ms, SPAN_KIND_INTERNAL) + // +2ms `- span 82ec54 "mongodb.create" (7.6ms, SPAN_KIND_CLIENT) + // +9ms `- span bda449 "mongodb.createIndexes" (3.9ms, SPAN_KIND_CLIENT) + // -8ms `- span a92f92 "mongodb.insert" (12.1ms, SPAN_KIND_CLIENT) + // +13ms `- span 5be842 "mongodb.drop" (0.8ms, SPAN_KIND_CLIENT) + // +1ms `- span 13d56b "mongodb.endSessions" (0.3ms, SPAN_KIND_CLIENT) + // -20ms `- span c4e688 "mongoose.User.save" (18.9ms, SPAN_KIND_CLIENT) + const spans = filterOutDnsNetSpans(col.sortedSpans); + t.equal(spans.length, 7); + + t.equal(spans[0].name, 'manual-parent-span'); + t.equal(spans[0].kind, 'SPAN_KIND_INTERNAL'); + + const mongooseSpans = spans.filter( + (s) => + s.scope.name === '@opentelemetry/instrumentation-mongoose' + ); + t.equal(mongooseSpans.length, 1); + + t.equal(mongooseSpans[0].name, 'mongoose.User.save'); + t.equal(mongooseSpans[0].kind, 'SPAN_KIND_CLIENT'); + t.equal(mongooseSpans[0].parentSpanId, spans[0].spanId); + }, + }, +]; + +test('mongoose instrumentation', {skip}, (suite) => { + runTestFixtures(suite, testFixtures); + suite.end(); +}); diff --git a/packages/opentelemetry-node/types/instrumentations.d.ts b/packages/opentelemetry-node/types/instrumentations.d.ts index 36522fd2..19d3015a 100644 --- a/packages/opentelemetry-node/types/instrumentations.d.ts +++ b/packages/opentelemetry-node/types/instrumentations.d.ts @@ -20,6 +20,7 @@ export type InstrumentaionsMap = { "@opentelemetry/instrumentation-lru-memoizer": import('@opentelemetry/instrumentation').InstrumentationConfig | InstrumentationFactory; "@opentelemetry/instrumentation-memcached": import('@opentelemetry/instrumentation-memcached').InstrumentationConfig | InstrumentationFactory; "@opentelemetry/instrumentation-mongodb": import('@opentelemetry/instrumentation-mongodb').MongoDBInstrumentationConfig | InstrumentationFactory; + "@opentelemetry/instrumentation-mongoose": import('@opentelemetry/instrumentation-mongoose').MongooseInstrumentationConfig | InstrumentationFactory; "@opentelemetry/instrumentation-mysql": import('@opentelemetry/instrumentation-mysql').MySQLInstrumentation | InstrumentationFactory; "@opentelemetry/instrumentation-mysql2": import('@opentelemetry/instrumentation-mysql2').MySQL2Instrumentation | InstrumentationFactory; "@opentelemetry/instrumentation-nestjs-core": import('@opentelemetry/instrumentation').InstrumentationConfig | InstrumentationFactory;