diff --git a/packages/collector/src/announceCycle/agentready.js b/packages/collector/src/announceCycle/agentready.js index 62c89dfd58..eac9745ac3 100644 --- a/packages/collector/src/announceCycle/agentready.js +++ b/packages/collector/src/announceCycle/agentready.js @@ -147,7 +147,6 @@ function enter(_ctx) { } logger.info('The Instana Node.js collector is now fully initialized and connected to the Instana host agent.'); - // CASE: This is an IPC message only for a parent process. // TODO: Add an EventEmitter functionality for the current process // such as `instana.on('instana.collector.initialized')`. diff --git a/packages/collector/test/tracing/misc/cjs-via-esm/app.js b/packages/collector/test/tracing/misc/cjs-via-esm/app.js new file mode 100644 index 0000000000..e960129b48 --- /dev/null +++ b/packages/collector/test/tracing/misc/cjs-via-esm/app.js @@ -0,0 +1,42 @@ +/* + * (c) Copyright IBM Corp. 2025 + */ + +'use strict'; + +// NOTE: c8 bug https://github.com/bcoe/c8/issues/166 +process.on('SIGTERM', () => { + process.disconnect(); + process.exit(0); +}); + +const logPrefix = `CJS via ESM (${process.pid}):\t`; +const port = require('../../../test_util/app-port')(); +const express = require('express'); +const bodyParser = require('body-parser'); +const pinoLogger = require('pino')(); + +const app = express(); +app.use(bodyParser.json()); + +app.get('/', (req, res) => { + res.sendStatus(200); +}); + +app.get('/trigger', async (req, res) => { + log('Received request'); + await fetch(`http://localhost:${port}`); + pinoLogger.error('wtf'); + res.json({ success: true }); +}); + +app.listen(port, () => { + log(`Listening on port: ${port}`); +}); + +function log() { + /* eslint-disable no-console */ + const args = Array.prototype.slice.call(arguments); + args[0] = logPrefix + args[0]; + console.log.apply(console, args); +} diff --git a/packages/collector/test/tracing/misc/cjs-via-esm/test.js b/packages/collector/test/tracing/misc/cjs-via-esm/test.js new file mode 100644 index 0000000000..0d316d8ee6 --- /dev/null +++ b/packages/collector/test/tracing/misc/cjs-via-esm/test.js @@ -0,0 +1,67 @@ +/* + * (c) Copyright IBM Corp. 2025 + */ + +'use strict'; + +const semver = require('semver'); +const path = require('path'); +const expect = require('chai').expect; +const supportedVersion = require('@instana/core').tracing.supportedVersion; +const ProcessControls = require('../../../test_util/ProcessControls'); +const globalAgent = require('../../../globalAgent'); +const { retry } = require('../../../../../core/test/test_util'); + +const mochaSuiteFn = + supportedVersion(process.versions.node) && semver.gte(process.versions.node, '18.19.0') ? describe : describe.skip; + +mochaSuiteFn('tracing/cjs-via-esm', function () { + this.timeout(1000 * 60); + globalAgent.setUpCleanUpHooks(); + + let controls; + const agentControls = globalAgent.instance; + + before(async () => { + const rootFolder = path.join(__dirname, '..', '..', '..', '..'); + + controls = new ProcessControls({ + useGlobalAgent: true, + dirname: __dirname, + enableOtelIntegration: true, + execArgv: ['--import', `${rootFolder}/esm-register.mjs`] + }); + + await controls.startAndWaitForAgentConnection(); + }); + + beforeEach(async () => { + await agentControls.clearReceivedTraceData(); + }); + + after(async () => { + await controls.stop(); + }); + + it('must trace', async () => { + await controls.sendRequest({ + path: '/trigger' + }); + + return retry(async () => { + const spans = await agentControls.getSpans(); + + expect(spans.length).to.equal(4); + + const pinoSpan = spans.find(span => span.n === 'log.pino'); + expect(pinoSpan).to.exist; + + const httpServerSpan = spans.find(span => span.n === 'node.http.server'); + expect(httpServerSpan).to.exist; + + const httpClientSpan = spans.find(span => span.n === 'node.http.client'); + expect(httpClientSpan).to.exist; + expect(httpClientSpan.data).to.exist; + }); + }); +});