Skip to content

Commit

Permalink
Use process.getActiveResourcesInfo() in process metrics
Browse files Browse the repository at this point in the history
We should use process.getActiveResourcesInfo() here because it is a
public alternative of the private APIs process._getActiveHandles() and
process._getActiveRequests().

Refs: https://nodejs.org/api/process.html#processgetactiveresourcesinfo

Signed-off-by: Darshan Sen <darshan.sen@postman.com>
  • Loading branch information
RaisinTen authored and zbjornson committed Jan 11, 2022
1 parent 18cc6fa commit 3b139f9
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 2 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ project adheres to [Semantic Versioning](http://semver.org/).
causing vscode to think that push/pushAdd and delete didn't promise
resulting in incorrect behavior.

- The `processHandles` and `processRequests` metrics were replaced by the more
advanced `processResources` metric, which keeps a track of all sorts of active
resources. It consists of the following gauges:
- `nodejs_active_resources` - Number of active resources that are currently
keeping the event loop alive, grouped by async resource type.
- `nodejs_active_resources_total` - Total number of active resources.

### Added

## [14.0.0] - 2021-09-18
Expand Down
Binary file added example/.default-metrics.js.swp
Binary file not shown.
6 changes: 4 additions & 2 deletions lib/defaultMetrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const processMaxFileDescriptors = require('./metrics/processMaxFileDescriptors')
const eventLoopLag = require('./metrics/eventLoopLag');
const processHandles = require('./metrics/processHandles');
const processRequests = require('./metrics/processRequests');
const processResources = require('./metrics/processResources');
const heapSizeAndUsed = require('./metrics/heapSizeAndUsed');
const heapSpacesSizeAndUsed = require('./metrics/heapSpacesSizeAndUsed');
const version = require('./metrics/version');
Expand All @@ -23,8 +24,9 @@ const metrics = {
processOpenFileDescriptors,
processMaxFileDescriptors,
eventLoopLag,
processHandles,
processRequests,
...(typeof process.getActiveResourcesInfo === 'function'
? { processResources }
: { processHandles, processRequests }),
heapSizeAndUsed,
heapSpacesSizeAndUsed,
version,
Expand Down
58 changes: 58 additions & 0 deletions lib/metrics/processResources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use strict';
const Gauge = require('../gauge');
const { updateMetrics } = require('./helpers/processMetricsHelpers');

const NODEJS_ACTIVE_RESOURCES = 'nodejs_active_resources';
const NODEJS_ACTIVE_RESOURCES_TOTAL = 'nodejs_active_resources_total';

module.exports = (registry, config = {}) => {
// Don't do anything if the function does not exist in previous nodes (exists in node@17.3.0)
if (typeof process.getActiveResourcesInfo !== 'function') {
return;
}

const namePrefix = config.prefix ? config.prefix : '';
const labels = config.labels ? config.labels : {};
const labelNames = Object.keys(labels);

new Gauge({
name: namePrefix + NODEJS_ACTIVE_RESOURCES,
help:
'Number of active resources that are currently keeping the event loop alive, grouped by async resource type.',
labelNames: ['type', ...labelNames],
registers: registry ? [registry] : undefined,
collect() {
const resources = process.getActiveResourcesInfo();

const data = {};

for (let i = 0; i < resources.length; i++) {
const resource = resources[i];

if (Object.hasOwn(data, resource)) {
data[resource] += 1;
} else {
data[resource] = 1;
}
}

updateMetrics(this, data, labels);
},
});

new Gauge({
name: namePrefix + NODEJS_ACTIVE_RESOURCES_TOTAL,
help: 'Total number of active resources.',
registers: registry ? [registry] : undefined,
labelNames,
collect() {
const resources = process.getActiveResourcesInfo();
this.set(labels, resources.length);
},
});
};

module.exports.metricNames = [
NODEJS_ACTIVE_RESOURCES,
NODEJS_ACTIVE_RESOURCES_TOTAL,
];
37 changes: 37 additions & 0 deletions test/metrics/processResourcesTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

describe('processRequests', () => {
const register = require('../../index').register;
const processResources = require('../../lib/metrics/processResources');

beforeAll(() => {
register.clear();
});

afterEach(() => {
register.clear();
});

it('should add metric to the registry', async () => {
if (typeof process.getActiveResourcesInfo !== 'function') {
return;
}

expect(await register.getMetricsAsJSON()).toHaveLength(0);

processResources();

const metrics = await register.getMetricsAsJSON();

expect(metrics).toHaveLength(2);
expect(metrics[0].help).toEqual(
'Number of active resources that are currently keeping the event loop alive, grouped by async resource type.',
);
expect(metrics[0].type).toEqual('gauge');
expect(metrics[0].name).toEqual('nodejs_active_resources');

expect(metrics[1].help).toEqual('Total number of active resources.');
expect(metrics[1].type).toEqual('gauge');
expect(metrics[1].name).toEqual('nodejs_active_resources_total');
});
});

0 comments on commit 3b139f9

Please sign in to comment.