From 025d36ffda4bf0e95f47cb90aed9c77dcc4a3094 Mon Sep 17 00:00:00 2001 From: Arya Mohanan Date: Mon, 17 Jun 2024 14:12:24 +0530 Subject: [PATCH] chore: fine tuning --- package-lock.json | 12 +- package.json | 3 +- packages/aws-fargate/esm-loader.mjs | 3 + packages/aws-fargate/esm-register.mjs | 11 +- .../azure-container-services/esm-loader.mjs | 3 + .../azure-container-services/esm-register.mjs | 11 +- packages/collector/esm-app/index.mjs | 23 - packages/collector/esm-app/package-lock.json | 961 ------------------ packages/collector/esm-app/package.json | 15 - packages/collector/esm-loader.mjs | 3 + packages/collector/esm-register.mjs | 8 +- .../test/test_util/ProcessControls.js | 3 +- .../database/elasticsearch/mockVersion.js | 6 +- .../tracing/database/mongodb/mockVersion.js | 6 +- .../test/tracing/database/prisma/test.js | 31 +- .../collector/test/tracing/esm/iitm/test.js | 78 -- .../test/tracing/logger/pino/mockVersion.js | 6 +- .../tracing/messaging/amqp/mockVersion.js | 6 +- .../collector/test/tracing/native_esm/app.js | 53 + .../tracing/{esm/iitm => native_esm}/app.mjs | 6 +- .../collector/test/tracing/native_esm/test.js | 75 ++ .../tracing/protocols/graphql/mockVersion.js | 6 +- .../tracing/protocols/grpc-js/mockVersion.js | 6 +- packages/core/{loader.mjs => iitm-loader.mjs} | 0 packages/core/package.json | 2 +- .../core/src/tracing/esmSupportedVersion.js | 23 +- packages/core/src/tracing/hook.js | 42 +- packages/core/src/tracing/index.js | 2 +- .../instrumentation/cloud/aws-sdk/v2/index.js | 4 +- .../instrumentation/cloud/aws-sdk/v2/sdk.js | 4 +- .../instrumentation/cloud/aws-sdk/v2/sqs.js | 6 +- .../instrumentation/cloud/aws-sdk/v3/index.js | 10 +- .../cloud/aws-sdk/v3/sqs-consumer.js | 4 +- .../instrumentation/cloud/aws-sdk/v3/sqs.js | 6 +- .../instrumentation/cloud/azure/blob.js | 4 +- .../instrumentation/cloud/gcp/pubsub.js | 6 +- .../instrumentation/cloud/gcp/storage.js | 4 +- .../instrumentation/control_flow/bluebird.js | 4 +- .../instrumentation/control_flow/clsHooked.js | 4 +- .../control_flow/graphqlSubscriptions.js | 6 +- .../instrumentation/database/couchbase.js | 4 +- .../tracing/instrumentation/database/db2.js | 4 +- .../instrumentation/database/elasticsearch.js | 4 +- .../instrumentation/database/ioredis.js | 4 +- .../instrumentation/database/memcached.js | 4 +- .../instrumentation/database/mongodb.js | 8 +- .../instrumentation/database/mongoose.js | 4 +- .../tracing/instrumentation/database/mssql.js | 4 +- .../tracing/instrumentation/database/mysql.js | 8 +- .../tracing/instrumentation/database/pg.js | 4 +- .../instrumentation/database/pgNative.js | 4 +- .../instrumentation/database/prisma.js | 4 +- .../tracing/instrumentation/database/redis.js | 6 +- .../instrumentation/frameworks/express.js | 4 +- .../instrumentation/frameworks/fastify.js | 4 +- .../instrumentation/frameworks/hapi.js | 4 +- .../tracing/instrumentation/frameworks/koa.js | 4 +- .../tracing/instrumentation/loggers/bunyan.js | 4 +- .../tracing/instrumentation/loggers/log4js.js | 6 +- .../tracing/instrumentation/loggers/pino.js | 4 +- .../instrumentation/loggers/winston.js | 6 +- .../tracing/instrumentation/messaging/amqp.js | 8 +- .../tracing/instrumentation/messaging/bull.js | 4 +- .../instrumentation/messaging/kafkaJs.js | 6 +- .../instrumentation/messaging/kafkaNode.js | 4 +- .../tracing/instrumentation/messaging/nats.js | 4 +- .../messaging/natsStreaming.js | 4 +- .../instrumentation/messaging/rdkafka.js | 8 +- .../instrumentation/process/memored.js | 4 +- .../instrumentation/protocols/graphql.js | 8 +- .../instrumentation/protocols/grpcJs.js | 8 +- .../instrumentation/protocols/httpClient.js | 4 +- .../instrumentation/protocols/superagent.js | 4 +- .../instrumentation/test/squareCalc.js | 15 +- .../src/util/applicationUnderMonitoring.js | 15 +- packages/core/src/util/iitmHook.js | 34 +- .../src/util/initializedTooLateHeuristic.js | 3 +- packages/core/src/util/normalizeConfig.js | 1 - packages/core/src/util/requireHook.js | 4 +- packages/google-cloud-run/esm-loader.mjs | 3 + packages/google-cloud-run/esm-register.mjs | 11 +- 81 files changed, 410 insertions(+), 1306 deletions(-) delete mode 100644 packages/collector/esm-app/index.mjs delete mode 100644 packages/collector/esm-app/package-lock.json delete mode 100644 packages/collector/esm-app/package.json delete mode 100644 packages/collector/test/tracing/esm/iitm/test.js create mode 100644 packages/collector/test/tracing/native_esm/app.js rename packages/collector/test/tracing/{esm/iitm => native_esm}/app.mjs (86%) create mode 100644 packages/collector/test/tracing/native_esm/test.js rename packages/core/{loader.mjs => iitm-loader.mjs} (100%) diff --git a/package-lock.json b/package-lock.json index 0d6a9c1963..ffcbbad0be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -161,7 +161,8 @@ "socket.io-client": "^4.7.5", "sqs-consumer": "^10.3.0", "sqs-consumer-v5": "npm:sqs-consumer@^5.7.0", - "square-calc": "^2.2.3", + "square-calc": "^3.1.0", + "square-calc-v2": "npm:square-calc@^2.2.3", "stealthy-require": "1.1.1", "superagent": "^9.0.2", "tedious": "^15.1.3", @@ -47435,6 +47436,13 @@ } }, "node_modules/square-calc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/square-calc/-/square-calc-3.1.0.tgz", + "integrity": "sha512-KcqANB9SAekQqFgSjhSC28lD61emsmt0aD1302IbVX7BeHGD1PHQS/6Y0ZNXb/tFQKXBuECnn8+TgRdxkp8lIA==", + "dev": true + }, + "node_modules/square-calc-v2": { + "name": "square-calc", "version": "2.2.3", "resolved": "https://registry.npmjs.org/square-calc/-/square-calc-2.2.3.tgz", "integrity": "sha512-4o+2OoT+4IegZDjsnQlvYeWtzuvXjbQfVwNaNE8oOt7cARdotbwQPvltW3eNKADG5EmgJkbL2zyTJLQMSvGfOw==", @@ -51110,7 +51118,7 @@ "@opentelemetry/instrumentation-tedious": "0.10.1", "@opentelemetry/sdk-trace-base": "1.24.0", "cls-bluebird": "^2.1.0", - "import-in-the-middle": "^1.7.4", + "import-in-the-middle": "1.7.4", "lru-cache": "^10.1.0", "methods": "^1.1.2", "opentracing": "^0.14.5", diff --git a/package.json b/package.json index f1dfee0960..b88f2934cc 100644 --- a/package.json +++ b/package.json @@ -219,7 +219,8 @@ "socket.io-client": "^4.7.5", "sqs-consumer": "^10.3.0", "sqs-consumer-v5": "npm:sqs-consumer@^5.7.0", - "square-calc": "^2.2.3", + "square-calc": "^3.1.0", + "square-calc-v2": "npm:square-calc@^2.2.3", "stealthy-require": "1.1.1", "superagent": "^9.0.2", "tedious": "^15.1.3", diff --git a/packages/aws-fargate/esm-loader.mjs b/packages/aws-fargate/esm-loader.mjs index 3b25bb492d..92cf7bc98b 100644 --- a/packages/aws-fargate/esm-loader.mjs +++ b/packages/aws-fargate/esm-loader.mjs @@ -24,3 +24,6 @@ */ import './src/index.js'; +// Here we exports all named exports from '@instana/core/iitm-loader.mjs', enabling +// integration of import-in-the-middle (IITM) for Native ESM module support. +export * from '@instana/core/iitm-loader.mjs'; diff --git a/packages/aws-fargate/esm-register.mjs b/packages/aws-fargate/esm-register.mjs index b011f8a5e8..fbed0ffa0a 100644 --- a/packages/aws-fargate/esm-register.mjs +++ b/packages/aws-fargate/esm-register.mjs @@ -9,7 +9,7 @@ * Previously, loading the Instana collector within the loader and after the update ESM support * no longer working with v18.19 and above. To address this, we've opted to load the Instana * collector in the main thread using --import. - * Additionally, we aim to incorporate native ESM support by utilizing the node register method, + * Additionally, we incorporated native ESM support by utilizing the node register method, * enabling customization of the ESM loader with 'import-in-the-middle'. * * Usage: @@ -19,7 +19,8 @@ // Import the initialization module for aws-fargate collector; it self-initializes upon import // and it should be executed in the main thread. import './src/index.js'; - -// We plan to utilize this for adding native ESM support in the near future -// import { register } from 'node:module'; -// register(./loader.mjs, import.meta.url); \ No newline at end of file +import { register } from 'node:module'; +// ESM module resolution and loading are facilitated by registering `@instana/core/iitm-loader.mjs`, which exports +// import-in-the-middle(IITM) hooks. This registration can be accomplished using the register method from node:module. +// see: https://nodejs.org/api/module.html#customization-hooks +register('@instana/core/iitm-loader.mjs', import.meta.url); \ No newline at end of file diff --git a/packages/azure-container-services/esm-loader.mjs b/packages/azure-container-services/esm-loader.mjs index c87787f4fd..3e3b032983 100644 --- a/packages/azure-container-services/esm-loader.mjs +++ b/packages/azure-container-services/esm-loader.mjs @@ -24,3 +24,6 @@ */ import './src/index.js'; +// Here we exports all named exports from '@instana/core/iitm-loader.mjs', enabling +// integration of import-in-the-middle (IITM) for Native ESM module support. +export * from '@instana/core/iitm-loader.mjs'; diff --git a/packages/azure-container-services/esm-register.mjs b/packages/azure-container-services/esm-register.mjs index d33dae0917..a49e88948c 100644 --- a/packages/azure-container-services/esm-register.mjs +++ b/packages/azure-container-services/esm-register.mjs @@ -8,7 +8,7 @@ * see https://github.com/nodejs/node/pull/44710. * Previously, loading the Instana collector within the loader and after the update ESM support * no longer working with v18.19 and above. To address this, we've opted to load the Instana - * collector in the main thread using --import. Additionally, we aim to incorporate native ESM + * collector in the main thread using --import. Additionally, we incorporated native ESM * support by utilizing the node register method, enabling customization of the ESM loader * with 'import-in-the-middle'. * @@ -19,7 +19,8 @@ // Import the initialization module for azure-container-services collector; it self-initializes upon import // and it should be executed in the main thread. import './src/index.js'; - -// We plan to utilize this for adding native ESM support in the near future -// import { register } from 'node:module'; -// register(./loader.mjs, import.meta.url); \ No newline at end of file +import { register } from 'node:module'; +// ESM module resolution and loading are facilitated by registering `@instana/core/iitm-loader.mjs`, which exports +// import-in-the-middle(IITM) hooks. This registration can be accomplished using the register method from node:module. +// see: https://nodejs.org/api/module.html#customization-hooks +register('@instana/core/iitm-loader.mjs', import.meta.url); \ No newline at end of file diff --git a/packages/collector/esm-app/index.mjs b/packages/collector/esm-app/index.mjs deleted file mode 100644 index 1f842d9719..0000000000 --- a/packages/collector/esm-app/index.mjs +++ /dev/null @@ -1,23 +0,0 @@ -import got from 'got'; -import express from 'express'; -import calculateSquare from 'square-calc'; - -const app = express(); - -app.use(express.json()); - -app.get('/', (req, res) => { - console.log(`${req.method} ${req.url}`); - res.send('Hello World, I am ES module'); -}); - -app.get('/esm', async (req, res) => { - const square = calculateSquare(5); - console.log(`square ${square}`); - await got('https://example.com/?random=1000'); - res.send({ status: 'ok' }); -}); - -app.listen(3003, () => { - console.log('Welcome to ES module express app'); -}); diff --git a/packages/collector/esm-app/package-lock.json b/packages/collector/esm-app/package-lock.json deleted file mode 100644 index ea7e23f40e..0000000000 --- a/packages/collector/esm-app/package-lock.json +++ /dev/null @@ -1,961 +0,0 @@ -{ - "name": "esm-app", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "esm-app", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "express": "^4.18.3", - "got": "^14.3.0", - "square-calc": "^3.1.0" - } - }, - "node_modules/@sec-ant/readable-stream": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", - "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==" - }, - "node_modules/@sindresorhus/is": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-6.3.1.tgz", - "integrity": "sha512-FX4MfcifwJyFOI2lPoX7PQxCqx8BG1HCho7WdiXwpEQx1Ycij0JxkfYtGK7yqNScrZGSlt6RE6sw8QYoH7eKnQ==", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", - "engines": { - "node": ">=14.16" - } - }, - "node_modules/cacheable-request": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-12.0.1.tgz", - "integrity": "sha512-Yo9wGIQUaAfIbk+qY0X4cDQgCosecfBe3V9NSyeY4qPC2SAkbCS4Xj79VP8WOzitpJUZKc/wsRCYF5ariDIwkg==", - "dependencies": { - "@types/http-cache-semantics": "^4.0.4", - "get-stream": "^9.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.4", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.1", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", - "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", - "dependencies": { - "@sec-ant/readable-stream": "^0.4.1", - "is-stream": "^4.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/form-data-encoder": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-4.0.2.tgz", - "integrity": "sha512-KQVhvhK8ZkWzxKxOr56CPulAhH3dobtuQ4+hNQ+HekH/Wp5gSOafqRAeTphQUJAIk0GBvHZgJ2ZGRWd5kphMuw==", - "engines": { - "node": ">= 18" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "14.3.0", - "resolved": "https://registry.npmjs.org/got/-/got-14.3.0.tgz", - "integrity": "sha512-vZkrXdq5BtPWTXqvjXSpl6zky3zpHaOVfSug/RfFHu3YrtSsvYzopVMDqrh2do77WnGoCSSRCHW25zXOSAQ9zw==", - "dependencies": { - "@sindresorhus/is": "^6.3.1", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^12.0.1", - "decompress-response": "^6.0.0", - "form-data-encoder": "^4.0.2", - "get-stream": "^8.0.1", - "http2-wrapper": "^2.2.1", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^4.0.1", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/normalize-url": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", - "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/p-cancelable": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-4.0.1.tgz", - "integrity": "sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg==", - "engines": { - "node": ">=14.16" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/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==" - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/square-calc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/square-calc/-/square-calc-3.1.0.tgz", - "integrity": "sha512-KcqANB9SAekQqFgSjhSC28lD61emsmt0aD1302IbVX7BeHGD1PHQS/6Y0ZNXb/tFQKXBuECnn8+TgRdxkp8lIA==" - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - } - } -} diff --git a/packages/collector/esm-app/package.json b/packages/collector/esm-app/package.json deleted file mode 100644 index 5e6a8f096e..0000000000 --- a/packages/collector/esm-app/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "esm-app", - "version": "1.0.0", - "scripts": { - "start": "node --inspect-brk=0.0.0.0:9229 --import ../esm-register.mjs index.mjs", - "start-v18": "node --loader ../esm-loader.mjs app.mjs" - }, - "author": "arya.mohanan@ibm.com", - "license": "ISC", - "dependencies": { - "square-calc": "^3.1.0", - "express": "^4.18.3", - "got": "^14.3.0" - } -} diff --git a/packages/collector/esm-loader.mjs b/packages/collector/esm-loader.mjs index e778551940..22bb377090 100644 --- a/packages/collector/esm-loader.mjs +++ b/packages/collector/esm-loader.mjs @@ -20,3 +20,6 @@ import instana from './src/index.js'; instana(); +// Here we exports all named exports from '@instana/core/iitm-loader.mjs', enabling +// integration of import-in-the-middle (IITM) for Native ESM module support. +export * from '@instana/core/iitm-loader.mjs'; diff --git a/packages/collector/esm-register.mjs b/packages/collector/esm-register.mjs index 5c1c686e3a..b8d1e33c8f 100644 --- a/packages/collector/esm-register.mjs +++ b/packages/collector/esm-register.mjs @@ -8,7 +8,7 @@ * see https://github.com/nodejs/node/pull/44710. * Previously, loading the Instana collector within the loader and after the update ESM support * no longer working with v18.19 and above. To address this, we've opted to load the Instana - * collector in the main thread using --import. Additionally, we aim to incorporate native ESM + * collector in the main thread using --import. Additionally, we incorporated native ESM * support by utilizing the node register method, enabling customization of the ESM loader * with 'import-in-the-middle'. * @@ -19,6 +19,8 @@ // Import the initialization module for Instana collector and it should be executed in the main thread. import instana from './src/index.js'; instana(); - +// ESM module resolution and loading are facilitated by registering `@instana/core/iitm-loader.mjs`, which exports +// import-in-the-middle(IITM) hooks. This registration can be accomplished using the register method from node:module. +// see: https://nodejs.org/api/module.html#customization-hooks import { register } from 'node:module'; -register('@instana/core/loader.mjs', import.meta.url); +register('@instana/core/iitm-loader.mjs', import.meta.url); diff --git a/packages/collector/test/test_util/ProcessControls.js b/packages/collector/test/test_util/ProcessControls.js index 58f664c6fc..5592caf181 100644 --- a/packages/collector/test/test_util/ProcessControls.js +++ b/packages/collector/test/test_util/ProcessControls.js @@ -38,7 +38,6 @@ class ProcessControls { * @property {boolean} [tracingEnabled] * @property {*} [agentControls] * @property {Object. { providers.forEach(provider => { - let mochaSuiteFn = supportedVersion(process.versions.node) ? describe : describe.skip; - mochaSuiteFn = version === 'latest' && semver.lt(process.versions.node, '16.0.0') ? describe.skip : describe; + let mochaSuiteFn = describe; + + if (supportedVersion(process.versions.node)) { + // Skip tests for Node.js version 18.19.0 and above due to an issue with import-in-the-middle (IITM) package. + // See https://github.com/DataDog/import-in-the-middle/issues/97 + if (semver.gte(process.versions.node, '18.19.0')) { + mochaSuiteFn = describe.skip; + } + + if (version === 'latest' && semver.lt(process.versions.node, '16.0.0')) { + mochaSuiteFn = describe.skip; + } + } else { + mochaSuiteFn = describe.skip; + } mochaSuiteFn(`[${version}] with provider ${provider}`, () => { if (provider === 'postgresql' && !process.env.PRISMA_POSTGRES_URL) { @@ -60,20 +73,6 @@ describe('tracing/prisma', function () { } catch (err) { // ignore } - - // By default, Prisma Client is generated into the './node_modules/.prisma/client' folder. - // However, In case of ESM apps when loading the module with the IITM hook, it checks for its - // installation in the root 'node_modules' folder. Therefore, if the '.prisma' folder is not found - // in the root directory during module loading, this code copies it from its default location. - // This is beacuse of we are handling prisma tests differently in our code base. - const prismaClientDestination = path.resolve(__dirname, '../../../../../../node_modules/.prisma'); - const destinationExists = await fs - .access(prismaClientDestination) - .then(() => true) - .catch(() => false); - if (!destinationExists) { - await recursiveCopy(path.resolve(__dirname, './node_modules/.prisma'), prismaClientDestination); - } }); // Set up Prisma stuff for the provider we want to test with (either sqlite or postgresql). diff --git a/packages/collector/test/tracing/esm/iitm/test.js b/packages/collector/test/tracing/esm/iitm/test.js deleted file mode 100644 index a445aea620..0000000000 --- a/packages/collector/test/tracing/esm/iitm/test.js +++ /dev/null @@ -1,78 +0,0 @@ -/* - * (c) Copyright IBM Corp. 2024 - */ - -'use strict'; - -const expect = require('chai').expect; -const supportedVersion = require('@instana/core').tracing.supportedVersion; -const config = require('../../../../../core/test/config'); -const { retry, verifyEntrySpan } = require('../../../../../core/test/test_util'); -const ProcessControls = require('../../../test_util/ProcessControls'); -const globalAgent = require('../../../globalAgent'); -const constants = require('@instana/core').tracing.constants; - -const mochaSuiteFn = supportedVersion(process.versions.node) ? describe : describe.skip; - -mochaSuiteFn('[ESM] - iitm', function () { - this.timeout(config.getTestTimeout()); - - globalAgent.setUpCleanUpHooks(); - const agentControls = globalAgent.instance; - - let controls; - - before(async () => { - controls = new ProcessControls({ - dirname: __dirname, - useGlobalAgent: true, - esm: true // TODO: a temp solution, TBD - }); - await controls.startAndWaitForAgentConnection(); - }); - - beforeEach(async () => { - await agentControls.clearReceivedTraceData(); - }); - - after(async () => { - await controls.stop(); - }); - - afterEach(async () => { - await controls.clearIpcMessages(); - }); - - it('GET request', () => - controls - .sendRequest({ - method: 'GET', - path: '/request' - }) - .then(() => - retry(() => - agentControls.getSpans().then(spans => { - expect(spans.length).to.equal(2); - verifyEntrySpan({ - spanName: 'node.http.server', - spans, - withError: false, - pid: String(controls.getPid()), - dataProperty: 'http', - extraTests: [ - span => { - expect(span.data.http.method).to.equal('GET'); - expect(span.data.http.url).to.equal('/request'); - expect(span.data.http.status).to.equal(200); - } - ] - }); - - const calculatorSpan = spans.find(span => span.n === 'square-calc'); - expect(calculatorSpan).to.exist; - expect(calculatorSpan.k).to.equal(constants.EXIT); - expect(calculatorSpan.data.calculator).to.be.an('object'); - }) - ) - )); -}); diff --git a/packages/collector/test/tracing/logger/pino/mockVersion.js b/packages/collector/test/tracing/logger/pino/mockVersion.js index 8dc3c364b4..0194db9fe4 100644 --- a/packages/collector/test/tracing/logger/pino/mockVersion.js +++ b/packages/collector/test/tracing/logger/pino/mockVersion.js @@ -5,7 +5,7 @@ 'use strict'; const mock = require('mock-require'); -const requireHook = require('../../../../../core/src/util/requireHook'); +const hook = require('../../../../../core/src/tracing/hook'); const PINO_VERSION = process.env.PINO_VERSION || 'latest'; const PINO_REQUIRE = PINO_VERSION === 'latest' ? 'pino' : `pino-${PINO_VERSION}`; @@ -22,8 +22,8 @@ if (PINO_REQUIRE !== 'pino') { * If we test against `pino-v6`, we need to wait for the * on file load event for `node_modules/pino-v6/....js` */ -const originalOnFileLoad = requireHook.onFileLoad; -requireHook.onFileLoad = function onFileLoad() { +const originalOnFileLoad = hook.onFileLoad; +hook.onFileLoad = function onFileLoad() { if (arguments[0].toString() !== '/\\/pino\\/lib\\/tools\\.js/') { return originalOnFileLoad.apply(this, arguments); } diff --git a/packages/collector/test/tracing/messaging/amqp/mockVersion.js b/packages/collector/test/tracing/messaging/amqp/mockVersion.js index 4a17b20f1c..152b13c4a3 100644 --- a/packages/collector/test/tracing/messaging/amqp/mockVersion.js +++ b/packages/collector/test/tracing/messaging/amqp/mockVersion.js @@ -6,7 +6,7 @@ const Module = require('module'); const mock = require('mock-require'); -const requireHook = require('../../../../../core/src/util/requireHook'); +const hook = require('../../../../../core/src/tracing/hook'); const AMQPLIB_REQUIRE = process.env.AMQPLIB_VERSION === 'latest' ? 'amqplib' : `amqplib-${process.env.AMQPLIB_VERSION}`; @@ -23,8 +23,8 @@ if (AMQPLIB_REQUIRE !== 'amqplib') { * If we test against `amqplib-v0.8.0`, we need to wait for the * on file load event for `node_modules/amqplib-v0.8.0/lib/... */ -const originalOnFileLoad = requireHook.onFileLoad; -requireHook.onFileLoad = function onFileLoad() { +const originalOnFileLoad = hook.onFileLoad; +hook.onFileLoad = function onFileLoad() { if ( arguments[0].source === '\\/amqplib\\/lib\\/channel\\.js' || arguments[0].source === '\\/amqplib\\/lib\\/channel_model\\.js' || diff --git a/packages/collector/test/tracing/native_esm/app.js b/packages/collector/test/tracing/native_esm/app.js new file mode 100644 index 0000000000..c55f8dd554 --- /dev/null +++ b/packages/collector/test/tracing/native_esm/app.js @@ -0,0 +1,53 @@ +/* + * (c) Copyright IBM Corp. 2024 + */ + +'use strict'; + +// NOTE: c8 bug https://github.com/bcoe/c8/issues/166 +process.on('SIGTERM', () => { + process.disconnect(); + process.exit(0); +}); +const mock = require('mock-require'); +mock('square-calc', 'square-calc-v2'); + +require('../../..')(); +const express = require('express'); +const morgan = require('morgan'); +const bodyParser = require('body-parser'); +const getAppPort = require('../../test_util/app-port'); +const calculateSquare = require('square-calc'); + +const port = getAppPort(); + +const app = express(); +const logPrefix = `Native ESM App (${process.pid}):\t`; + +if (process.env.WITH_STDOUT) { + app.use(morgan(`${logPrefix}:method :url :status`)); +} + +app.use(bodyParser.json()); + +app.get('/', async (req, res) => { + res.sendStatus(200); +}); + +app.get('/request', async (req, res) => { + const square = calculateSquare(5); + res.json({ square }); +}); + +app.listen(port, () => { + log(`Listening on port: ${port}`); +}); + +function log() { + const args = Array.prototype.slice.call(arguments); + args[0] = logPrefix + args[0]; + // eslint-disable-next-line no-console + console.log.apply(console, args); +} + +module.exports = app; diff --git a/packages/collector/test/tracing/esm/iitm/app.mjs b/packages/collector/test/tracing/native_esm/app.mjs similarity index 86% rename from packages/collector/test/tracing/esm/iitm/app.mjs rename to packages/collector/test/tracing/native_esm/app.mjs index b8bd43b8dc..b199658e7f 100644 --- a/packages/collector/test/tracing/esm/iitm/app.mjs +++ b/packages/collector/test/tracing/native_esm/app.mjs @@ -13,7 +13,7 @@ process.on('SIGTERM', () => { import express from 'express'; import morgan from 'morgan'; import bodyParser from 'body-parser'; -import getAppPort from '../../../test_util/app-port.js'; +import getAppPort from '../../test_util/app-port.js'; import calculateSquare from 'square-calc'; const port = getAppPort(); @@ -36,6 +36,10 @@ app.get('/request', async (req, res) => { const square = calculateSquare(5); res.json({ square }); }); +app.get('/cjs', async (req, res) => { + const square = calculateSquare(5); + res.json({ square }); +}); app.listen(port, () => { log(`Listening on port: ${port}`); diff --git a/packages/collector/test/tracing/native_esm/test.js b/packages/collector/test/tracing/native_esm/test.js new file mode 100644 index 0000000000..dc731c045a --- /dev/null +++ b/packages/collector/test/tracing/native_esm/test.js @@ -0,0 +1,75 @@ +/* + * (c) Copyright IBM Corp. 2024 + */ + +'use strict'; + +const expect = require('chai').expect; +const supportedVersion = require('@instana/core').tracing.supportedVersion; +const config = require('../../../../core/test/config'); +const { retry, verifyEntrySpan } = require('../../../../core/test/test_util'); +const ProcessControls = require('../../test_util/ProcessControls'); +const globalAgent = require('../../globalAgent'); +const constants = require('@instana/core').tracing.constants; + +const mochaSuiteFn = supportedVersion(process.versions.node) ? describe : describe.skip; + +mochaSuiteFn('tracing/native-esm modules', function () { + this.timeout(config.getTestTimeout()); + + globalAgent.setUpCleanUpHooks(); + const agentControls = globalAgent.instance; + + let controls; + + before(async () => { + controls = new ProcessControls({ + dirname: __dirname, + useGlobalAgent: true + }); + await controls.startAndWaitForAgentConnection(); + }); + + beforeEach(async () => { + await agentControls.clearReceivedTraceData(); + }); + + after(async () => { + await controls.stop(); + }); + + afterEach(async () => { + await controls.clearIpcMessages(); + }); + + it('should collect spans', async () => { + await controls.sendRequest({ + method: 'GET', + path: '/request' + }); + + await retry(async () => { + const spans = await agentControls.getSpans(); + expect(spans.length).to.equal(2); + verifyEntrySpan({ + spanName: 'node.http.server', + spans, + withError: false, + pid: String(controls.getPid()), + dataProperty: 'http', + extraTests: [ + span => { + expect(span.data.http.method).to.equal('GET'); + expect(span.data.http.url).to.equal('/request'); + expect(span.data.http.status).to.equal(200); + } + ] + }); + + const calculatorSpan = spans.find(span => span.n === 'square-calc'); + expect(calculatorSpan).to.exist; + expect(calculatorSpan.k).to.equal(constants.EXIT); + expect(calculatorSpan.data.calculator).to.be.an('object'); + }); + }); +}); diff --git a/packages/collector/test/tracing/protocols/graphql/mockVersion.js b/packages/collector/test/tracing/protocols/graphql/mockVersion.js index 2d82b1f6ba..192e0628c5 100644 --- a/packages/collector/test/tracing/protocols/graphql/mockVersion.js +++ b/packages/collector/test/tracing/protocols/graphql/mockVersion.js @@ -8,7 +8,7 @@ const semver = require('semver'); const path = require('path'); const mock = require('mock-require'); -const requireHook = require('../../../../../core/src/util/requireHook'); +const hook = require('../../../../../core/src/tracing/hook'); const graphqlMajorDefault = semver.major(require(`${path.dirname(require.resolve('graphql'))}/package.json`).version); const GRAPHQL_VERSION = process.env.GRAPHQL_VERSION || graphqlMajorDefault.toString(); @@ -45,8 +45,8 @@ if (GRAPHQL_REQUIRE !== 'graphql') { * If we test against `graphql-v16`, we need to wait for the * on file load event for `node_modules/graphql-v16/execution/execution.js` */ -const originalOnFileLoad = requireHook.onFileLoad; -requireHook.onFileLoad = function onFileLoad() { +const originalOnFileLoad = hook.onFileLoad; +hook.onFileLoad = function onFileLoad() { if (arguments[0].toString() !== '/\\/graphql\\/execution\\/execute.js/') { return originalOnFileLoad.apply(this, arguments); } diff --git a/packages/collector/test/tracing/protocols/grpc-js/mockVersion.js b/packages/collector/test/tracing/protocols/grpc-js/mockVersion.js index 96acb7762d..072acf6727 100644 --- a/packages/collector/test/tracing/protocols/grpc-js/mockVersion.js +++ b/packages/collector/test/tracing/protocols/grpc-js/mockVersion.js @@ -5,7 +5,7 @@ 'use strict'; const mock = require('mock-require'); -const requireHook = require('../../../../../core/src/util/requireHook'); +const hook = require('../../../../../core/src/tracing/hook'); const INSTANA_GRPC_VERSION = process.env.INSTANA_GRPC_VERSION; const GRPC_REQUIRE = @@ -15,8 +15,8 @@ if (GRPC_REQUIRE !== '@grpc/grpc-js') { mock('@grpc/grpc-js', GRPC_REQUIRE); } -const originalOnFileLoad = requireHook.onFileLoad; -requireHook.onFileLoad = function onFileLoad() { +const originalOnFileLoad = hook.onFileLoad; +hook.onFileLoad = function onFileLoad() { if ( arguments[0].source === '\\/@grpc\\/grpc-js\\/build\\/src\\/server\\.js' || arguments[0].source === '\\/@grpc\\/grpc-js\\/build\\/src\\/client\\.js' diff --git a/packages/core/loader.mjs b/packages/core/iitm-loader.mjs similarity index 100% rename from packages/core/loader.mjs rename to packages/core/iitm-loader.mjs diff --git a/packages/core/package.json b/packages/core/package.json index 41b1a7f0c2..576a8a8d9e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -64,7 +64,7 @@ "@opentelemetry/instrumentation-tedious": "0.10.1", "@opentelemetry/sdk-trace-base": "1.24.0", "cls-bluebird": "^2.1.0", - "import-in-the-middle": "^1.7.4", + "import-in-the-middle": "1.7.4", "lru-cache": "^10.1.0", "methods": "^1.1.2", "opentracing": "^0.14.5", diff --git a/packages/core/src/tracing/esmSupportedVersion.js b/packages/core/src/tracing/esmSupportedVersion.js index ea7c3f7b3c..15a9bbf485 100644 --- a/packages/core/src/tracing/esmSupportedVersion.js +++ b/packages/core/src/tracing/esmSupportedVersion.js @@ -39,13 +39,20 @@ exports.hasExperimentalLoaderFlag = function hasExperimentalLoaderFlag() { return experimentalLoaderFlagIsSet && exports.isLatestEsmSupportedVersion(process.versions.node); }; + /** - * Checks if the application is an ESM (ECMAScript Modules) app by inspecting how the collector is invoked with flags - * like --experimental-loader and --import. - * @returns {boolean} - True if the application is an ESM app, false otherwise. + * Checks if the application is an ECMAScript Modules (ESM) app by inspecting + * the presence of flags like --experimental-loader and --import in the environment. + * @returns {boolean} True if an ESM app is detected, false otherwise. + * If the application is ESM, caching the result for efficiency. */ exports.isESMApp = function isESMApp() { - return ( + const cacheKey = 'isESMApp'; + + if (require.cache[cacheKey]) { + return require.cache[cacheKey].exports; + } + const isESM = (process.env.NODE_OPTIONS && (process.env.NODE_OPTIONS.indexOf('--experimental-loader') !== -1 || process.env.NODE_OPTIONS.indexOf('--import') !== -1)) || @@ -56,6 +63,10 @@ exports.isESMApp = function isESMApp() { (process.execArgv[0].indexOf('--experimental-loader') !== -1 && process.execArgv[1].indexOf('esm-loader.mjs') !== -1) || (process.execArgv[0].indexOf('--import') !== -1 && process.execArgv[0].indexOf('esm-register.mjs') !== -1) || - (process.execArgv[0].indexOf('--import') !== -1 && process.execArgv[1].indexOf('esm-register.mjs') !== -1))) - ); + (process.execArgv[0].indexOf('--import') !== -1 && process.execArgv[1].indexOf('esm-register.mjs') !== -1))); + + // @ts-ignore + require.cache[cacheKey] = { exports: isESM }; + + return isESM; }; diff --git a/packages/core/src/tracing/hook.js b/packages/core/src/tracing/hook.js index fc305277b8..f644c76054 100644 --- a/packages/core/src/tracing/hook.js +++ b/packages/core/src/tracing/hook.js @@ -4,15 +4,43 @@ 'use strict'; -const { onModuleLoad: iitmOnModuleLoad } = require('../util/iitmHook'); -const { onModuleLoad: requireHookOnModuleLoad } = require('../util/requireHook'); +const iitmHook = require('../util/iitmHook'); +const requireHook = require('../util/requireHook'); +// eslint-disable-next-line import/no-useless-path-segments +const isESMApp = require('../tracing/esmSupportedVersion').isESMApp; -const pureEsmLibraries = ['square-calc']; +/* + * RequireHook + * + * Provides support for all CommonJS (CJS) modules in CJS applications, even if the CJS version of + * pureEsmLibraries is used in CJS apps. + * Also, extends support to all CommonJS (CJS) modules in ESM applications. + */ + +/* + * Import-in-the-middle + * + * Offers support for all native ECMAScript Modules listed in pureEsmLibraries within ESM applications + * (including both CJS and ESM versions) of pure ECMAScript Modules. + * However, it does not provide support for modules loaded from CJS apps. + */ -exports.onModuleLoad = (/** @type {string} */ module, /** @type {Function} */ fn, /** @type {boolean} */ esmAPP) => { - if (pureEsmLibraries.includes(module) && esmAPP) { - iitmOnModuleLoad(module, fn); +const pureEsmLibraries = ['square-calc']; +/** + * @param {string} moduleName + * @param {Function} fn + */ +exports.onModuleLoad = (moduleName, fn) => { + if (pureEsmLibraries.includes(moduleName) && isESMApp()) { + iitmHook.onModuleLoad(moduleName, fn); } else { - requireHookOnModuleLoad(module, fn); + requireHook.onModuleLoad(moduleName, fn); } }; +/** + * @param {RegExp} pattern + * @param {Function} fn + */ +exports.onFileLoad = (pattern, fn) => { + requireHook.onFileLoad(pattern, fn); +}; diff --git a/packages/core/src/tracing/index.js b/packages/core/src/tracing/index.js index 73b6d255fc..26be1ced63 100644 --- a/packages/core/src/tracing/index.js +++ b/packages/core/src/tracing/index.js @@ -130,6 +130,7 @@ exports.supportedVersion = supportedVersion; exports.util = tracingUtil; exports.esmSupportedVersion = esmSupportedVersion; exports.isLatestEsmSupportedVersion = isLatestEsmSupportedVersion; +exports.isESMApp = isESMApp; /** * @param {import('../util/normalizeConfig').InstanaConfig} cfg @@ -178,7 +179,6 @@ exports.init = function init(_config, downstreamConnection, _processIdentityProv 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' ); } - _config.esm = isESMApp(); config = _config; processIdentityProvider = _processIdentityProvider; diff --git a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/index.js b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/index.js index 86a65deea8..21f2800a8b 100644 --- a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/index.js +++ b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/index.js @@ -6,7 +6,7 @@ 'use strict'; const shimmer = require('../../../../shimmer'); -const requireHook = require('../../../../../util/requireHook'); +const hook = require('../../../../hook'); /** @type {Array. */ const awsProducts = [ @@ -34,7 +34,7 @@ exports.isActive = function () { }; exports.init = function init() { - requireHook.onModuleLoad('aws-sdk', instrumentAWS); + hook.onModuleLoad('aws-sdk', instrumentAWS); }; exports.activate = function activate() { diff --git a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/sdk.js b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/sdk.js index 7c44b4004a..d705c1feda 100644 --- a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/sdk.js +++ b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/sdk.js @@ -5,7 +5,7 @@ 'use strict'; -const requireHook = require('../../../../../util/requireHook'); +const hook = require('../../../../hook'); const constants = require('../../../../constants'); /** @@ -14,7 +14,7 @@ const constants = require('../../../../constants'); * (see https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html). */ exports.init = function init() { - requireHook.onFileLoad(/\/aws-sdk\/lib\/signers\/v4.js/, addInstanaHeadersToUnsignableHeaders); + hook.onFileLoad(/\/aws-sdk\/lib\/signers\/v4.js/, addInstanaHeadersToUnsignableHeaders); }; function addInstanaHeadersToUnsignableHeaders(v4SignerModule) { diff --git a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/sqs.js b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/sqs.js index a906e8b768..c521079373 100644 --- a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/sqs.js +++ b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v2/sqs.js @@ -15,7 +15,7 @@ const { readTracingAttributes } = require('../aws_utils'); const { ENTRY, EXIT, sqsAttributeNames } = require('../../../../constants'); -const requireHook = require('../../../../../util/requireHook'); +const hook = require('../../../../hook'); const tracingUtil = require('../../../../tracingUtil'); // Available call types to be sent into span.data.sqs.type @@ -40,8 +40,8 @@ let logger = require('../../../../../logger').getLogger('tracing/sqs/v2', newLog let isActive = false; exports.init = function init() { - requireHook.onModuleLoad('aws-sdk', instrumentSQS); - requireHook.onModuleLoad('sqs-consumer', instrumentSQSConsumer); + hook.onModuleLoad('aws-sdk', instrumentSQS); + hook.onModuleLoad('sqs-consumer', instrumentSQSConsumer); }; function instrumentSQS(AWS) { diff --git a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/index.js b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/index.js index d8441f0a33..406b307375 100644 --- a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/index.js +++ b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/index.js @@ -6,7 +6,7 @@ 'use strict'; const shimmer = require('../../../../shimmer'); -const requireHook = require('../../../../../util/requireHook'); +const hook = require('../../../../hook'); const { getFunctionArguments } = require('../../../../../util/function_arguments'); /** @type {Array. */ @@ -37,23 +37,23 @@ exports.init = function init() { sqsConsumer.init(); // NOTE: each aws product can have it's own init fn to wrap or unwrap specific functions - awsProducts.forEach(awsProduct => awsProduct.init && awsProduct.init(requireHook, shimmer)); + awsProducts.forEach(awsProduct => awsProduct.init && awsProduct.init(hook, shimmer)); /** * @aws-sdk/smithly-client >= 3.36.0 changed how the dist structure gets delivered * https://github.com/aws/aws-sdk-js-v3/blob/main/packages/smithy-client/CHANGELOG.md#3360-2021-10-08 * @aws-sdk/smithly-client is a subdependency of any @aws-sdk/* package */ - requireHook.onFileLoad(/@aws-sdk\/smithy-client\/dist-cjs\/client\.js/, instrumentGlobalSmithy); + hook.onFileLoad(/@aws-sdk\/smithy-client\/dist-cjs\/client\.js/, instrumentGlobalSmithy); /** * @aws-sdk/smithly-client < 3.36.0 */ - requireHook.onFileLoad(/@aws-sdk\/smithy-client\/dist\/cjs\/client\.js/, instrumentGlobalSmithy); + hook.onFileLoad(/@aws-sdk\/smithy-client\/dist\/cjs\/client\.js/, instrumentGlobalSmithy); /** * @aws-sdk/smithly-client > 3.36.0 */ - requireHook.onModuleLoad('@smithy/smithy-client', instrumentGlobalSmithy); + hook.onModuleLoad('@smithy/smithy-client', instrumentGlobalSmithy); }; exports.isActive = function () { diff --git a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/sqs-consumer.js b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/sqs-consumer.js index 26562c4d40..f44c7ad18b 100644 --- a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/sqs-consumer.js +++ b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/sqs-consumer.js @@ -5,11 +5,11 @@ 'use strict'; const shimmer = require('../../../../shimmer'); -const requireHook = require('../../../../../util/requireHook'); +const hook = require('../../../../hook'); const cls = require('../../../../cls'); function init() { - requireHook.onModuleLoad('sqs-consumer', instrument); + hook.onModuleLoad('sqs-consumer', instrument); } function instrument(SQSConsumer) { diff --git a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/sqs.js b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/sqs.js index 3aefd4c67a..62c2679cc5 100644 --- a/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/sqs.js +++ b/packages/core/src/tracing/instrumentation/cloud/aws-sdk/v3/sqs.js @@ -39,11 +39,11 @@ const operations = Object.keys(operationsInfo); const SPAN_NAME = 'sqs'; class InstanaAWSSQS extends InstanaAWSProduct { - init(requireHook, shimmer) { + init(hook, shimmer) { // < 3.481.0 // refs https://github.com/instana/nodejs/commit/6ae90e74fee5c47cc4ade67d21c4885d34c08847 // Background: sqs.receiveMessage returned a different promise than smithy.send (which is called internally) - requireHook.onFileLoad(/@aws-sdk\/client-sqs\/dist-cjs\/SQS\.js/, function (module) { + hook.onFileLoad(/@aws-sdk\/client-sqs\/dist-cjs\/SQS\.js/, function (module) { shimmer.wrap(module.SQS.prototype, 'receiveMessage', function (originalReceiveMsgFn) { return function instanaReceiveMessage() { return cls.ns.runAndReturn(() => { @@ -68,7 +68,7 @@ class InstanaAWSSQS extends InstanaAWSProduct { // >= 3.481 // https://github.com/aws/aws-sdk-js-v3/pull/5604 - requireHook.onFileLoad(/@aws-sdk\/client-sqs\/dist-cjs\/index\.js/, function (module) { + hook.onFileLoad(/@aws-sdk\/client-sqs\/dist-cjs\/index\.js/, function (module) { shimmer.wrap(module.SQS.prototype, 'receiveMessage', function (originalReceiveMsgFn) { return function instanaReceiveMessage() { return cls.ns.runAndReturn(() => { diff --git a/packages/core/src/tracing/instrumentation/cloud/azure/blob.js b/packages/core/src/tracing/instrumentation/cloud/azure/blob.js index d6c6f9e6eb..2ea0c4f65d 100644 --- a/packages/core/src/tracing/instrumentation/cloud/azure/blob.js +++ b/packages/core/src/tracing/instrumentation/cloud/azure/blob.js @@ -6,7 +6,7 @@ const shimmer = require('../../../shimmer'); -const requireHook = require('../../../../util/requireHook'); +const hook = require('../../../hook'); const tracingUtil = require('../../../tracingUtil'); const constants = require('../../../constants'); const cls = require('../../../cls'); @@ -16,7 +16,7 @@ let isActive = false; exports.spanName = 'azstorage'; exports.init = function init() { - requireHook.onModuleLoad('@azure/storage-blob', instrumentBlob); + hook.onModuleLoad('@azure/storage-blob', instrumentBlob); }; function instrumentBlob(blob) { diff --git a/packages/core/src/tracing/instrumentation/cloud/gcp/pubsub.js b/packages/core/src/tracing/instrumentation/cloud/gcp/pubsub.js index babe4933f7..456433038c 100644 --- a/packages/core/src/tracing/instrumentation/cloud/gcp/pubsub.js +++ b/packages/core/src/tracing/instrumentation/cloud/gcp/pubsub.js @@ -15,7 +15,7 @@ const { ENTRY, EXIT } = require('../../../constants'); -const requireHook = require('../../../../util/requireHook'); +const hook = require('../../../hook'); const tracingUtil = require('../../../tracingUtil'); let logger; @@ -28,8 +28,8 @@ const subscriptionRegex = /^projects\/([^/]+)\/subscriptions\/(.+)$/; let isActive = false; exports.init = function init() { - requireHook.onFileLoad(/\/@google-cloud\/pubsub\/build\/src\/publisher\/index.js/, instrumentPublisher); - requireHook.onFileLoad(/\/@google-cloud\/pubsub\/build\/src\/subscriber.js/, instrumentSubscriber); + hook.onFileLoad(/\/@google-cloud\/pubsub\/build\/src\/publisher\/index.js/, instrumentPublisher); + hook.onFileLoad(/\/@google-cloud\/pubsub\/build\/src\/subscriber.js/, instrumentSubscriber); }; function instrumentPublisher(publisher) { diff --git a/packages/core/src/tracing/instrumentation/cloud/gcp/storage.js b/packages/core/src/tracing/instrumentation/cloud/gcp/storage.js index 050a0641f8..7a118869e3 100644 --- a/packages/core/src/tracing/instrumentation/cloud/gcp/storage.js +++ b/packages/core/src/tracing/instrumentation/cloud/gcp/storage.js @@ -10,13 +10,13 @@ const shimmer = require('../../../shimmer'); const cls = require('../../../cls'); const constants = require('../../../constants'); -const requireHook = require('../../../../util/requireHook'); +const hook = require('../../../hook'); const tracingUtil = require('../../../tracingUtil'); let isActive = false; exports.init = function init() { - requireHook.onModuleLoad('@google-cloud/storage', instrument); + hook.onModuleLoad('@google-cloud/storage', instrument); }; const storageInstrumentations = [ diff --git a/packages/core/src/tracing/instrumentation/control_flow/bluebird.js b/packages/core/src/tracing/instrumentation/control_flow/bluebird.js index 43a289af6c..43f5a9b361 100644 --- a/packages/core/src/tracing/instrumentation/control_flow/bluebird.js +++ b/packages/core/src/tracing/instrumentation/control_flow/bluebird.js @@ -6,7 +6,7 @@ 'use strict'; const instrument = require('cls-bluebird'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const cls = require('../../cls'); exports.activate = function activate() { @@ -18,7 +18,7 @@ exports.deactivate = function deactivate() { }; exports.init = function init() { - requireHook.onModuleLoad('bluebird', patchBluebird); + hook.onModuleLoad('bluebird', patchBluebird); }; function patchBluebird(bluebirdModule) { diff --git a/packages/core/src/tracing/instrumentation/control_flow/clsHooked.js b/packages/core/src/tracing/instrumentation/control_flow/clsHooked.js index e89cecdf0d..8ef255d8bb 100644 --- a/packages/core/src/tracing/instrumentation/control_flow/clsHooked.js +++ b/packages/core/src/tracing/instrumentation/control_flow/clsHooked.js @@ -7,12 +7,12 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); let hasBeenPatched = false; exports.init = () => { - requireHook.onModuleLoad('cls-hooked', patchClsHooked); + hook.onModuleLoad('cls-hooked', patchClsHooked); }; // This module applies a patch to the cls-hooked module (https://github.com/Jeff-Lewis/cls-hooked/). This patch fixes a diff --git a/packages/core/src/tracing/instrumentation/control_flow/graphqlSubscriptions.js b/packages/core/src/tracing/instrumentation/control_flow/graphqlSubscriptions.js index dd2b7a079f..9faad9f4c5 100644 --- a/packages/core/src/tracing/instrumentation/control_flow/graphqlSubscriptions.js +++ b/packages/core/src/tracing/instrumentation/control_flow/graphqlSubscriptions.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const cls = require('../../cls'); let isActive = false; @@ -15,8 +15,8 @@ let isActive = false; const CLS_CONTEXT_SYMBOL = Symbol('_instana_cls_context'); exports.init = () => { - requireHook.onModuleLoad('graphql-subscriptions', instrumentModule); - requireHook.onFileLoad(/\/graphql-subscriptions\/dist\/pubsub-async-iterator\.js/, instrumentAsyncIterator); + hook.onModuleLoad('graphql-subscriptions', instrumentModule); + hook.onFileLoad(/\/graphql-subscriptions\/dist\/pubsub-async-iterator\.js/, instrumentAsyncIterator); }; function instrumentModule(graphQlSubscriptions) { diff --git a/packages/core/src/tracing/instrumentation/database/couchbase.js b/packages/core/src/tracing/instrumentation/database/couchbase.js index fcdfb4138c..1240d4c01b 100644 --- a/packages/core/src/tracing/instrumentation/database/couchbase.js +++ b/packages/core/src/tracing/instrumentation/database/couchbase.js @@ -5,7 +5,7 @@ 'use strict'; const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -24,7 +24,7 @@ exports.deactivate = function deactivate() { }; exports.init = function init() { - requireHook.onModuleLoad('couchbase', instrument); + hook.onModuleLoad('couchbase', instrument); // The couchbase client talks to some Couchbase services via http directly from the JS implementation. // e.g. search service diff --git a/packages/core/src/tracing/instrumentation/database/db2.js b/packages/core/src/tracing/instrumentation/database/db2.js index 7dd1507158..ff7da86dab 100644 --- a/packages/core/src/tracing/instrumentation/database/db2.js +++ b/packages/core/src/tracing/instrumentation/database/db2.js @@ -6,7 +6,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -18,7 +18,7 @@ const CLOSE_TIMEOUT_IN_MS = process.env.DB2_CLOSE_TIMEOUT_IN_MS || 1000 * 30; exports.spanName = 'ibmdb2'; exports.init = function init() { - requireHook.onModuleLoad('ibm_db', instrument); + hook.onModuleLoad('ibm_db', instrument); }; /** diff --git a/packages/core/src/tracing/instrumentation/database/elasticsearch.js b/packages/core/src/tracing/instrumentation/database/elasticsearch.js index 22d7df00b8..c41a37af51 100644 --- a/packages/core/src/tracing/instrumentation/database/elasticsearch.js +++ b/packages/core/src/tracing/instrumentation/database/elasticsearch.js @@ -8,7 +8,7 @@ const url = require('url'); const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -27,7 +27,7 @@ exports.spanName = 'elasticsearch'; exports.batchable = true; exports.init = function init() { - requireHook.onModuleLoad('@elastic/elasticsearch', instrument); + hook.onModuleLoad('@elastic/elasticsearch', instrument); }; const connectionUrlCache = {}; diff --git a/packages/core/src/tracing/instrumentation/database/ioredis.js b/packages/core/src/tracing/instrumentation/database/ioredis.js index eb6fad0888..0cb481f7c2 100644 --- a/packages/core/src/tracing/instrumentation/database/ioredis.js +++ b/packages/core/src/tracing/instrumentation/database/ioredis.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -26,7 +26,7 @@ exports.deactivate = function deactivate() { }; exports.init = function init() { - requireHook.onModuleLoad('ioredis', instrument); + hook.onModuleLoad('ioredis', instrument); }; function instrument(ioredis) { diff --git a/packages/core/src/tracing/instrumentation/database/memcached.js b/packages/core/src/tracing/instrumentation/database/memcached.js index be3642d240..67cc7bbbc9 100644 --- a/packages/core/src/tracing/instrumentation/database/memcached.js +++ b/packages/core/src/tracing/instrumentation/database/memcached.js @@ -10,7 +10,7 @@ const { EXIT } = require('../../constants'); const tracingUtil = require('../../tracingUtil'); const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const { getFunctionArguments } = require('../../../util/function_arguments'); const operationsInfo = { @@ -39,7 +39,7 @@ exports.isActive = function () { }; exports.init = function init() { - requireHook.onModuleLoad('memcached', instrumentMemcached); + hook.onModuleLoad('memcached', instrumentMemcached); }; exports.activate = function activate() { diff --git a/packages/core/src/tracing/instrumentation/database/mongodb.js b/packages/core/src/tracing/instrumentation/database/mongodb.js index 9a4bb22897..871fbea55e 100644 --- a/packages/core/src/tracing/instrumentation/database/mongodb.js +++ b/packages/core/src/tracing/instrumentation/database/mongodb.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -34,11 +34,11 @@ exports.batchable = true; exports.init = function init() { // unified topology layer - requireHook.onFileLoad(/\/mongodb\/lib\/cmap\/connection\.js/, instrumentCmapConnection); + hook.onFileLoad(/\/mongodb\/lib\/cmap\/connection\.js/, instrumentCmapConnection); // mongodb >= 3.3.x, legacy topology layer - requireHook.onFileLoad(/\/mongodb\/lib\/core\/connection\/pool\.js/, instrumentLegacyTopologyPool); + hook.onFileLoad(/\/mongodb\/lib\/core\/connection\/pool\.js/, instrumentLegacyTopologyPool); // mongodb < 3.3.x, legacy topology layer - requireHook.onFileLoad(/\/mongodb-core\/lib\/connection\/pool\.js/, instrumentLegacyTopologyPool); + hook.onFileLoad(/\/mongodb-core\/lib\/connection\/pool\.js/, instrumentLegacyTopologyPool); }; function instrumentCmapConnection(connection) { diff --git a/packages/core/src/tracing/instrumentation/database/mongoose.js b/packages/core/src/tracing/instrumentation/database/mongoose.js index f68d129531..1c6ce9941f 100644 --- a/packages/core/src/tracing/instrumentation/database/mongoose.js +++ b/packages/core/src/tracing/instrumentation/database/mongoose.js @@ -12,11 +12,11 @@ logger = require('../../../logger').getLogger('tracing/mongoose', newLogger => { logger = newLogger; }); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const cls = require('../../cls'); exports.init = function () { - requireHook.onModuleLoad('mongoose', exports.instrument); + hook.onModuleLoad('mongoose', exports.instrument); }; // This instruments the Aggregate object exported by Mongoose. The Mongoose library uses the standard MongoDB driver diff --git a/packages/core/src/tracing/instrumentation/database/mssql.js b/packages/core/src/tracing/instrumentation/database/mssql.js index c668461ab0..8dcbae9081 100644 --- a/packages/core/src/tracing/instrumentation/database/mssql.js +++ b/packages/core/src/tracing/instrumentation/database/mssql.js @@ -5,7 +5,7 @@ 'use strict'; -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -17,7 +17,7 @@ exports.spanName = 'mssql'; exports.batchable = true; exports.init = function init() { - requireHook.onModuleLoad('mssql', instrumentMssql); + hook.onModuleLoad('mssql', instrumentMssql); }; function instrumentMssql(mssql) { diff --git a/packages/core/src/tracing/instrumentation/database/mysql.js b/packages/core/src/tracing/instrumentation/database/mysql.js index 2507fc1dea..4a57898939 100644 --- a/packages/core/src/tracing/instrumentation/database/mysql.js +++ b/packages/core/src/tracing/instrumentation/database/mysql.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -18,9 +18,9 @@ exports.spanName = 'mysql'; exports.batchable = true; exports.init = function init() { - requireHook.onModuleLoad('mysql', instrumentMysql); - requireHook.onModuleLoad('mysql2', instrumentMysql2); - requireHook.onModuleLoad('mysql2/promise', instrumentMysql2WithPromises); + hook.onModuleLoad('mysql', instrumentMysql); + hook.onModuleLoad('mysql2', instrumentMysql2); + hook.onModuleLoad('mysql2/promise', instrumentMysql2WithPromises); }; function instrumentMysql(mysql) { diff --git a/packages/core/src/tracing/instrumentation/database/pg.js b/packages/core/src/tracing/instrumentation/database/pg.js index 6792674a31..3fe0f04de1 100644 --- a/packages/core/src/tracing/instrumentation/database/pg.js +++ b/packages/core/src/tracing/instrumentation/database/pg.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -18,7 +18,7 @@ exports.spanName = 'postgres'; exports.batchable = true; exports.init = function init() { - requireHook.onModuleLoad('pg', instrumentPg); + hook.onModuleLoad('pg', instrumentPg); }; function instrumentPg(pg) { diff --git a/packages/core/src/tracing/instrumentation/database/pgNative.js b/packages/core/src/tracing/instrumentation/database/pgNative.js index d3ffc44468..5a66dba417 100644 --- a/packages/core/src/tracing/instrumentation/database/pgNative.js +++ b/packages/core/src/tracing/instrumentation/database/pgNative.js @@ -8,7 +8,7 @@ const { LRUCache } = require('lru-cache'); const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -28,7 +28,7 @@ exports.spanName = 'postgres'; exports.batchable = true; exports.init = function init() { - requireHook.onModuleLoad('pg-native', instrumentPgNative); + hook.onModuleLoad('pg-native', instrumentPgNative); }; function instrumentPgNative(Client) { diff --git a/packages/core/src/tracing/instrumentation/database/prisma.js b/packages/core/src/tracing/instrumentation/database/prisma.js index d119dd00ba..34924409cf 100644 --- a/packages/core/src/tracing/instrumentation/database/prisma.js +++ b/packages/core/src/tracing/instrumentation/database/prisma.js @@ -11,7 +11,7 @@ logger = require('../../../logger').getLogger('tracing/prisma', newLogger => { logger = newLogger; }); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const { getErrorDetails, getStackTrace } = require('../../tracingUtil'); const { EXIT } = require('../../constants'); const cls = require('../../cls'); @@ -21,7 +21,7 @@ let isActive = false; const providerAndDataSourceUriMap = new WeakMap(); exports.init = function init() { - requireHook.onModuleLoad('@prisma/client', instrumentPrismaClient); + hook.onModuleLoad('@prisma/client', instrumentPrismaClient); }; function instrumentPrismaClient(prismaClientModule) { diff --git a/packages/core/src/tracing/instrumentation/database/redis.js b/packages/core/src/tracing/instrumentation/database/redis.js index 37ad207c03..2404ed6925 100644 --- a/packages/core/src/tracing/instrumentation/database/redis.js +++ b/packages/core/src/tracing/instrumentation/database/redis.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -27,8 +27,8 @@ exports.deactivate = function deactivate() { exports.init = function init() { // v4 commands, "redis-commands" is outdated and no longer compatible with it - requireHook.onFileLoad(/\/@redis\/client\/dist\/lib\/cluster\/commands.js/, captureCommands); - requireHook.onModuleLoad('redis', instrument); + hook.onFileLoad(/\/@redis\/client\/dist\/lib\/cluster\/commands.js/, captureCommands); + hook.onModuleLoad('redis', instrument); }; let redisCommandList = []; diff --git a/packages/core/src/tracing/instrumentation/frameworks/express.js b/packages/core/src/tracing/instrumentation/frameworks/express.js index f737d7ca86..91f14577d7 100644 --- a/packages/core/src/tracing/instrumentation/frameworks/express.js +++ b/packages/core/src/tracing/instrumentation/frameworks/express.js @@ -8,7 +8,7 @@ const shimmer = require('../../shimmer'); const methods = require('methods'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const httpServer = require('../protocols/httpServer'); const cls = require('../../cls'); @@ -24,7 +24,7 @@ exports.deactivate = function deactivate() { }; exports.init = function init() { - requireHook.onModuleLoad('express', instrument); + hook.onModuleLoad('express', instrument); }; function instrument(express) { diff --git a/packages/core/src/tracing/instrumentation/frameworks/fastify.js b/packages/core/src/tracing/instrumentation/frameworks/fastify.js index 2356b98e2f..162af4573b 100644 --- a/packages/core/src/tracing/instrumentation/frameworks/fastify.js +++ b/packages/core/src/tracing/instrumentation/frameworks/fastify.js @@ -5,7 +5,7 @@ 'use strict'; -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const httpServer = require('../protocols/httpServer'); const cls = require('../../cls'); let logger = require('../../../logger').getLogger('tracing/fastify', newLogger => { @@ -23,7 +23,7 @@ exports.deactivate = function deactivate() { }; exports.init = function init() { - requireHook.onModuleLoad('fastify', instrument); + hook.onModuleLoad('fastify', instrument); }; /** diff --git a/packages/core/src/tracing/instrumentation/frameworks/hapi.js b/packages/core/src/tracing/instrumentation/frameworks/hapi.js index 64eb8978fe..671f5f4b0f 100644 --- a/packages/core/src/tracing/instrumentation/frameworks/hapi.js +++ b/packages/core/src/tracing/instrumentation/frameworks/hapi.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const httpServer = require('../protocols/httpServer'); const cls = require('../../cls'); @@ -19,7 +19,7 @@ logger = require('../../../logger').getLogger('tracing/hapi', newLogger => { let isActive = false; exports.init = function init() { - requireHook.onModuleLoad('@hapi/call', instrumentHapiCall); + hook.onModuleLoad('@hapi/call', instrumentHapiCall); }; function instrumentHapiCall(hapiCall) { diff --git a/packages/core/src/tracing/instrumentation/frameworks/koa.js b/packages/core/src/tracing/instrumentation/frameworks/koa.js index 639d517ca5..8bea94ffb6 100644 --- a/packages/core/src/tracing/instrumentation/frameworks/koa.js +++ b/packages/core/src/tracing/instrumentation/frameworks/koa.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const httpServer = require('../protocols/httpServer'); const cls = require('../../cls'); @@ -22,7 +22,7 @@ exports.deactivate = function deactivate() { }; exports.init = function init() { - requireHook.onModuleLoad('koa-router', instrumentRouter); + hook.onModuleLoad('koa-router', instrumentRouter); }; function instrumentRouter(Router) { diff --git a/packages/core/src/tracing/instrumentation/loggers/bunyan.js b/packages/core/src/tracing/instrumentation/loggers/bunyan.js index 555f3ff315..d1e8292c9c 100644 --- a/packages/core/src/tracing/instrumentation/loggers/bunyan.js +++ b/packages/core/src/tracing/instrumentation/loggers/bunyan.js @@ -9,7 +9,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -17,7 +17,7 @@ const cls = require('../../cls'); let isActive = false; exports.init = function init() { - requireHook.onModuleLoad('bunyan', instrument); + hook.onModuleLoad('bunyan', instrument); }; function instrument(Logger) { diff --git a/packages/core/src/tracing/instrumentation/loggers/log4js.js b/packages/core/src/tracing/instrumentation/loggers/log4js.js index 8a9ed5bd4d..a4dcb4ff12 100644 --- a/packages/core/src/tracing/instrumentation/loggers/log4js.js +++ b/packages/core/src/tracing/instrumentation/loggers/log4js.js @@ -8,7 +8,7 @@ const util = require('util'); const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -18,8 +18,8 @@ let isActive = false; let levels; exports.init = function init() { - requireHook.onFileLoad(/\/log4js\/lib\/levels\.js/, saveLevelsRef); - requireHook.onFileLoad(/\/log4js\/lib\/logger\.js/, instrumentLog4jsLogger); + hook.onFileLoad(/\/log4js\/lib\/levels\.js/, saveLevelsRef); + hook.onFileLoad(/\/log4js\/lib\/logger\.js/, instrumentLog4jsLogger); }; function saveLevelsRef(levelsModule) { diff --git a/packages/core/src/tracing/instrumentation/loggers/pino.js b/packages/core/src/tracing/instrumentation/loggers/pino.js index d4a89971ab..8939fb6758 100644 --- a/packages/core/src/tracing/instrumentation/loggers/pino.js +++ b/packages/core/src/tracing/instrumentation/loggers/pino.js @@ -10,7 +10,7 @@ const { inspect } = require('util'); const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -18,7 +18,7 @@ const cls = require('../../cls'); let isActive = false; exports.init = function init() { - requireHook.onFileLoad(/\/pino\/lib\/tools\.js/, instrumentPinoTools); + hook.onFileLoad(/\/pino\/lib\/tools\.js/, instrumentPinoTools); }; function instrumentPinoTools(toolsModule) { diff --git a/packages/core/src/tracing/instrumentation/loggers/winston.js b/packages/core/src/tracing/instrumentation/loggers/winston.js index 138fc46711..bbe2d31710 100644 --- a/packages/core/src/tracing/instrumentation/loggers/winston.js +++ b/packages/core/src/tracing/instrumentation/loggers/winston.js @@ -5,7 +5,7 @@ 'use strict'; -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -14,9 +14,9 @@ let isActive = false; exports.init = function init() { // Winston 2.x - requireHook.onFileLoad(/\/winston\/lib\/winston\/logger\.js/, instrumentWinston2); + hook.onFileLoad(/\/winston\/lib\/winston\/logger\.js/, instrumentWinston2); // Winston >= 3.x - requireHook.onFileLoad(/\/winston\/lib\/winston\/create-logger\.js/, instrumentWinston3); + hook.onFileLoad(/\/winston\/lib\/winston\/create-logger\.js/, instrumentWinston3); }; function instrumentWinston2(loggerModule) { diff --git a/packages/core/src/tracing/instrumentation/messaging/amqp.js b/packages/core/src/tracing/instrumentation/messaging/amqp.js index 13736c923b..eeec0d8357 100644 --- a/packages/core/src/tracing/instrumentation/messaging/amqp.js +++ b/packages/core/src/tracing/instrumentation/messaging/amqp.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -20,9 +20,9 @@ logger = require('../../../logger').getLogger('tracing/amqp', newLogger => { let isActive = false; exports.init = function init() { - requireHook.onFileLoad(/\/amqplib\/lib\/channel\.js/, instrumentChannel); - requireHook.onFileLoad(/\/amqplib\/lib\/channel_model\.js/, instrumentChannelModel); - requireHook.onFileLoad(/\/amqplib\/lib\/callback_model\.js/, instrumentCallbackModel); + hook.onFileLoad(/\/amqplib\/lib\/channel\.js/, instrumentChannel); + hook.onFileLoad(/\/amqplib\/lib\/channel_model\.js/, instrumentChannelModel); + hook.onFileLoad(/\/amqplib\/lib\/callback_model\.js/, instrumentCallbackModel); }; function instrumentChannel(channelModule) { diff --git a/packages/core/src/tracing/instrumentation/messaging/bull.js b/packages/core/src/tracing/instrumentation/messaging/bull.js index f70c6a1714..c58130b649 100644 --- a/packages/core/src/tracing/instrumentation/messaging/bull.js +++ b/packages/core/src/tracing/instrumentation/messaging/bull.js @@ -8,7 +8,7 @@ const shimmer = require('../../shimmer'); const cls = require('../../cls'); const { ENTRY, EXIT } = require('../../constants'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const { getFunctionArguments } = require('../../../util/function_arguments'); @@ -21,7 +21,7 @@ let isActive = false; exports.spanName = 'bull'; exports.init = function init() { - requireHook.onModuleLoad('bull', instrumentBull); + hook.onModuleLoad('bull', instrumentBull); }; function instrumentBull(Bull) { diff --git a/packages/core/src/tracing/instrumentation/messaging/kafkaJs.js b/packages/core/src/tracing/instrumentation/messaging/kafkaJs.js index a783dd6523..d326229f0d 100644 --- a/packages/core/src/tracing/instrumentation/messaging/kafkaJs.js +++ b/packages/core/src/tracing/instrumentation/messaging/kafkaJs.js @@ -5,7 +5,7 @@ 'use strict'; -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const { limitTraceId } = require('../../tracingHeaders'); const leftPad = require('../../leftPad'); @@ -23,8 +23,8 @@ let headerFormat = constants.kafkaHeaderFormatDefault; let isActive = false; exports.init = function init(config) { - requireHook.onFileLoad(/\/kafkajs\/src\/producer\/messageProducer\.js/, instrumentProducer); - requireHook.onFileLoad(/\/kafkajs\/src\/consumer\/runner\.js/, instrumentConsumer); + hook.onFileLoad(/\/kafkajs\/src\/producer\/messageProducer\.js/, instrumentProducer); + hook.onFileLoad(/\/kafkajs\/src\/consumer\/runner\.js/, instrumentConsumer); traceCorrelationEnabled = config.tracing.kafka.traceCorrelation; headerFormat = config.tracing.kafka.headerFormat; }; diff --git a/packages/core/src/tracing/instrumentation/messaging/kafkaNode.js b/packages/core/src/tracing/instrumentation/messaging/kafkaNode.js index 201dc3b967..e84acc89ff 100644 --- a/packages/core/src/tracing/instrumentation/messaging/kafkaNode.js +++ b/packages/core/src/tracing/instrumentation/messaging/kafkaNode.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -22,7 +22,7 @@ let isActive = false; // FYI: officially deprecated. No release since 4 years. But still very // high usage on npm trends. We will drop in 4.x v4. exports.init = function init() { - requireHook.onModuleLoad('kafka-node', instrument); + hook.onModuleLoad('kafka-node', instrument); }; function instrument(kafka) { diff --git a/packages/core/src/tracing/instrumentation/messaging/nats.js b/packages/core/src/tracing/instrumentation/messaging/nats.js index 37dc5bf46d..d6c81626e7 100644 --- a/packages/core/src/tracing/instrumentation/messaging/nats.js +++ b/packages/core/src/tracing/instrumentation/messaging/nats.js @@ -7,7 +7,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -17,7 +17,7 @@ let clientHasBeenInstrumentedV1 = false; let clientHasBeenInstrumentedV2 = false; exports.init = function init() { - requireHook.onModuleLoad('nats', instrumentNats); + hook.onModuleLoad('nats', instrumentNats); }; let natsModule; diff --git a/packages/core/src/tracing/instrumentation/messaging/natsStreaming.js b/packages/core/src/tracing/instrumentation/messaging/natsStreaming.js index d60ef077bb..684e2abb23 100644 --- a/packages/core/src/tracing/instrumentation/messaging/natsStreaming.js +++ b/packages/core/src/tracing/instrumentation/messaging/natsStreaming.js @@ -10,7 +10,7 @@ const shimmer = require('../../shimmer'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -19,7 +19,7 @@ let isActive = false; let clientHasBeenInstrumented = false; exports.init = function init() { - requireHook.onModuleLoad('node-nats-streaming', instrumentNatsStreaming); + hook.onModuleLoad('node-nats-streaming', instrumentNatsStreaming); }; function instrumentNatsStreaming(natsStreamingModule) { diff --git a/packages/core/src/tracing/instrumentation/messaging/rdkafka.js b/packages/core/src/tracing/instrumentation/messaging/rdkafka.js index 3e340e05d4..9d7e6d949b 100644 --- a/packages/core/src/tracing/instrumentation/messaging/rdkafka.js +++ b/packages/core/src/tracing/instrumentation/messaging/rdkafka.js @@ -4,7 +4,7 @@ 'use strict'; -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const { limitTraceId } = require('../../tracingHeaders'); const leftPad = require('../../leftPad'); @@ -23,9 +23,9 @@ logger = require('../../../logger').getLogger('tracing/rdkafka', newLogger => { let isActive = false; exports.init = function init(config) { - requireHook.onFileLoad(/\/node-rdkafka\/lib\/producer\.js/, instrumentProducer); - requireHook.onFileLoad(/\/node-rdkafka\/lib\/kafka-consumer-stream\.js/, instrumentConsumerAsStream); - requireHook.onModuleLoad('node-rdkafka', instrumentConsumer); + hook.onFileLoad(/\/node-rdkafka\/lib\/producer\.js/, instrumentProducer); + hook.onFileLoad(/\/node-rdkafka\/lib\/kafka-consumer-stream\.js/, instrumentConsumerAsStream); + hook.onModuleLoad('node-rdkafka', instrumentConsumer); traceCorrelationEnabled = config.tracing.kafka.traceCorrelation; configHeader = config.tracing.kafka.headerFormat; diff --git a/packages/core/src/tracing/instrumentation/process/memored.js b/packages/core/src/tracing/instrumentation/process/memored.js index 3494caf55c..8f4ffe31b4 100644 --- a/packages/core/src/tracing/instrumentation/process/memored.js +++ b/packages/core/src/tracing/instrumentation/process/memored.js @@ -5,13 +5,13 @@ 'use strict'; -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const cls = require('../../cls'); let isActive = false; exports.init = function init() { - requireHook.onFileLoad(/\/memored\/index.js/, instrumentMemored); + hook.onFileLoad(/\/memored\/index.js/, instrumentMemored); }; // This instruments a dependency of edgemicro that usually lives in diff --git a/packages/core/src/tracing/instrumentation/protocols/graphql.js b/packages/core/src/tracing/instrumentation/protocols/graphql.js index 2ac3707c99..5f1354ac07 100644 --- a/packages/core/src/tracing/instrumentation/protocols/graphql.js +++ b/packages/core/src/tracing/instrumentation/protocols/graphql.js @@ -12,7 +12,7 @@ logger = require('../../../logger').getLogger('tracing/graphql', newLogger => { logger = newLogger; }); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -27,9 +27,9 @@ const operationTypes = [queryOperationType, mutationOperationType, subscriptionO const subscriptionUpdate = 'subscription-update'; exports.init = function init() { - requireHook.onFileLoad(/\/graphql\/execution\/execute.js/, instrumentExecute); - requireHook.onFileLoad(/\/@apollo\/gateway\/dist\/executeQueryPlan.js/, instrumentApolloGatewayExecuteQueryPlan); - requireHook.onModuleLoad('@apollo/federation', logDeprecatedWarning); + hook.onFileLoad(/\/graphql\/execution\/execute.js/, instrumentExecute); + hook.onFileLoad(/\/@apollo\/gateway\/dist\/executeQueryPlan.js/, instrumentApolloGatewayExecuteQueryPlan); + hook.onModuleLoad('@apollo/federation', logDeprecatedWarning); }; function instrumentExecute(executeModule) { diff --git a/packages/core/src/tracing/instrumentation/protocols/grpcJs.js b/packages/core/src/tracing/instrumentation/protocols/grpcJs.js index 6cf06deeb9..e0c413b0b6 100644 --- a/packages/core/src/tracing/instrumentation/protocols/grpcJs.js +++ b/packages/core/src/tracing/instrumentation/protocols/grpcJs.js @@ -11,7 +11,7 @@ logger = require('../../../logger').getLogger('tracing/grpcjs', newLogger => { logger = newLogger; }); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const tracingUtil = require('../../tracingUtil'); const constants = require('../../constants'); const cls = require('../../cls'); @@ -31,9 +31,9 @@ const TYPES_WITH_CALLBACK = [TYPES.UNARY, TYPES.CLIENT_STREAM]; const TYPES_WITH_CALL_END = [TYPES.SERVER_STREAM, TYPES.BIDI]; exports.init = function () { - requireHook.onModuleLoad('@grpc/grpc-js', instrumentModule); - requireHook.onFileLoad(/\/@grpc\/grpc-js\/build\/src\/server\.js/, instrumentServer); - requireHook.onFileLoad(/\/@grpc\/grpc-js\/build\/src\/client\.js/, instrumentClient); + hook.onModuleLoad('@grpc/grpc-js', instrumentModule); + hook.onFileLoad(/\/@grpc\/grpc-js\/build\/src\/server\.js/, instrumentServer); + hook.onFileLoad(/\/@grpc\/grpc-js\/build\/src\/client\.js/, instrumentClient); }; function instrumentModule(grpc) { diff --git a/packages/core/src/tracing/instrumentation/protocols/httpClient.js b/packages/core/src/tracing/instrumentation/protocols/httpClient.js index 2c498d6754..d9506e804b 100644 --- a/packages/core/src/tracing/instrumentation/protocols/httpClient.js +++ b/packages/core/src/tracing/instrumentation/protocols/httpClient.js @@ -19,7 +19,7 @@ const { const constants = require('../../constants'); const cls = require('../../cls'); const url = require('url'); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); let logger; logger = require('../../../logger').getLogger('tracing/httpClient', newLogger => { logger = newLogger; @@ -32,7 +32,7 @@ exports.init = function init(config) { instrument(coreHttpModule, false); instrument(coreHttpsModule, true); extraHttpHeadersToCapture = config.tracing.http.extraHttpHeadersToCapture; - requireHook.onModuleLoad('request', logDeprecatedWarning); + hook.onModuleLoad('request', logDeprecatedWarning); }; function logDeprecatedWarning() { logger.warn( diff --git a/packages/core/src/tracing/instrumentation/protocols/superagent.js b/packages/core/src/tracing/instrumentation/protocols/superagent.js index 7bcdecc31d..aa05e58bb7 100644 --- a/packages/core/src/tracing/instrumentation/protocols/superagent.js +++ b/packages/core/src/tracing/instrumentation/protocols/superagent.js @@ -13,11 +13,11 @@ logger = require('../../../logger').getLogger('tracing/superagent', newLogger => logger = newLogger; }); -const requireHook = require('../../../util/requireHook'); +const hook = require('../../hook'); const cls = require('../../cls'); exports.init = function () { - requireHook.onModuleLoad('superagent', exports.instrument); + hook.onModuleLoad('superagent', exports.instrument); }; // This instruments the Request object exported by superagent. The superagent library uses Node.js' http/https/http2 diff --git a/packages/core/src/tracing/instrumentation/test/squareCalc.js b/packages/core/src/tracing/instrumentation/test/squareCalc.js index 2ed148ac6b..fa8921c8f0 100644 --- a/packages/core/src/tracing/instrumentation/test/squareCalc.js +++ b/packages/core/src/tracing/instrumentation/test/squareCalc.js @@ -4,17 +4,13 @@ 'use strict'; -/* eslint-disable no-unused-vars */ -const shimmer = require('../../shimmer'); const { EXIT } = require('../../constants'); const tracingUtil = require('../../tracingUtil'); const cls = require('../../cls'); const hook = require('../../hook'); - +// eslint-disable-next-line no-unused-vars let active = false; -/* eslint-disable no-console */ - exports.activate = function activate() { active = true; }; @@ -24,19 +20,18 @@ exports.deactivate = function deactivate() { }; exports.init = function init() { - const esmAPP = arguments[0].esm; - hook.onModuleLoad('square-calc', instrument, esmAPP); + hook.onModuleLoad('square-calc', instrument); }; /** - * @param {{ calculateSquare: (...args: any[]) => undefined; }} orgModule + * Instruments the 'calculateSquare' method of the 'square-calc' module. + * @param {{ calculateSquare: (...args: any[]) => undefined; }} orgModule - The original module. */ function instrument(orgModule) { const originalCalculateSquare = orgModule; orgModule = function () { const number = arguments[0]; - console.log(`Calculating the square of ${number}`); return cls.ns.runAndReturn(() => { const span = cls.startSpan('square-calc', EXIT, null, null); @@ -48,7 +43,7 @@ function instrument(orgModule) { span.d = Date.now() - span.ts; span.data.calculator = { number, method: 'calculateSquare' }; span.transmit(); - return 10; + return result; } catch (err) { span.ec = 1; span.data.calculator.error = err.message; diff --git a/packages/core/src/util/applicationUnderMonitoring.js b/packages/core/src/util/applicationUnderMonitoring.js index 1f8cef8115..2c584282fa 100644 --- a/packages/core/src/util/applicationUnderMonitoring.js +++ b/packages/core/src/util/applicationUnderMonitoring.js @@ -7,6 +7,8 @@ const fs = require('../uninstrumentedFs'); const path = require('path'); +// eslint-disable-next-line import/no-useless-path-segments +const isESMApp = require('../tracing/esmSupportedVersion').isESMApp; /** @type {import('../logger').GenericLogger} */ let logger; @@ -166,18 +168,7 @@ function getMainPackageJsonPathStartingAtDirectory(startDirectory, cb) { if ( // @ts-ignore (process._preload_modules && process._preload_modules.length > 0) || - (process.env.NODE_OPTIONS && - (process.env.NODE_OPTIONS.indexOf('--experimental-loader') !== -1 || - process.env.NODE_OPTIONS.indexOf('--import') !== -1)) || - (process.execArgv && - process.execArgv.length > 0 && - ((process.execArgv[0].indexOf('--experimental-loader') !== -1 && - process.execArgv[0].indexOf('esm-loader.mjs')) !== -1 || - (process.execArgv[0].indexOf('--experimental-loader') !== -1 && - process.execArgv[1].indexOf('esm-loader.mjs') !== -1) || - (process.execArgv[0].indexOf('--import') !== -1 && process.execArgv[0].indexOf('esm-register.mjs')) !== - -1 || - (process.execArgv[0].indexOf('--import') !== -1 && process.execArgv[1].indexOf('esm-register.mjs') !== -1))) + isESMApp() ) { // @ts-ignore mainModule = { diff --git a/packages/core/src/util/iitmHook.js b/packages/core/src/util/iitmHook.js index 721355d52b..fbcbae4e51 100644 --- a/packages/core/src/util/iitmHook.js +++ b/packages/core/src/util/iitmHook.js @@ -11,27 +11,27 @@ let logger = require('../logger').getLogger('util/iitmHook', newLogger => { logger = newLogger; }); -/** @type {Object.} */ +/** @type {Object.} */ const byModuleNameTransformers = {}; +/** + * Initializes the import-in-the-middle hooking. + */ exports.init = function init() { - // eslint-disable-next-line no-restricted-syntax - for (const [moduleName, applicableTransformers] of Object.entries(byModuleNameTransformers)) { + Object.entries(byModuleNameTransformers).forEach(([moduleName, applicableTransformers]) => { if (applicableTransformers) { - for (let i = 0; i < applicableTransformers.length; i++) { - const transformerFn = applicableTransformers[i]; + applicableTransformers.forEach(transformerFn => { if (typeof transformerFn === 'function') { try { // @ts-ignore - // eslint-disable-next-line no-loop-func - iitmHook([moduleName], (exports, name, basedir) => { - logger.info(`Hooking enabled for module ${name} in base directory ${basedir}`); + iitmHook([moduleName], (exports, name) => { + logger.debug(`iitm-hooking enabled for module ${name}`); if (exports && exports.default) { exports.default = transformerFn(exports.default); - return exports; } else { return transformerFn(exports); } + return exports; }); } catch (e) { logger.error(`Cannot instrument ${moduleName} due to an error in instrumentation: ${e}`); @@ -46,21 +46,19 @@ exports.init = function init() { logger.error( `The transformer is not a function but of type "${typeof transformerFn}" (details: ${ transformerFn == null ? 'null/undefined' : transformerFn - // eslint-disable-next-line no-useless-concat - }). ` + "The most likely cause is that something has messed with Node.js' module cache." + }).` ); } - } + }); } - } + }); }; /** - * Add a transformer function for a specific module. - * @param {string} moduleName - * @param {Function} transfornFn + * @param {string} moduleName - The name of the module. + * @param {Function} transformFn - The transformer function. */ -exports.onModuleLoad = function onModuleLoad(moduleName, transfornFn) { +exports.onModuleLoad = function onModuleLoad(moduleName, transformFn) { byModuleNameTransformers[moduleName] = byModuleNameTransformers[moduleName] || []; - byModuleNameTransformers[moduleName].push(transfornFn); + byModuleNameTransformers[moduleName].push(transformFn); }; diff --git a/packages/core/src/util/initializedTooLateHeuristic.js b/packages/core/src/util/initializedTooLateHeuristic.js index 01f27516ae..e72e82fd98 100644 --- a/packages/core/src/util/initializedTooLateHeuristic.js +++ b/packages/core/src/util/initializedTooLateHeuristic.js @@ -68,7 +68,8 @@ let patterns = [ /\/superagent\/lib\/node\/index.js/, /\/@smithy\/smithy-client\//, /\/request\/index.js/, - /\/@apollo\/federation\/dist\// + /\/@apollo\/federation\/dist\//, + /\/square-calc\/index.mjs/ ]; const extraPatterns = [ diff --git a/packages/core/src/util/normalizeConfig.js b/packages/core/src/util/normalizeConfig.js index 10093a6fe1..3dc8bcc5a3 100644 --- a/packages/core/src/util/normalizeConfig.js +++ b/packages/core/src/util/normalizeConfig.js @@ -59,7 +59,6 @@ const constants = require('../tracing/constants'); * @property {InstanaTracingOption} [tracing] * @property {InstanaSecretsOption} [secrets] * @property {number} [timeBetweenHealthcheckCalls] - * @property {boolean} [esm] */ /** diff --git a/packages/core/src/util/requireHook.js b/packages/core/src/util/requireHook.js index d5c932dd5e..24e81dbf86 100644 --- a/packages/core/src/util/requireHook.js +++ b/packages/core/src/util/requireHook.js @@ -57,7 +57,7 @@ function patchedModuleLoad(moduleName) { // CASE: when using ESM, the Node runtime passes a full path to Module._load // We aim to extract the module name to apply our instrumentation. // CASE: we ignore all file endings, which we are not interested in. Any module can load any file. - // CASE: Native ESM support is still pending, and the requireHook is not compatible with native ESM. + // CASE: The requireHook is not compatible with native ESM so the native ESM is not handled here. // However, starting from version 12, the 'got' module is transitioning to a pure ESM module but // continues to function. This is because 'got' is instrumented coincidentally with the 'http' module. // The instrumentation of 'http' and 'https' works without the requireHook. @@ -67,7 +67,9 @@ function patchedModuleLoad(moduleName) { // where we require 'http' and 'https' at the top. Native ESM libraries that import core Node modules // (e.g., import http from 'node:http') do not trigger Module._load, hence do not use the requireHook. // However, when an ESM library imports a CommonJS package, our requireHook is triggered. + // For native ESM libraries the iitmHook is triggered. if (path.isAbsolute(moduleName) && ['.node', '.json', '.ts'].indexOf(path.extname(moduleName)) === -1) { + // EDGE CASE for ESM: mysql2/promise.js if (moduleName.indexOf('node_modules/mysql2/promise.js') !== -1) { moduleName = 'mysql2/promise'; } else { diff --git a/packages/google-cloud-run/esm-loader.mjs b/packages/google-cloud-run/esm-loader.mjs index 87eb0881eb..956d382d92 100644 --- a/packages/google-cloud-run/esm-loader.mjs +++ b/packages/google-cloud-run/esm-loader.mjs @@ -24,3 +24,6 @@ */ import './src/index.js'; +// Here we exports all named exports from '@instana/core/iitm-loader.mjs', enabling +// integration of import-in-the-middle (IITM) for Native ESM module support. +export * from '@instana/core/iitm-loader.mjs'; diff --git a/packages/google-cloud-run/esm-register.mjs b/packages/google-cloud-run/esm-register.mjs index 97e5f564d2..168a8b439d 100644 --- a/packages/google-cloud-run/esm-register.mjs +++ b/packages/google-cloud-run/esm-register.mjs @@ -8,7 +8,7 @@ * see https://github.com/nodejs/node/pull/44710. * Previously, loading the Instana collector within the loader and after the update ESM support * no longer working with v18.19 and above. To address this, we've opted to load the Instana - * collector in the main thread using --import. Additionally, we aim to incorporate native ESM + * collector in the main thread using --import. Additionally, we incorporated native ESM * support by utilizing the node register method, enabling customization of the ESM loader * with 'import-in-the-middle'. * @@ -19,7 +19,8 @@ // Import the initialization module for google-cloud-run collector; it self-initializes upon import // and it should be executed in the main thread. import './src/index.js'; - -// We plan to utilize this for adding native ESM support in the near future -// import { register } from 'node:module'; -// register(./loader.mjs, import.meta.url); +import { register } from 'node:module'; +// ESM module resolution and loading are facilitated by registering `@instana/core/iitm-loader.mjs`, which exports +// import-in-the-middle(IITM) hooks. This registration can be accomplished using the register method from node:module. +// see: https://nodejs.org/api/module.html#customization-hooks +register('@instana/core/iitm-loader.mjs', import.meta.url);