From 20328d4a655b41b7f5546137c90dbdce1cce4e14 Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 27 Mar 2024 01:38:22 +0100 Subject: [PATCH] fix(instr-mongodb): `mongodb` >=v6.4.0 support (#2001) The new version of mongodb `v6.4.0` comes with some internal changes that break the instrumentation. Details of the changes are described in https://github.com/open-telemetry/opentelemetry-js-contrib/issues/1983#issuecomment-1979740812 Closes: #1983 --- .github/workflows/unit-test.yml | 2 +- package-lock.json | 376 ++++++++++-------- .../.tav.yml | 26 +- .../package.json | 4 +- .../src/instrumentation.ts | 157 ++++++-- .../src/internal-types.ts | 22 +- .../test/mongodb-v3.test.ts | 26 +- .../test/mongodb-v4-v5-v6.metrics.test.ts | 24 +- .../test/mongodb-v4.test.ts | 17 +- .../test/mongodb-v5-v6.test.ts | 10 +- .../test/utils.ts | 23 +- 11 files changed, 428 insertions(+), 259 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index af0bd5cdc5..025b727e9b 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -11,7 +11,7 @@ jobs: matrix: node: ["14", "16", "18.18.2"] include: - - node: 14 + - node: 18.18.2 code-coverage: true runs-on: ubuntu-latest services: diff --git a/package-lock.json b/package-lock.json index d15344e958..65bcc6f9f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6784,11 +6784,10 @@ "dev": true }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", - "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz", + "integrity": "sha512-XLNOMH66KhJzUJNwT/qlMnS4WsNDWD5ASdyaSH3EtK+F4r/CFGa3jT4GNi4mfOitGvWXtdLgQJkQjxSVrio+jA==", "dev": true, - "optional": true, "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -23809,8 +23808,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "dev": true, - "optional": true + "dev": true }, "node_modules/meow": { "version": "8.1.2", @@ -27581,18 +27579,6 @@ "node": ">=0.10" } }, - "node_modules/optional-require": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", - "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", - "dev": true, - "dependencies": { - "require-at": "^1.0.6" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -29983,15 +29969,6 @@ "node": ">=0.10" } }, - "node_modules/require-at": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", - "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -30700,19 +30677,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "devOptional": true }, - "node_modules/saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "dev": true, - "optional": true, - "dependencies": { - "sparse-bitfield": "^3.0.3" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", @@ -31619,7 +31583,6 @@ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "dev": true, - "optional": true, "dependencies": { "memory-pager": "^1.0.2" } @@ -38086,7 +38049,7 @@ "@types/mongodb": "3.6.20", "@types/node": "18.6.5", "mocha": "7.2.0", - "mongodb": "3.6.11", + "mongodb": "6.5.0", "nyc": "15.1.0", "rimraf": "5.0.5", "test-all-versions": "6.1.0", @@ -38100,57 +38063,115 @@ "@opentelemetry/api": "^1.3.0" } }, - "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/bl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", - "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/@types/whatwg-url": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", + "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", "dev": true, "dependencies": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "@types/webidl-conversions": "*" + } + }, + "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" } }, "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.4.0.tgz", + "integrity": "sha512-6/gSSEdbkuFlSb+ufj5jUSU4+wo8xQOwm2bDSqwmxiPE17JTpsP63eAwoN8iF8Oy4gJYj+PAL3zdRCTdaw5Y1g==", "dev": true, "engines": { - "node": ">=0.6.19" + "node": ">=16.20.1" } }, - "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/gaxios": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz", + "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==", "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" + }, "engines": { - "node": ">=0.10" + "node": ">=12" + } + }, + "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/gcp-metadata": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", + "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "gaxios": "^5.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" } }, "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/mongodb": { - "version": "3.6.11", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.11.tgz", - "integrity": "sha512-4Y4lTFHDHZZdgMaHmojtNAlqkvddX2QQBEN0K//GzxhGwlI9tZ9R0vhbjr1Decw+TF7qK0ZLjQT292XgHRRQgw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", + "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", "dev": true, "dependencies": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "optional-require": "^1.0.3", - "safe-buffer": "^5.1.2" + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.4.0", + "mongodb-connection-string-url": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=16.20.1" }, - "optionalDependencies": { - "saslprep": "^1.0.0" + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" }, "peerDependenciesMeta": { - "aws4": { + "@aws-sdk/credential-providers": { "optional": true }, - "bson-ext": { + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { "optional": true }, "kerberos": { @@ -38159,42 +38180,47 @@ "mongodb-client-encryption": { "optional": true }, - "mongodb-extjson": { + "snappy": { "optional": true }, - "snappy": { + "socks": { "optional": true } } }, - "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/mongodb-connection-string-url": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", + "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", "dev": true, "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" } }, - "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dev": true, + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } }, - "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "plugins/node/opentelemetry-instrumentation-mongodb/node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", "dev": true, "dependencies": { - "safe-buffer": "~5.1.0" + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" } }, "plugins/node/opentelemetry-instrumentation-mysql": { @@ -44493,11 +44519,10 @@ "dev": true }, "@mongodb-js/saslprep": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", - "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz", + "integrity": "sha512-XLNOMH66KhJzUJNwT/qlMnS4WsNDWD5ASdyaSH3EtK+F4r/CFGa3jT4GNi4mfOitGvWXtdLgQJkQjxSVrio+jA==", "dev": true, - "optional": true, "requires": { "sparse-bitfield": "^3.0.3" } @@ -46573,7 +46598,7 @@ "@types/mongodb": "3.6.20", "@types/node": "18.6.5", "mocha": "7.2.0", - "mongodb": "3.6.11", + "mongodb": "6.5.0", "nyc": "15.1.0", "rimraf": "5.0.5", "test-all-versions": "6.1.0", @@ -46581,70 +46606,108 @@ "typescript": "4.4.4" }, "dependencies": { - "bl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", - "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "@types/whatwg-url": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", + "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", + "dev": true, + "requires": { + "@types/webidl-conversions": "*" + } + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, + "optional": true, + "peer": true, "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" + "debug": "4" } }, "bson": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", - "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.4.0.tgz", + "integrity": "sha512-6/gSSEdbkuFlSb+ufj5jUSU4+wo8xQOwm2bDSqwmxiPE17JTpsP63eAwoN8iF8Oy4gJYj+PAL3zdRCTdaw5Y1g==", "dev": true }, - "denque": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", - "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", - "dev": true + "gaxios": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz", + "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" + } + }, + "gcp-metadata": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", + "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "gaxios": "^5.0.0", + "json-bigint": "^1.0.0" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "agent-base": "6", + "debug": "4" + } }, "mongodb": { - "version": "3.6.11", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.11.tgz", - "integrity": "sha512-4Y4lTFHDHZZdgMaHmojtNAlqkvddX2QQBEN0K//GzxhGwlI9tZ9R0vhbjr1Decw+TF7qK0ZLjQT292XgHRRQgw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", + "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", "dev": true, "requires": { - "bl": "^2.2.1", - "bson": "^1.1.4", - "denque": "^1.4.1", - "optional-require": "^1.0.3", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.4.0", + "mongodb-connection-string-url": "^3.0.0" } }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "mongodb-connection-string-url": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", + "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dev": true, + "requires": { + "punycode": "^2.3.0" + } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" } } } @@ -60025,8 +60088,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "dev": true, - "optional": true + "dev": true }, "meow": { "version": "8.1.2", @@ -63065,15 +63127,6 @@ "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz", "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==" }, - "optional-require": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", - "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", - "dev": true, - "requires": { - "require-at": "^1.0.6" - } - }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -64924,12 +64977,6 @@ "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "dev": true }, - "require-at": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", - "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -65459,16 +65506,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "devOptional": true }, - "saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "dev": true, - "optional": true, - "requires": { - "sparse-bitfield": "^3.0.3" - } - }, "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", @@ -66221,7 +66258,6 @@ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "dev": true, - "optional": true, "requires": { "memory-pager": "^1.0.2" } diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/.tav.yml b/plugins/node/opentelemetry-instrumentation-mongodb/.tav.yml index 403959c458..64af522512 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/.tav.yml +++ b/plugins/node/opentelemetry-instrumentation-mongodb/.tav.yml @@ -1,11 +1,17 @@ mongodb: - jobs: - - versions: ">=3.3 <4" - commands: npm run test-v3 - - versions: ">=4 <5" - commands: npm run test-v4 - - versions: ">=5 <6" - commands: npm run test-v5-v6 - - versions: ">=6 <6.4" - node: '>=15.0.0' - commands: npm run test-v5-v6 + - versions: ">=3.3 <4" + commands: npm run test-v3 + - versions: + include: ">=4 <5" + # This version has been excluded because `mongoose` instrumentation has it + # pined as a transitive dependency. + # When `test-all-versions` tries to install it npm actually does nothing and + # we end up running tests for the wrong version (v6.5.0) + # Ref: https://github.com/open-telemetry/opentelemetry-js-contrib/pull/2001#issuecomment-1992202942 + exclude: "4.17.1" + commands: npm run test-v4 + - versions: ">=5 <6" + commands: npm run test-v5-v6 + - versions: ">=6 <7" + node: '>=15.0.0' + commands: npm run test-v5-v6 diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/package.json b/plugins/node/opentelemetry-instrumentation-mongodb/package.json index c3fb06a8d5..c0ad347f68 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/package.json +++ b/plugins/node/opentelemetry-instrumentation-mongodb/package.json @@ -7,7 +7,7 @@ "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": "npm run test-v3", + "test": "npm run test-v5-v6", "test-v3": "nyc ts-mocha -p tsconfig.json --require '@opentelemetry/contrib-test-utils' 'test/**/mongodb-v3.test.ts'", "test-v4": "nyc ts-mocha -p tsconfig.json --require '@opentelemetry/contrib-test-utils' 'test/mongodb-v4-v5-v6.metrics.test.ts' 'test/**/mongodb-v4.test.ts'", "test-v5-v6": "nyc ts-mocha -p tsconfig.json --require '@opentelemetry/contrib-test-utils' 'test/mongodb-v4-v5-v6.metrics.test.ts' 'test/**/mongodb-v5-v6.test.ts'", @@ -58,7 +58,7 @@ "@types/mongodb": "3.6.20", "@types/node": "18.6.5", "mocha": "7.2.0", - "mongodb": "3.6.11", + "mongodb": "6.5.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 f2c9687c34..0a1dad9af9 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/src/instrumentation.ts @@ -74,8 +74,11 @@ export class MongoDBInstrumentation extends InstrumentationBase { } = this._getV3ConnectionPatches(); const { v4PatchConnect, v4UnpatchConnect } = this._getV4ConnectPatches(); - const { v4PatchConnection, v4UnpatchConnection } = - this._getV4ConnectionPatches(); + const { + v4PatchConnectionCallback, + v4PatchConnectionPromise, + v4UnpatchConnection, + } = this._getV4ConnectionPatches(); const { v4PatchConnectionPool, v4UnpatchConnectionPool } = this._getV4ConnectionPoolPatches(); const { v4PatchSessions, v4UnpatchSessions } = this._getV4SessionsPatches(); @@ -97,14 +100,20 @@ export class MongoDBInstrumentation extends InstrumentationBase { ), new InstrumentationNodeModuleDefinition( 'mongodb', - ['4.*', '5.*', '>=6 <6.4'], + ['4.*', '5.*', '6.*'], undefined, undefined, [ new InstrumentationNodeModuleFile( 'mongodb/lib/cmap/connection.js', ['4.*', '5.*', '>=6 <6.4'], - v4PatchConnection, + v4PatchConnectionCallback, + v4UnpatchConnection + ), + new InstrumentationNodeModuleFile( + 'mongodb/lib/cmap/connection.js', + ['>=6.4'], + v4PatchConnectionPromise, v4UnpatchConnection ), new InstrumentationNodeModuleFile( @@ -115,13 +124,13 @@ export class MongoDBInstrumentation extends InstrumentationBase { ), new InstrumentationNodeModuleFile( 'mongodb/lib/cmap/connect.js', - ['4.*', '5.*', '>=6 <6.4'], + ['4.*', '5.*', '6.*'], v4PatchConnect, v4UnpatchConnect ), new InstrumentationNodeModuleFile( 'mongodb/lib/sessions.js', - ['4.*', '5.*', '>=6 <6.4'], + ['4.*', '5.*', '6.*'], v4PatchSessions, v4UnpatchSessions ), @@ -339,12 +348,32 @@ export class MongoDBInstrumentation extends InstrumentationBase { private _getV4ConnectCommand() { const instrumentation = this; - return (original: V4Connect['connect']) => { + return ( + original: V4Connect['connectCallback'] | V4Connect['connectPromise'] + ) => { return function patchedConnect( this: unknown, options: any, callback: any ) { + // from v6.4 `connect` method only accepts an options param and returns a promise + // with the connection + if (original.length === 1) { + const result = (original as V4Connect['connectPromise']).call( + this, + options + ); + if (result && typeof result.then === 'function') { + result.then( + () => instrumentation.setPoolName(options), + // this handler is set to pass the lint rules + () => undefined + ); + } + return result; + } + + // Earlier versions expects a callback param and return void const patchedCallback = function (err: any, conn: any) { if (err || !conn) { callback(err, conn); @@ -353,7 +382,12 @@ export class MongoDBInstrumentation extends InstrumentationBase { instrumentation.setPoolName(options); callback(err, conn); }; - return original.call(this, options, patchedCallback); + + return (original as V4Connect['connectCallback']).call( + this, + options, + patchedCallback + ); }; }; } @@ -361,7 +395,10 @@ export class MongoDBInstrumentation extends InstrumentationBase { // eslint-disable-next-line @typescript-eslint/no-unused-vars private _getV4ConnectionPatches() { return { - v4PatchConnection: (moduleExports: any, moduleVersion?: string) => { + v4PatchConnectionCallback: ( + moduleExports: any, + moduleVersion?: string + ) => { diag.debug(`Applying patch for mongodb@${moduleVersion}`); // patch insert operation if (isWrapped(moduleExports.Connection.prototype.command)) { @@ -371,7 +408,24 @@ export class MongoDBInstrumentation extends InstrumentationBase { this._wrap( moduleExports.Connection.prototype, 'command', - this._getV4PatchCommand() + this._getV4PatchCommandCallback() + ); + return moduleExports; + }, + v4PatchConnectionPromise: ( + moduleExports: any, + moduleVersion?: string + ) => { + diag.debug(`Applying patch for mongodb@${moduleVersion}`); + // patch insert operation + if (isWrapped(moduleExports.Connection.prototype.command)) { + this._unwrap(moduleExports.Connection.prototype, 'command'); + } + + this._wrap( + moduleExports.Connection.prototype, + 'command', + this._getV4PatchCommandPromise() ); return moduleExports; }, @@ -482,9 +536,9 @@ export class MongoDBInstrumentation extends InstrumentationBase { } /** Creates spans for command operation */ - private _getV4PatchCommand() { + private _getV4PatchCommandCallback() { const instrumentation = this; - return (original: V4Connection['command']) => { + return (original: V4Connection['commandCallback']) => { return function patchedV4ServerCommand( this: any, ns: any, @@ -504,22 +558,12 @@ export class MongoDBInstrumentation extends InstrumentationBase { ) { return original.call(this, ns, cmd, options, callback); } - if (!currentSpan) { - const patchedCallback = instrumentation._patchEnd( - undefined, - resultHandler, - this.id, - commandType - ); - return original.call(this, ns, cmd, options, patchedCallback); - } else { - const span = instrumentation.tracer.startSpan( - `mongodb.${commandType}`, - { - kind: SpanKind.CLIENT, - } - ); + let span = undefined; + if (currentSpan) { + span = instrumentation.tracer.startSpan(`mongodb.${commandType}`, { + kind: SpanKind.CLIENT, + }); instrumentation._populateV4Attributes( span, this, @@ -527,15 +571,64 @@ export class MongoDBInstrumentation extends InstrumentationBase { cmd, commandType ); - const patchedCallback = instrumentation._patchEnd( + } + const patchedCallback = instrumentation._patchEnd( + span, + resultHandler, + this.id, + commandType + ); + + return original.call(this, ns, cmd, options, patchedCallback); + }; + }; + } + + private _getV4PatchCommandPromise() { + const instrumentation = this; + return (original: V4Connection['commandPromise']) => { + return function patchedV4ServerCommand( + this: any, + ns: any, + cmd: any, + options: undefined | unknown + ) { + 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); + } + + let span = undefined; + if (currentSpan) { + span = instrumentation.tracer.startSpan(`mongodb.${commandType}`, { + kind: SpanKind.CLIENT, + }); + instrumentation._populateV4Attributes( span, - resultHandler, - this.id, + this, + ns, + cmd, commandType ); - - return original.call(this, ns, cmd, options, patchedCallback); } + + const patchedCallback = instrumentation._patchEnd( + span, + resultHandler, + this.id, + commandType + ); + + const result = original.call(this, ns, cmd, options); + result.then( + (res: any) => patchedCallback(null, res), + (err: any) => patchedCallback(err) + ); + + return result; }; }; } diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts b/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts index 5cb4119de5..38b357077b 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/src/internal-types.ts @@ -174,9 +174,18 @@ export type Document = { [key: string]: any; }; -// https://github.com/mongodb/node-mongodb-native/blob/v4.2.2/src/cmap/connection.ts export type V4Connection = { - command( + 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, + cmd: Document, + options: 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, cmd: Document, options: undefined | unknown, @@ -191,9 +200,14 @@ export type V4ConnectionPool = { checkOut: (callback: (error: any, connection: any) => void) => void; }; -// https://github.com/mongodb/node-mongodb-native/blob/v4.2.2/src/cmap/connect.ts export type V4Connect = { - connect: (options: any, callback: any) => void; + connect: 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.0/src/cmap/connect.ts + connectPromise: (options: any) => Promise; + // Earlier versions expect a callback param and return void + // https://github.com/mongodb/node-mongodb-native/blob/v4.2.2/src/cmap/connect.ts + connectCallback: (options: any, callback: any) => void; }; // https://github.com/mongodb/node-mongodb-native/blob/v4.2.2/src/sessions.ts diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v3.test.ts b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v3.test.ts index 938c00875a..144c375c68 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v3.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v3.test.ts @@ -31,7 +31,7 @@ const instrumentation = registerInstrumentationTesting( new MongoDBInstrumentation() ); -import * as mongodb from 'mongodb'; +import type { MongoClient, Collection } from 'mongodb'; import { assertSpans, accessCollection, DEFAULT_MONGO_HOST } from './utils'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; @@ -54,8 +54,8 @@ describe('MongoDBInstrumentation-Tracing-v3', () => { const DB_NAME = process.env.MONGODB_DB || 'opentelemetry-tests'; const COLLECTION_NAME = 'test'; - let client: mongodb.MongoClient; - let collection: mongodb.Collection; + let client: MongoClient; + let collection: Collection; before(done => { shouldTest = true; @@ -66,9 +66,7 @@ describe('MongoDBInstrumentation-Tracing-v3', () => { done(); }) .catch((err: Error) => { - console.log( - 'Skipping test-mongodb. Could not connect. Run MongoDB to test' - ); + console.log('Skipping test-mongodb. ' + err.message); shouldTest = false; done(); }); @@ -83,6 +81,7 @@ describe('MongoDBInstrumentation-Tracing-v3', () => { } // Non traced insertion of basic data to perform tests const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }]; + // @ts-expect-error -- v5 removed callback support collection.insertMany(insertData, (err: any, result: any) => { resetMemoryExporter(); done(); @@ -91,9 +90,11 @@ describe('MongoDBInstrumentation-Tracing-v3', () => { afterEach(done => { if (shouldTest) { - return collection.deleteMany({}, done); + // @ts-expect-error -- v5 removed callback support + collection.deleteMany({}, done); + } else { + done(); } - done(); }); after(() => { @@ -542,8 +543,8 @@ describe('MongoDBInstrumentation-Tracing-v3', () => { }); describe('MongoDb useUnifiedTopology enabled', () => { - let client: mongodb.MongoClient; - let collection: mongodb.Collection; + let client: MongoClient; + let collection: Collection; before(done => { accessCollection(URL, DB_NAME, COLLECTION_NAME, { // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -556,9 +557,7 @@ describe('MongoDBInstrumentation-Tracing-v3', () => { done(); }) .catch((err: Error) => { - console.log( - 'Skipping test-mongodb. Could not connect. Run MongoDB to test' - ); + console.log('Skipping test-mongodb. ' + err.message); shouldTest = false; done(); }); @@ -571,6 +570,7 @@ describe('MongoDBInstrumentation-Tracing-v3', () => { it('should generate correct span attributes', done => { const span = trace.getTracer('default').startSpan('findRootSpan'); context.with(trace.setSpan(context.active(), span), () => { + // @ts-expect-error -- v5 removed callback support collection.find({ a: 1 }).toArray((err, results) => { span.end(); const [mongoSpan] = getTestSpans(); diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4-v5-v6.metrics.test.ts b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4-v5-v6.metrics.test.ts index eb8d3b3946..9bb49cb45b 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4-v5-v6.metrics.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4-v5-v6.metrics.test.ts @@ -44,7 +44,7 @@ const instrumentation = registerInstrumentationTesting( ); import { accessCollection, DEFAULT_MONGO_HOST } from './utils'; -import * as mongodb from 'mongodb'; +import type { MongoClient, Collection } from 'mongodb'; import * as assert from 'assert'; async function waitForNumberOfExports( @@ -80,11 +80,26 @@ describe('MongoDBInstrumentation-Metrics', () => { const DB_NAME = process.env.MONGODB_DB || 'opentelemetry-tests-metrics'; const COLLECTION_NAME = 'test-metrics'; const URL = `mongodb://${HOST}:${PORT}/${DB_NAME}`; - let client: mongodb.MongoClient; - before(() => { + let client: MongoClient; + let collection: Collection; + + before(done => { otelTestingMeterProvider.addMetricReader(metricReader); instrumentation?.setMeterProvider(otelTestingMeterProvider); + + shouldTest = true; + accessCollection(URL, DB_NAME, COLLECTION_NAME) + .then(result => { + client = result.client; + collection = result.collection; + done(); + }) + .catch((err: Error) => { + console.log('Skipping test-mongodb. ' + err.message); + shouldTest = false; + done(); + }); }); beforeEach(function mongoBeforeEach(done) { @@ -100,9 +115,6 @@ describe('MongoDBInstrumentation-Metrics', () => { }); it('Should add connection usage metrics', async () => { - const result = await accessCollection(URL, DB_NAME, COLLECTION_NAME); - client = result.client; - const collection = result.collection; const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }]; await collection.insertMany(insertData); await collection.deleteMany({}); diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4.test.ts b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4.test.ts index 7fb8dc4fca..1a8af5f081 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4.test.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/test/mongodb-v4.test.ts @@ -33,7 +33,7 @@ const instrumentation = registerInstrumentationTesting( new MongoDBInstrumentation() ); -import * as mongodb from 'mongodb'; +import type { MongoClient, Collection } from 'mongodb'; import { assertSpans, accessCollection, DEFAULT_MONGO_HOST } from './utils'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; @@ -56,8 +56,8 @@ describe('MongoDBInstrumentation-Tracing-v4', () => { const COLLECTION_NAME = 'test-traces'; const URL = `mongodb://${HOST}:${PORT}/${DB_NAME}`; - let client: mongodb.MongoClient; - let collection: mongodb.Collection; + let client: MongoClient; + let collection: Collection; before(done => { accessCollection(URL, DB_NAME, COLLECTION_NAME) @@ -67,9 +67,7 @@ describe('MongoDBInstrumentation-Tracing-v4', () => { done(); }) .catch((err: Error) => { - console.log( - 'Skipping test-mongodb. Could not connect. Run MongoDB to test' - ); + console.log('Skipping test-mongodb. ' + err.message); shouldTest = false; done(); }); @@ -84,6 +82,7 @@ describe('MongoDBInstrumentation-Tracing-v4', () => { } // Non traced insertion of basic data to perform tests const insertData = [{ a: 1 }, { a: 2 }, { a: 3 }]; + // @ts-expect-error -- v5 removed callback support collection.insertMany(insertData, (err: any, result: any) => { resetMemoryExporter(); done(); @@ -92,9 +91,11 @@ describe('MongoDBInstrumentation-Tracing-v4', () => { afterEach(done => { if (shouldTest) { - return collection.deleteMany({}, done); + // @ts-expect-error -- v5 removed callback support + collection.deleteMany({}, done); + } else { + done(); } - done(); }); after(async () => { 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 b264a44efe..be6ac80ee0 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 @@ -42,7 +42,7 @@ let instrumentation: MongoDBInstrumentation; } } -import * as mongodb from 'mongodb'; +import type { MongoClient, Collection } from 'mongodb'; import { assertSpans, accessCollection, DEFAULT_MONGO_HOST } from './utils'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; @@ -65,8 +65,8 @@ describe('MongoDBInstrumentation-Tracing-v5', () => { const COLLECTION_NAME = 'test-traces'; const URL = `mongodb://${HOST}:${PORT}/${DB_NAME}`; - let client: mongodb.MongoClient; - let collection: mongodb.Collection; + let client: MongoClient; + let collection: Collection; before(done => { accessCollection(URL, DB_NAME, COLLECTION_NAME) @@ -76,9 +76,7 @@ describe('MongoDBInstrumentation-Tracing-v5', () => { done(); }) .catch((err: Error) => { - console.log( - 'Skipping test-mongodb. Could not connect. Run MongoDB to test' - ); + console.log('Skipping test-mongodb. ' + err.message); shouldTest = false; done(); }); diff --git a/plugins/node/opentelemetry-instrumentation-mongodb/test/utils.ts b/plugins/node/opentelemetry-instrumentation-mongodb/test/utils.ts index 02b26705f6..a158cc9b16 100644 --- a/plugins/node/opentelemetry-instrumentation-mongodb/test/utils.ts +++ b/plugins/node/opentelemetry-instrumentation-mongodb/test/utils.ts @@ -18,13 +18,13 @@ import { SpanKind, SpanStatusCode } from '@opentelemetry/api'; import { SemanticAttributes } from '@opentelemetry/semantic-conventions'; import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import * as assert from 'assert'; -import * as mongodb from 'mongodb'; +import type { MongoClient, MongoClientOptions, Collection } from 'mongodb'; export const DEFAULT_MONGO_HOST = '127.0.0.1'; export interface MongoDBAccess { - client: mongodb.MongoClient; - collection: mongodb.Collection; + client: MongoClient; + collection: Collection; } /** @@ -38,19 +38,28 @@ export function accessCollection( url: string, dbName: string, collectionName: string, - options: mongodb.MongoClientOptions = {} + options: MongoClientOptions = {} ): Promise { return new Promise((resolve, reject) => { + let mongodb; + try { + mongodb = require('mongodb'); + } catch (err: any) { + reject(new Error('Could not load mongodb. ' + err.message)); + return; + } mongodb.MongoClient.connect(url, { serverSelectionTimeoutMS: 1000, }) - .then(client => { + .then((client: MongoClient) => { const db = client.db(dbName); const collection = db.collection(collectionName); resolve({ client, collection }); }) - .catch(reason => { - reject(reason); + .catch((reason: any) => { + reject( + new Error('Could not connect. Run MongoDB to test. ' + reason.message) + ); }); }); }