diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f291bb01fa..52448cb364 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -374,18 +374,11 @@ REGIONS= SKIP_DOCKER_IMAGE=true BUILD_LAYER_WITH=local LAYER_NAME=experi We have added the ESM support for all Node.js versions, Since version 20.6, [ESM loaders are off-thread](https://github.com/nodejs/node/pull/44710), loaded separately, a shift from previous setups where the Instana collector was loaded within the loader, leading to a disruption in existing implementation. To resolve this, we've replaced the deprecated `--experimental-loader` with `--import`, facilitating the loading of the collector in the main thread. However, note that `--import` is only compatible with Node.js v18.19 and later, necessitating the maintenance of both styles for different Node.js versions. -Use the following command to enable experimental ESM support: - -- For Node.js versions greater than or equal to 18.19: +Use the following command to enable ESM support: ```sh node --import /path/to/instana/node_modules/@instana/collector/esm-register.mjs entry-point ``` -- For Node.js versions less than 18.19: - -```sh -node --experimental-loader /path/to/instana/node_modules/@instana/collector/esm-loader.mjs entry-point -``` ## Node.js prerelease diff --git a/packages/aws-fargate/esm-loader.mjs b/packages/aws-fargate/esm-loader.mjs index f0962b70a6..bf4aaeb404 100644 --- a/packages/aws-fargate/esm-loader.mjs +++ b/packages/aws-fargate/esm-loader.mjs @@ -5,6 +5,8 @@ 'use strict'; /** + * IMPORTANT: This file is deprecated, no longer supported, and will be removed in the next major release (v6). + * * IMPORTANT NOTE: From Node.js version 18.19 and above, the ESM loaders operate off-thread. * Consequently, ESM instrumentation using '--experimental-loader' becomes deprecated. * Instead, we are using '--import' for loading instrumentation and relocated the Instana collector diff --git a/packages/aws-fargate/src/preactivate.js b/packages/aws-fargate/src/preactivate.js index af1e6b5d9b..8c442370bb 100644 --- a/packages/aws-fargate/src/preactivate.js +++ b/packages/aws-fargate/src/preactivate.js @@ -5,18 +5,45 @@ 'use strict'; -const { isNodeJsTooOld, minimumNodeJsVersion } = require('@instana/core/src/util/nodeJsVersionCheck'); +const { esm, nodeJsVersionCheck } = require('@instana/core/src/util'); -if (isNodeJsTooOld()) { +if (nodeJsVersionCheck.isNodeJsTooOld()) { // eslint-disable-next-line no-console console.error( - `The package @instana/aws-fargate requires at least Node.js ${minimumNodeJsVersion} but this process is ` + + // eslint-disable-next-line max-len + `The package @instana/aws-fargate requires at least Node.js ${nodeJsVersionCheck.minimumNodeJsVersion} but this process is ` + `running on Node.js ${process.version}. This Fargate container will not be monitored by Instana.` + 'See https://www.ibm.com/docs/en/instana-observability/current?topic=agents-aws-fargate#versioning.' ); return; } +// Check for unsupported ESM loader configurations and exit early +if (esm.hasExperimentalLoaderFlag()) { + // eslint-disable-next-line no-console + console.error( + "Node.js 18.19.0 and later no longer support the '--experimental-loader' flag for ESM. " + + `Your current version is ${process.version}. To ensure tracing by Instana, ` + + "please use the '--import' flag instead. For more information, refer to the Instana documentation: " + + 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' + ); + return; +} + +// This loader worked with '--experimental-loader' in Node.js versions below 18.19. +// TODO: Remove 'esm-loader.mjs' file and this log in the next major release (v6). +if (esm.hasEsmLoaderFile()) { + // eslint-disable-next-line no-console + console.error( + "Importing 'esm-loader.mjs' is not supported and will be removed in next major release. " + + 'This process will not be monitored by Instana. ' + + "Use 'esm-register.mjs' with '--import' to enable tracing. For more information, " + + 'refer to the Instana documentation: ' + + 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' + ); + return; +} + const { util: coreUtil } = require('@instana/core'); const { environment: environmentUtil, consoleLogger: serverlessLogger } = require('@instana/serverless'); diff --git a/packages/aws-fargate/test/Control.js b/packages/aws-fargate/test/Control.js index de10e80e60..b5bd260f7a 100644 --- a/packages/aws-fargate/test/Control.js +++ b/packages/aws-fargate/test/Control.js @@ -13,7 +13,6 @@ const config = require('@instana/core/test/config'); const AbstractServerlessControl = require('../../serverless/test/util/AbstractServerlessControl'); const portfinder = require('../../collector/test/test_util/portfinder'); const PATH_TO_INSTANA_FARGATE_PACKAGE = path.join(__dirname, '..'); -const isLatestEsmSupportedVersion = require('@instana/core').util.esm.isLatestEsmSupportedVersion; let execArg; function Control(opts) { @@ -99,9 +98,7 @@ Control.prototype.startMonitoredProcess = function startMonitoredProcess() { env.INSTANA_AGENT_KEY = this.instanaAgentKey; } - const loaderPath = isLatestEsmSupportedVersion(process.versions.node) - ? ['--import', `${path.join(__dirname, '..', 'esm-register.mjs')}`] - : [`--experimental-loader=${path.join(__dirname, '..', 'esm-loader.mjs')}`]; + const loaderPath = ['--import', `${path.join(__dirname, '..', 'esm-register.mjs')}`]; if (this.opts.containerAppPath && this.opts.env && this.opts.env.ESM_TEST) { if (this.opts.containerAppPath.endsWith('.mjs')) { diff --git a/packages/azure-container-services/esm-loader.mjs b/packages/azure-container-services/esm-loader.mjs index 06178f22b9..57ceb4eb75 100644 --- a/packages/azure-container-services/esm-loader.mjs +++ b/packages/azure-container-services/esm-loader.mjs @@ -5,6 +5,8 @@ 'use strict'; /** + * IMPORTANT: This file is deprecated, no longer supported, and will be removed in the next major release (v6). + * * IMPORTANT NOTE: From Node.js version 18.19 and above, the ESM loaders operate off-thread. * Consequently, ESM instrumentation using '--experimental-loader' becomes deprecated. * Instead, we are using '--import' for loading instrumentation and relocated the Instana collector diff --git a/packages/azure-container-services/src/index.js b/packages/azure-container-services/src/index.js index 1b490c87d6..f4cd448d2b 100644 --- a/packages/azure-container-services/src/index.js +++ b/packages/azure-container-services/src/index.js @@ -4,21 +4,47 @@ 'use strict'; -const { isNodeJsTooOld, minimumNodeJsVersion } = require('@instana/core/src/util/nodeJsVersionCheck'); +const { esm, nodeJsVersionCheck } = require('@instana/core/src/util'); // As of now, Azure App Service supports Node.js versions 16-lts,18-lts and 20-lts. However, for existing services, // older Node.js versions might still be supported. You can find more information about configuring Node.js on Azure // App Service at: https://learn.microsoft.com/en-us/azure/app-service/configure-language-nodejs?pivots=platform-linux -if (isNodeJsTooOld()) { +if (nodeJsVersionCheck.isNodeJsTooOld()) { // eslint-disable-next-line no-console console.error( - `The package @instana/azure-container-services requires at least Node.js ${minimumNodeJsVersion} but this` + + // eslint-disable-next-line max-len + `The package @instana/azure-container-services requires at least Node.js ${nodeJsVersionCheck.minimumNodeJsVersion} but this` + `process is running on Node.js ${process.version}. This azure container service will not be monitored by Instana.` ); return; } +if (esm.hasExperimentalLoaderFlag()) { + // eslint-disable-next-line no-console + console.error( + "Node.js 18.19.0 and later no longer support the '--experimental-loader' flag for ESM. " + + `Your current version is ${process.version}. To ensure tracing by Instana, ` + + "please use the '--import' flag instead. For more information, refer to the Instana documentation: " + + 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' + ); + return; +} + +// This loader worked with '--experimental-loader' in Node.js versions below 18.19. +// TODO: Remove 'esm-loader.mjs' file and this log in the next major release (v6). +if (esm.hasEsmLoaderFile()) { + // eslint-disable-next-line no-console + console.error( + "Importing 'esm-loader.mjs' is not supported and will be removed in next major release. " + + 'This process will not be monitored by Instana. ' + + "Use 'esm-register.mjs' with '--import' to enable tracing. For more information, " + + 'refer to the Instana documentation: ' + + 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' + ); + return; +} + const { util: coreUtil } = require('@instana/core'); const { environment: environmentUtil, consoleLogger: log } = require('@instana/serverless'); diff --git a/packages/azure-container-services/test/Control.js b/packages/azure-container-services/test/Control.js index f62c82d7b7..a562ab3850 100644 --- a/packages/azure-container-services/test/Control.js +++ b/packages/azure-container-services/test/Control.js @@ -10,7 +10,6 @@ const fetch = require('node-fetch-v2'); const portfinder = require('@instana/collector/test/test_util/portfinder'); const config = require('@instana/core/test/config'); const AbstractServerlessControl = require('../../serverless/test/util/AbstractServerlessControl'); -const isLatestEsmSupportedVersion = require('@instana/core').util.esm.isLatestEsmSupportedVersion; const PATH_TO_INSTANA_AZURE_PACKAGE = path.join(__dirname, '..'); let execArg; @@ -59,9 +58,7 @@ class Control extends AbstractServerlessControl { env.INSTANA_AGENT_KEY = this.instanaAgentKey; } - const loaderPath = isLatestEsmSupportedVersion(process.versions.node) - ? ['--import', `${path.join(__dirname, '..', 'esm-register.mjs')}`] - : [`--experimental-loader=${path.join(__dirname, '..', 'esm-loader.mjs')}`]; + const loaderPath = ['--import', `${path.join(__dirname, '..', 'esm-register.mjs')}`]; if (this.opts.containerAppPath && this.opts.env && this.opts.env.ESM_TEST) { execArg = this.opts.containerAppPath.endsWith('.mjs') ? loaderPath : ['--require', PATH_TO_INSTANA_AZURE_PACKAGE]; diff --git a/packages/collector/esm-loader.mjs b/packages/collector/esm-loader.mjs index cc6fb4b346..9072bc53c6 100644 --- a/packages/collector/esm-loader.mjs +++ b/packages/collector/esm-loader.mjs @@ -5,6 +5,8 @@ 'use strict'; /** + * IMPORTANT: This file is deprecated, no longer supported, and will be removed in the next major release (v6). + * * IMPORTANT NOTE: From Node.js version 18.19 and above, the ESM loaders operate off-thread. * Consequently, ESM instrumentation using '--experimental-loader' becomes deprecated. * Instead, we are using '--import' for loading instrumentation and relocated the Instana collector diff --git a/packages/collector/src/index.js b/packages/collector/src/index.js index 7b40eaa7ae..dd800b2f92 100644 --- a/packages/collector/src/index.js +++ b/packages/collector/src/index.js @@ -5,7 +5,7 @@ 'use strict'; -const { isNodeJsTooOld, minimumNodeJsVersion } = require('@instana/core/src/util/nodeJsVersionCheck'); +const { esm, nodeJsVersionCheck } = require('@instana/core/src/util'); const { isProcessAvailable } = require('@instana/core/src/util/moduleAvailable'); if (!isProcessAvailable()) { @@ -20,10 +20,11 @@ if (!isProcessAvailable()) { return; } -if (isNodeJsTooOld()) { +if (nodeJsVersionCheck.isNodeJsTooOld()) { // eslint-disable-next-line no-console console.error( - `The package @instana/collector requires at least Node.js ${minimumNodeJsVersion} but this process is ` + + // eslint-disable-next-line max-len + `The package @instana/collector requires at least Node.js ${nodeJsVersionCheck.minimumNodeJsVersion} but this process is ` + `running on Node.js ${process.version}. This process will not be monitored by Instana.` ); @@ -34,6 +35,36 @@ if (isNodeJsTooOld()) { return; } +// v18.19 and above usage of --experimental-loader flag no longer supported +// TODO: Remove error log in the next major release(v6) +if (esm.hasExperimentalLoaderFlag()) { + // eslint-disable-next-line no-console + console.error( + "Node.js 18.19.0 and later no longer support the '--experimental-loader' flag for ESM. " + + `Your current version is ${process.version}. To ensure tracing by Instana, ` + + "please use the '--import' flag instead. For more information, refer to the Instana documentation: " + + 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' + ); + module.exports.default = function noOp() {}; + // @ts-ignore TS1108 + return; +} + +// This loader worked with '--experimental-loader' in Node.js versions below 18.19. +// TODO: Remove 'esm-loader.mjs' file and this log in the next major release (v6). +if (esm.hasEsmLoaderFile()) { + // eslint-disable-next-line no-console + console.error( + "Importing 'esm-loader.mjs' is not supported and will be removed in next major release. " + + 'This process will not be monitored by Instana. ' + + "Use 'esm-register.mjs' with '--import' to enable tracing. For more information, " + + 'refer to the Instana documentation: ' + + 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' + ); + module.exports.default = function noOp() {}; + // @ts-ignore TS1108 + return; +} let isMainThread = true; try { isMainThread = require('worker_threads').isMainThread; diff --git a/packages/collector/test/test_util/ProcessControls.js b/packages/collector/test/test_util/ProcessControls.js index 43de07e843..3d4774a607 100644 --- a/packages/collector/test/test_util/ProcessControls.js +++ b/packages/collector/test/test_util/ProcessControls.js @@ -20,7 +20,6 @@ const globalAgent = require('../globalAgent'); const portFinder = require('./portfinder'); const sslDir = path.join(__dirname, '..', 'apps', 'ssl'); const cert = fs.readFileSync(path.join(sslDir, 'cert')); -const isLatestEsmSupportedVersion = require('@instana/core').util.esm.isLatestEsmSupportedVersion; class ProcessControls { /** @@ -57,10 +56,7 @@ class ProcessControls { } if (process.env.RUN_ESM && !opts.execArgv) { - const resolveEsmLoader = () => - isLatestEsmSupportedVersion(process.versions.node) - ? [`--import=${path.join(__dirname, '..', '..', 'esm-register.mjs')}`] - : [`--experimental-loader=${path.join(__dirname, '..', '..', 'esm-loader.mjs')}`]; + const esmLoader = [`--import=${path.join(__dirname, '..', '..', 'esm-register.mjs')}`]; try { // Custom appPath is provided, use that. here we check the exact file name for esm app @@ -72,13 +68,13 @@ class ProcessControls { const esmApp = testUtils.checkESMApp({ appPath: updatedPath }); if (esmApp) { - opts.execArgv = resolveEsmLoader(); + opts.execArgv = esmLoader; opts.appPath = updatedPath; } } else if (opts?.dirname) { const esmApp = testUtils.checkESMApp({ appPath: path.join(opts.dirname, 'app.mjs') }); if (esmApp) { - opts.execArgv = resolveEsmLoader(); + opts.execArgv = esmLoader; opts.appPath = path.join(opts.dirname, 'app.mjs'); } } diff --git a/packages/collector/test/tracing/misc/typescript/ts_esm/ts_esm_test.js b/packages/collector/test/tracing/misc/typescript/ts_esm/ts_esm_test.js index 8f52c78640..cc6d2756cc 100644 --- a/packages/collector/test/tracing/misc/typescript/ts_esm/ts_esm_test.js +++ b/packages/collector/test/tracing/misc/typescript/ts_esm/ts_esm_test.js @@ -9,16 +9,13 @@ const path = require('path'); const { execSync } = require('child_process'); const config = require('../../../../../../core/test/config'); const testUtils = require('../../../../../../core/test/test_util'); -const isLatestEsmSupportedVersion = require('../../../../../../core').util.esm.isLatestEsmSupportedVersion; const supportedVersion = require('../../../../../../core').tracing.supportedVersion; const ProcessControls = require('../../../../test_util/ProcessControls'); const globalAgent = require('../../../../globalAgent'); const mochaSuiteFn = supportedVersion(process.versions.node) ? describe : describe.skip; -const loaderPath = isLatestEsmSupportedVersion(process.versions.node) - ? ['--import', path.join(__dirname, 'node_modules', '@instana', 'collector', 'esm-register.mjs')] - : ['--experimental-loader', path.join(__dirname, 'node_modules', '@instana', 'collector', 'esm-loader.mjs')]; +const loaderPath = ['--import', path.join(__dirname, 'node_modules', '@instana', 'collector', 'esm-register.mjs')]; mochaSuiteFn('Typescript TS->ESM', function () { this.timeout(config.getTestTimeout() * 5); diff --git a/packages/collector/test/tracing/sdk/multiple_installations/esm/test.js b/packages/collector/test/tracing/sdk/multiple_installations/esm/test.js index 9944c824ed..696b05f37b 100644 --- a/packages/collector/test/tracing/sdk/multiple_installations/esm/test.js +++ b/packages/collector/test/tracing/sdk/multiple_installations/esm/test.js @@ -15,7 +15,6 @@ const config = require('@instana/core/test/config'); const testUtils = require('@instana/core/test/test_util'); const ProcessControls = require('../../../../test_util/ProcessControls'); const globalAgent = require('../../../../globalAgent'); -const isLatestEsmSupportedVersion = require('@instana/core').util.esm.isLatestEsmSupportedVersion; const mochaSuiteFn = supportedVersion(process.versions.node) ? describe : describe.skip; mochaSuiteFn('[ESM] tracing/sdk/multiple_installations', function () { @@ -40,9 +39,7 @@ mochaSuiteFn('[ESM] tracing/sdk/multiple_installations', function () { let controls; before(async () => { - const nodeOptions = isLatestEsmSupportedVersion(process.versions.node) - ? '--import ./load-instana.mjs' - : '--experimental-loader ./load-instana.mjs'; + const nodeOptions = '--import ./load-instana.mjs'; controls = new ProcessControls({ useGlobalAgent: true, cwd: path.join(__dirname, 'src'), diff --git a/packages/core/src/tracing/index.js b/packages/core/src/tracing/index.js index cf572ed838..f8afdb00fa 100644 --- a/packages/core/src/tracing/index.js +++ b/packages/core/src/tracing/index.js @@ -183,17 +183,6 @@ exports.init = function init(_config, downstreamConnection, _processIdentityProv console.debug(`The App is using the following preload flags: ${preloadFlags}`); } - // Consider removing this in the next major release of the @instana package. - if (coreUtil.esm.hasExperimentalLoaderFlag()) { - // eslint-disable-next-line no-console - console.warn( - 'Node.js introduced breaking changes in versions 18.19.0 and above, leading to the discontinuation of support ' + - `for the --experimental-loader flag by Instana. The current Node.js version is ${process.version}. ` + - "To ensure tracing by Instana, please use the '--import' flag instead. For more information, " + - 'refer to the Instana documentation: ' + - 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' - ); - } config = _config; processIdentityProvider = _processIdentityProvider; diff --git a/packages/core/src/util/esm.js b/packages/core/src/util/esm.js index ea6dd4a6b1..329b8fae90 100644 --- a/packages/core/src/util/esm.js +++ b/packages/core/src/util/esm.js @@ -4,31 +4,27 @@ 'use strict'; -const semver = require('semver'); - -/** - * Check if the given Node.js version is the latest version that supports ESM. - * @param {string} version - The Node.js version to check. - * @returns {boolean} - True if the version is the latest that supports ESM, false otherwise. - */ -exports.isLatestEsmSupportedVersion = function isLatestEsmSupportedVersion(version) { - // Reference: https://nodejs.org/en/blog/release/v18.19.0#esm-and-customization-hook-changes - // Node.js v18.19 and above the loaders are off threaded - // https://instana.slack.com/archives/G0118PFNN20/p1708556683665099 - return semver.gte(version, '18.19.0'); -}; - /** * Check if the experimental loader flag is enabled and if the current Node.js version supports it. * @returns {boolean} - True if the experimental loader is enabled and supported, false otherwise. * Node.js v18.19 and above we are not supporting --experimental-loader flag */ exports.hasExperimentalLoaderFlag = function hasExperimentalLoaderFlag() { - const experimentalLoaderFlagIsSet = + return !!( (process.env.NODE_OPTIONS && process.env.NODE_OPTIONS.includes('--experimental-loader')) || - (process.execArgv[0] && process.execArgv[0].includes('--experimental-loader')); + (process.execArgv[0] && process.execArgv[0].includes('--experimental-loader')) + ); +}; - return experimentalLoaderFlagIsSet && exports.isLatestEsmSupportedVersion(process.versions.node); +/** + * Check if esm-loader.mjs is being used. + * @returns {boolean} - True if esm-loader.mjs is present in Node options or execArgv, false otherwise. + */ +exports.hasEsmLoaderFile = function hasEsmLoaderFile() { + return !!( + (process.env.NODE_OPTIONS && process.env.NODE_OPTIONS.includes('esm-loader.mjs')) || + process.execArgv.some(arg => arg.includes('esm-loader.mjs')) + ); }; /** diff --git a/packages/core/src/util/index.js b/packages/core/src/util/index.js index b23e116bc9..b47cf8ab62 100644 --- a/packages/core/src/util/index.js +++ b/packages/core/src/util/index.js @@ -22,6 +22,7 @@ const preloadFlags = require('./getPreloadFlags'); const spanFilter = require('./spanFilter'); const yamlReader = require('./yamlReader'); const disableInstrumentation = require('./disableInstrumentation'); +const nodeJsVersionCheck = require('./nodeJsVersionCheck'); /** @type {import('@instana/core/src/core').GenericLogger} */ let logger; @@ -97,3 +98,4 @@ exports.esm = esm; exports.spanFilter = spanFilter; exports.yamlReader = yamlReader; exports.disableInstrumentation = disableInstrumentation; +exports.nodeJsVersionCheck = nodeJsVersionCheck; diff --git a/packages/core/test/util/esm_test.js b/packages/core/test/util/esm_test.js new file mode 100644 index 0000000000..6863795811 --- /dev/null +++ b/packages/core/test/util/esm_test.js @@ -0,0 +1,57 @@ +/* + * (c) Copyright IBM Corp. 2025 + */ + +'use strict'; + +const expect = require('chai').expect; +const { hasExperimentalLoaderFlag, hasEsmLoaderFile } = require('../../src/util/esm'); + +describe('util.esm', () => { + afterEach(() => { + delete process.env.NODE_OPTIONS; + }); + + describe('hasExperimentalLoaderFlag', () => { + it('should return true when --experimental-loader is in NODE_OPTIONS', () => { + process.env.NODE_OPTIONS = '--experimental-loader ./loader.mjs'; + expect(hasExperimentalLoaderFlag()).to.be.true; + }); + + it('should return false when --experimental-loader is not present', () => { + delete process.env.NODE_OPTIONS; + expect(hasExperimentalLoaderFlag()).to.be.false; + }); + + it('should return false when NODE_OPTIONS has other flags', () => { + process.env.NODE_OPTIONS = '--max-old-space-size=4096'; + expect(hasExperimentalLoaderFlag()).to.be.false; + }); + }); + + describe('hasEsmLoaderFile', () => { + it('should return true when esm-loader.mjs is in NODE_OPTIONS', () => { + process.env.NODE_OPTIONS = '--experimental-loader ./esm-loader.mjs'; + expect(hasEsmLoaderFile()).to.be.true; + }); + + it('should return true when esm-loader.mjs is in NODE_OPTIONS with other flags', () => { + process.env.NODE_OPTIONS = '--max-old-space-size=4096 --experimental-loader./esm-loader.mjs'; + expect(hasEsmLoaderFile()).to.be.true; + }); + + it('should return false when NODE_OPTIONS is not set', () => { + expect(hasEsmLoaderFile()).to.be.false; + }); + + it('should return false when NODE_OPTIONS has other loader files', () => { + process.env.NODE_OPTIONS = '--import ./esm-register.mjs'; + expect(hasEsmLoaderFile()).to.be.false; + }); + + it('should return false when NODE_OPTIONS is empty', () => { + process.env.NODE_OPTIONS = ''; + expect(hasEsmLoaderFile()).to.be.false; + }); + }); +}); diff --git a/packages/google-cloud-run/esm-loader.mjs b/packages/google-cloud-run/esm-loader.mjs index f760b891c3..8a6594edc5 100644 --- a/packages/google-cloud-run/esm-loader.mjs +++ b/packages/google-cloud-run/esm-loader.mjs @@ -5,6 +5,8 @@ 'use strict'; /** + * IMPORTANT: This file is deprecated, no longer supported, and will be removed in the next major release (v6). + * * IMPORTANT NOTE: From Node.js version 18.19 and above, the ESM loaders operate off-thread. * Consequently, ESM instrumentation using '--experimental-loader' becomes deprecated. * Instead, we are using '--import' for loading instrumentation and relocated the Instana collector diff --git a/packages/google-cloud-run/src/preactivate.js b/packages/google-cloud-run/src/preactivate.js index 2e20d6df5f..c4683b093c 100644 --- a/packages/google-cloud-run/src/preactivate.js +++ b/packages/google-cloud-run/src/preactivate.js @@ -5,18 +5,45 @@ 'use strict'; -const { isNodeJsTooOld, minimumNodeJsVersion } = require('@instana/core/src/util/nodeJsVersionCheck'); +const { esm, nodeJsVersionCheck } = require('@instana/core/src/util'); -if (isNodeJsTooOld()) { +if (nodeJsVersionCheck.isNodeJsTooOld()) { // eslint-disable-next-line no-console console.error( - `The package @instana/google-cloud-run requires at least Node.js ${minimumNodeJsVersion} but this process is ` + + // eslint-disable-next-line max-len + `The package @instana/google-cloud-run requires at least Node.js ${nodeJsVersionCheck.minimumNodeJsVersion} but this process is ` + `running on Node.js ${process.version}. This Google Cloud Run service will not be monitored by Instana.` + 'See https://www.ibm.com/docs/en/instana-observability/current?topic=agents-google-cloud-run#versioning.' ); return; } +// Check for unsupported ESM loader configurations and exit early +if (esm.hasExperimentalLoaderFlag()) { + // eslint-disable-next-line no-console + console.error( + "Node.js 18.19.0 and later no longer support the '--experimental-loader' flag for ESM. " + + `Your current version is ${process.version}. To ensure tracing by Instana, ` + + "please use the '--import' flag instead. For more information, refer to the Instana documentation: " + + 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' + ); + return; +} + +// This loader worked with '--experimental-loader' in Node.js versions below 18.19. +// TODO: Remove 'esm-loader.mjs' file and this log in the next major release (v6). +if (esm.hasEsmLoaderFile()) { + // eslint-disable-next-line no-console + console.error( + "Importing 'esm-loader.mjs' is not supported and will be removed in next major release. " + + 'This process will not be monitored by Instana. ' + + "Use 'esm-register.mjs' with '--import' to enable tracing. For more information, " + + 'refer to the Instana documentation: ' + + 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' + ); + return; +} + const { util: coreUtil } = require('@instana/core'); const { environment: environmentUtil, consoleLogger: serverlessLogger } = require('@instana/serverless'); diff --git a/packages/google-cloud-run/test/Control.js b/packages/google-cloud-run/test/Control.js index 2480d4846f..903439bee7 100644 --- a/packages/google-cloud-run/test/Control.js +++ b/packages/google-cloud-run/test/Control.js @@ -12,7 +12,6 @@ const fetch = require('node-fetch-v2'); const portfinder = require('@instana/collector/test/test_util/portfinder'); const config = require('@instana/core/test/config'); const AbstractServerlessControl = require('../../serverless/test/util/AbstractServerlessControl'); -const isLatestEsmSupportedVersion = require('@instana/core').util.esm.isLatestEsmSupportedVersion; const PATH_TO_INSTANA_GOOGLE_CLOUD_RUN_PACKAGE = path.join(__dirname, '..'); function Control(opts) { @@ -90,9 +89,7 @@ Control.prototype.startMonitoredProcess = function startMonitoredProcess() { env.INSTANA_AGENT_KEY = this.instanaAgentKey; } - const loaderPath = isLatestEsmSupportedVersion(process.versions.node) - ? ['--import', `${path.join(__dirname, '..', 'esm-register.mjs')}`] - : [`--experimental-loader=${path.join(__dirname, '..', 'esm-loader.mjs')}`]; + const loaderPath = ['--import', `${path.join(__dirname, '..', 'esm-register.mjs')}`]; if (!this.opts.containerAppPath && this.opts.env && this.opts.env.ESM_TEST) { if (this.opts.containerAppPath.endsWith('.mjs')) { diff --git a/packages/serverless-collector/esm-loader.mjs b/packages/serverless-collector/esm-loader.mjs index 9f845d5c67..a5889e5cdd 100644 --- a/packages/serverless-collector/esm-loader.mjs +++ b/packages/serverless-collector/esm-loader.mjs @@ -5,6 +5,8 @@ 'use strict'; /** + * IMPORTANT: This file is deprecated, no longer supported, and will be removed in the next major release (v6). + * * IMPORTANT NOTE: From Node.js version 18.19 and above, the ESM loaders operate off-thread. * Consequently, ESM instrumentation using '--experimental-loader' becomes deprecated. * Instead, we are using '--import' for loading instrumentation and relocated the Instana collector diff --git a/packages/serverless-collector/src/index.js b/packages/serverless-collector/src/index.js index 0c738d7109..05071d4460 100644 --- a/packages/serverless-collector/src/index.js +++ b/packages/serverless-collector/src/index.js @@ -4,17 +4,44 @@ 'use strict'; -const { isNodeJsTooOld, minimumNodeJsVersion } = require('@instana/core/src/util/nodeJsVersionCheck'); +const { esm, nodeJsVersionCheck } = require('@instana/core/src/util'); -if (isNodeJsTooOld()) { +if (nodeJsVersionCheck.isNodeJsTooOld()) { // eslint-disable-next-line no-console console.error( - `The package @instana/serverless-collector requires at least Node.js v${minimumNodeJsVersion} but this ` + + // eslint-disable-next-line max-len + `The package @instana/serverless-collector requires at least Node.js v${nodeJsVersionCheck.minimumNodeJsVersion} but this ` + `process is running on Node.js ${process.version}. This process will not be traced by Instana.` ); return; } +// Check for unsupported ESM loader configurations and exit early +if (esm.hasExperimentalLoaderFlag()) { + // eslint-disable-next-line no-console + console.error( + "Node.js 18.19.0 and later no longer support the '--experimental-loader' flag for ESM. " + + `Your current version is ${process.version}. To ensure tracing by Instana, ` + + "please use the '--import' flag instead. For more information, refer to the Instana documentation: " + + 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' + ); + return; +} + +// This loader worked with '--experimental-loader' in Node.js versions below 18.19. +// TODO: Remove 'esm-loader.mjs' file and this log in the next major release (v6). +if (esm.hasEsmLoaderFile()) { + // eslint-disable-next-line no-console + console.error( + "Importing 'esm-loader.mjs' is not supported and will be removed in next major release. " + + 'This process will not be monitored by Instana. ' + + "Use 'esm-register.mjs' with '--import' to enable tracing. For more information, " + + 'refer to the Instana documentation: ' + + 'https://www.ibm.com/docs/en/instana-observability/current?topic=nodejs-collector-installation.' + ); + return; +} + const { util: coreUtil } = require('@instana/core'); const { environment: environmentUtil, consoleLogger: serverlessLogger } = require('@instana/serverless'); diff --git a/packages/serverless-collector/test/Control.js b/packages/serverless-collector/test/Control.js index 97fd9d1d91..fed7424fa7 100644 --- a/packages/serverless-collector/test/Control.js +++ b/packages/serverless-collector/test/Control.js @@ -10,7 +10,6 @@ const fetch = require('node-fetch-v2'); const portfinder = require('@instana/collector/test/test_util/portfinder'); const config = require('@instana/core/test/config'); const AbstractServerlessControl = require('../../serverless/test/util/AbstractServerlessControl'); -const isLatestEsmSupportedVersion = require('@instana/core').util.esm.isLatestEsmSupportedVersion; const SERVERLESS_COLLECTOR_PATH = path.join(__dirname, '..'); let execArg; @@ -60,9 +59,7 @@ class Control extends AbstractServerlessControl { env.INSTANA_AGENT_KEY = this.instanaAgentKey; } - const loaderPath = isLatestEsmSupportedVersion(process.versions.node) - ? ['--import', `${path.join(__dirname, '..', 'esm-register.mjs')}`] - : [`--experimental-loader=${path.join(__dirname, '..', 'esm-loader.mjs')}`]; + const loaderPath = ['--import', `${path.join(__dirname, '..', 'esm-register.mjs')}`]; if (this.opts.containerAppPath && this.opts.env && this.opts.env.ESM_TEST) { execArg = this.opts.containerAppPath.endsWith('.mjs') ? loaderPath : ['--require', SERVERLESS_COLLECTOR_PATH]; diff --git a/packages/shared-metrics/test/esm-loader/test.js b/packages/shared-metrics/test/esm-loader/test.js index eaa05498b0..d416443f78 100644 --- a/packages/shared-metrics/test/esm-loader/test.js +++ b/packages/shared-metrics/test/esm-loader/test.js @@ -10,12 +10,10 @@ const expect = require('chai').expect; const { supportedVersion } = require('@instana/core').tracing; const testUtils = require('@instana/core/test/test_util'); const config = require('@instana/core/test/config'); -const isLatestEsmSupportedVersion = require('@instana/core').util.esm.isLatestEsmSupportedVersion; const ProcessControls = require('../../../collector/test/test_util/ProcessControls'); -const loaderPath = isLatestEsmSupportedVersion(process.versions.node) - ? ['--import', '../../../../collector/esm-register.mjs'] - : ['--experimental-loader=../../../../collector/esm-loader.mjs']; +const loaderPath = ['--import', '../../../../collector/esm-register.mjs']; + const mochaSuiteFn = supportedVersion(process.versions.node) ? describe : describe.skip; mochaSuiteFn('ESM loader', function () { @@ -121,9 +119,8 @@ mochaSuiteFn('ESM loader', function () { describe('case 4 (NODE_OPTIONS)', function () { this.timeout(config.getTestTimeout()); let controls; - const nodeOption = isLatestEsmSupportedVersion(process.versions.node) - ? '--import ../../../../collector/esm-register.mjs' - : '--experimental-loader=../../../../collector/esm-loader.mjs'; + const nodeOption = '--import ../../../../collector/esm-register.mjs'; + before(async () => { controls = new ProcessControls({ env: {