From a28f550be97d9f99f9073cfc3af36c284eb0b544 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Wed, 4 Feb 2026 09:32:41 -0300 Subject: [PATCH 1/2] Include the framework version with the report metadata This will report the fastify/express/bull/bullmq version they're using with each report, so we can more easily troubleshoot things if necessary and also verify version support on our side. This matches the behavior of Ruby/Python packages as well. --- packages/bull/src/index.js | 2 ++ packages/bullmq/src/index.js | 2 ++ packages/express/src/index.js | 2 ++ packages/fastify/src/plugin.js | 2 ++ 4 files changed, 8 insertions(+) diff --git a/packages/bull/src/index.js b/packages/bull/src/index.js index c21fe6e..4deb613 100644 --- a/packages/bull/src/index.js +++ b/packages/bull/src/index.js @@ -1,9 +1,11 @@ const { Judoscale } = require('judoscale-node-core') const BullMetricsCollector = require('./bull-metrics-collector') const packageInfo = require('../package.json') +const bullPackageInfo = require('bull/package.json') Judoscale.registerAdapter('judoscale-bull', new BullMetricsCollector(), { adapter_version: packageInfo.version, + framework_version: bullPackageInfo.version, }) module.exports = { diff --git a/packages/bullmq/src/index.js b/packages/bullmq/src/index.js index 13f1c30..bc16371 100644 --- a/packages/bullmq/src/index.js +++ b/packages/bullmq/src/index.js @@ -1,9 +1,11 @@ const { Judoscale } = require('judoscale-node-core') const BullMQMetricsCollector = require('./bull-mq-metrics-collector') const packageInfo = require('../package.json') +const bullmqPackageInfo = require('bullmq/package.json') Judoscale.registerAdapter('judoscale-bullmq', new BullMQMetricsCollector(), { adapter_version: packageInfo.version, + framework_version: bullmqPackageInfo.version, }) module.exports = { diff --git a/packages/express/src/index.js b/packages/express/src/index.js index 45879b1..7795b45 100644 --- a/packages/express/src/index.js +++ b/packages/express/src/index.js @@ -1,5 +1,6 @@ const { Judoscale, MetricsStore, requestMetrics, UtilizationTracker, WebMetricsCollector } = require('judoscale-node-core') const packageInfo = require('../package.json') +const expressPackageInfo = require('express/package.json') const metricsStore = new MetricsStore() const utilizationTracker = new UtilizationTracker() @@ -33,6 +34,7 @@ function middleware(judoscale) { Judoscale.registerAdapter('judoscale-express', new WebMetricsCollector(metricsStore, utilizationTracker), { adapter_version: packageInfo.version, + framework_version: expressPackageInfo.version, }) module.exports = { Judoscale, middleware } diff --git a/packages/fastify/src/plugin.js b/packages/fastify/src/plugin.js index 06c511f..d784948 100644 --- a/packages/fastify/src/plugin.js +++ b/packages/fastify/src/plugin.js @@ -1,6 +1,7 @@ const fp = require('fastify-plugin') const { Judoscale, MetricsStore, requestMetrics, UtilizationTracker, WebMetricsCollector } = require('judoscale-node-core') const packageInfo = require('../package.json') +const fastifyPackageInfo = require('fastify/package.json') const metricsStore = new MetricsStore() const utilizationTracker = new UtilizationTracker() @@ -41,6 +42,7 @@ const plugin = fp(rawPlugin, { Judoscale.registerAdapter('judoscale-fastify', new WebMetricsCollector(metricsStore, utilizationTracker), { adapter_version: packageInfo.version, + framework_version: fastifyPackageInfo.version, }) module.exports = { From c6ef8cc1003c7e735e055c50a0a5272ca3567ec4 Mon Sep 17 00:00:00 2001 From: Carlos Antonio da Silva Date: Wed, 4 Feb 2026 10:54:09 -0300 Subject: [PATCH 2/2] Register node-core as an adapter without a collector This allows us to report its adapter version & node version so we can keep track of versions supported, and it can aid troubleshooting. We need to make sure we skip trying to collect metrics from it though since there's no collector, so the report code was changed slightly to accommodate for that, and tests as well which were relying on the first registered adapter being the one they were testing against (which is no longer true.) --- packages/express/src/test/index.test.js | 10 ++++++---- packages/fastify/test/plugin.test.js | 10 ++++++---- packages/node-core/src/index.js | 6 ++++++ packages/node-core/src/judoscale.js | 4 +++- packages/node-core/src/reporter.js | 2 +- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/express/src/test/index.test.js b/packages/express/src/test/index.test.js index 76ea503..df1e26c 100644 --- a/packages/express/src/test/index.test.js +++ b/packages/express/src/test/index.test.js @@ -10,9 +10,11 @@ app.get('/test', (_req, res) => { res.send('Middleware test') }) +const expressAdapter = Judoscale.adapters.find((a) => a.identifier === 'judoscale-express') + test('adapter is registered', () => { - expect(Judoscale.adapters.length).toEqual(1) - expect(Judoscale.adapters[0].identifier).toEqual('judoscale-express') + expect(expressAdapter).toBeDefined() + expect(expressAdapter.identifier).toEqual('judoscale-express') }) describe('middleware', () => { @@ -24,7 +26,7 @@ describe('middleware', () => { expect(response.statusCode).toBe(200) expect(response.text).toBe('Middleware test') - const metrics = Judoscale.adapters[0].collector.collect() + const metrics = expressAdapter.collector.collect() expect(metrics.length).toEqual(3) // Queue time should be 100-200ms depending how long the test takes to run expect(metrics[0].identifier).toEqual('qt') @@ -40,7 +42,7 @@ describe('middleware', () => { const response = await request(app).get('/test') expect(response.statusCode).toBe(200) - const metrics = Judoscale.adapters[0].collector.collect() + const metrics = expressAdapter.collector.collect() // Only app time & utilization pct are tracked, queue time isn't. expect(metrics.length).toEqual(2) expect(metrics[0].identifier).toEqual('at') diff --git a/packages/fastify/test/plugin.test.js b/packages/fastify/test/plugin.test.js index f9a7de4..70f20ac 100644 --- a/packages/fastify/test/plugin.test.js +++ b/packages/fastify/test/plugin.test.js @@ -9,9 +9,11 @@ app.get('/test', async (_request, _reply) => { return { message: 'Middleware test' } }) +const fastifyAdapter = Judoscale.adapters.find((a) => a.identifier === 'judoscale-fastify') + test('adapter is registered', () => { - expect(Judoscale.adapters.length).toEqual(1) - expect(Judoscale.adapters[0].identifier).toEqual('judoscale-fastify') + expect(fastifyAdapter).toBeDefined() + expect(fastifyAdapter.identifier).toEqual('judoscale-fastify') }) describe('Judoscale Fastify Plugin', () => { @@ -35,7 +37,7 @@ describe('Judoscale Fastify Plugin', () => { expect(response.statusCode).toBe(200) expect(JSON.parse(response.body)).toEqual({ message: 'Middleware test' }) - const metrics = Judoscale.adapters[0].collector.collect() + const metrics = fastifyAdapter.collector.collect() expect(metrics.length).toEqual(3) // Queue time should be 100-200ms depending how long the test takes to run expect(metrics[0].identifier).toEqual('qt') @@ -55,7 +57,7 @@ describe('Judoscale Fastify Plugin', () => { }) expect(response.statusCode).toBe(200) - const metrics = Judoscale.adapters[0].collector.collect() + const metrics = fastifyAdapter.collector.collect() // Only app time & utilization pct are tracked, queue time isn't. expect(metrics.length).toEqual(2) expect(metrics[0].identifier).toEqual('at') diff --git a/packages/node-core/src/index.js b/packages/node-core/src/index.js index 54d4d4e..47e7520 100644 --- a/packages/node-core/src/index.js +++ b/packages/node-core/src/index.js @@ -8,6 +8,12 @@ const UtilizationTracker = require('./utilization-tracker') const WebMetricsCollector = require('./web-metrics-collector') const WorkerMetricsCollector = require('./worker-metrics-collector') const Judoscale = require('./judoscale') +const packageInfo = require('../package.json') + +Judoscale.registerAdapter('judoscale-node', null, { + adapter_version: packageInfo.version, + language_version: process.version, +}) module.exports = { Judoscale, diff --git a/packages/node-core/src/judoscale.js b/packages/node-core/src/judoscale.js index 43c94a2..e50eff2 100644 --- a/packages/node-core/src/judoscale.js +++ b/packages/node-core/src/judoscale.js @@ -9,7 +9,9 @@ class Judoscale { // Expose config to the collectors for (const adapter of Judoscale.adapters) { - adapter.collector.config = { ...this.config, ...adapter.collector.config } + if (adapter.collector) { + adapter.collector.config = { ...this.config, ...adapter.collector.config } + } } new Reporter().start(this.config, Judoscale.adapters) diff --git a/packages/node-core/src/reporter.js b/packages/node-core/src/reporter.js index 56c947a..6e38c34 100644 --- a/packages/node-core/src/reporter.js +++ b/packages/node-core/src/reporter.js @@ -41,7 +41,7 @@ class Reporter { } async report(adapters, config) { - const collectors = adapters.map((a) => a.collector) + const collectors = adapters.map((a) => a.collector).filter(Boolean) const metrics = (await Promise.all(collectors.map((collector) => collector.collect()))).flat() const report = new Report(adapters, config, metrics) config.logger.info(`[Judoscale] Reporting ${report.metrics.length} metrics`)