From e6ecc4885d4ef75c64709be3420bda0fd248938f Mon Sep 17 00:00:00 2001 From: Alex Shumsky Date: Mon, 18 Oct 2021 18:27:01 +0300 Subject: [PATCH] Add eventloop idle time metric --- CHANGELOG.md | 2 ++ lib/defaultMetrics.js | 2 ++ lib/metrics/eventLoopIdle.js | 44 ++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 lib/metrics/eventLoopIdle.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b0418d5..17141ce0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Added: `nodejs_eventloop_idle_seconds_total` metric to 'collectDefaultMetrics()`. + ## [14.0.0] - 2021-09-18 ### Breaking diff --git a/lib/defaultMetrics.js b/lib/defaultMetrics.js index 10e5906f..59c34664 100644 --- a/lib/defaultMetrics.js +++ b/lib/defaultMetrics.js @@ -9,6 +9,7 @@ const osMemoryHeap = require('./metrics/osMemoryHeap'); const processOpenFileDescriptors = require('./metrics/processOpenFileDescriptors'); const processMaxFileDescriptors = require('./metrics/processMaxFileDescriptors'); const eventLoopLag = require('./metrics/eventLoopLag'); +const eventLoopIdle = require('./metrics/eventLoopIdle'); const processHandles = require('./metrics/processHandles'); const processRequests = require('./metrics/processRequests'); const heapSizeAndUsed = require('./metrics/heapSizeAndUsed'); @@ -23,6 +24,7 @@ const metrics = { processOpenFileDescriptors, processMaxFileDescriptors, eventLoopLag, + eventLoopIdle, processHandles, processRequests, heapSizeAndUsed, diff --git a/lib/metrics/eventLoopIdle.js b/lib/metrics/eventLoopIdle.js new file mode 100644 index 00000000..f0e95b9d --- /dev/null +++ b/lib/metrics/eventLoopIdle.js @@ -0,0 +1,44 @@ +'use strict'; + +const Counter = require('../counter'); + +// Check if metric is available +let nodeTiming; +try { + /* eslint-disable node/no-unsupported-features/node-builtins */ + nodeTiming = require('perf_hooks').performance.nodeTiming; +} catch (ex) { + // node version is too old +} + +// Reported only when perf_hooks.performance.nodeTiming.idleTime is available. +const NODEJS_EVENTLOOP_IDLE = 'nodejs_eventloop_idle_seconds_total'; + +module.exports = (registry, config = {}) => { + if (!nodeTiming || nodeTiming.idleTime === undefined) { + return; + } + + const namePrefix = config.prefix ? config.prefix : ''; + const labels = config.labels ? config.labels : {}; + const labelNames = Object.keys(labels); + const registers = registry ? [registry] : undefined; + + let lastIdle = nodeTiming.idleTime; + + const idle = new Counter({ + name: namePrefix + NODEJS_EVENTLOOP_IDLE, + help: + "Total amount of time the event loop has been idle within the event loop's event provider", + registers, + labelNames, + aggregator: 'average', + collect() { + const val = nodeTiming.idleTime / 1e3; + idle.inc(labels, val - lastIdle); + lastIdle = val; + }, + }); +}; + +module.exports.metricNames = [NODEJS_EVENTLOOP_IDLE];