From b1f4b819f4a5808f1296de8cfa3307161e465a71 Mon Sep 17 00:00:00 2001 From: Simon Schick Date: Wed, 22 Apr 2020 15:00:31 +0200 Subject: [PATCH 1/3] refactor(metrics): use documented node-apis Use `process.memoryUsage()` instead of `v8.getHeapStatistics()` --- lib/metrics/runtime.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/metrics/runtime.js b/lib/metrics/runtime.js index 39510bc1af..8263dd7ece 100644 --- a/lib/metrics/runtime.js +++ b/lib/metrics/runtime.js @@ -1,7 +1,5 @@ 'use strict' -const v8 = require('v8') - const eventLoopMonitor = require('monitor-event-loop-delay') const activeHandles = typeof process._getActiveHandles === 'function' @@ -43,10 +41,10 @@ class RuntimeCollector { this.stats['nodejs.eventloop.delay.avg.ms'] = loopDelay this.loopMonitor.reset() - // Heap - const heap = v8.getHeapStatistics() - this.stats['nodejs.memory.heap.allocated.bytes'] = heap.total_heap_size - this.stats['nodejs.memory.heap.used.bytes'] = heap.used_heap_size + // Memory / Heap + const memoryUsage = process.memoryUsage() + this.stats['nodejs.memory.heap.allocated.bytes'] = memoryUsage.heapTotal + this.stats['nodejs.memory.heap.used.bytes'] = memoryUsage.heapUsed if (cb) process.nextTick(cb) } From 95fa1fb2a60029c02e2790e9d88aca6a2de0a4cf Mon Sep 17 00:00:00 2001 From: Simon Schick Date: Wed, 22 Apr 2020 15:02:37 +0200 Subject: [PATCH 2/3] feat(metrics): add metrics for external memory Added metrics for `nodejs.memory.external.bytes` and `nodejs.memory.arrayBuffers.bytes` --- docs/metrics.asciidoc | 19 +++++++++++++++++++ lib/metrics/runtime.js | 7 ++++++- test/metrics/index.js | 6 ++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/metrics.asciidoc b/docs/metrics.asciidoc index dd19e73fd4..162a74fec9 100644 --- a/docs/metrics.asciidoc +++ b/docs/metrics.asciidoc @@ -129,6 +129,25 @@ The current allocated heap size in bytes. The currently used heap size in bytes. +[float] +[[metric-nodejs.memory.external.bytes]] +=== `nodejs.memory.external.bytes` + +* *Type:* Long +* *Format:* Bytes + +Memory usage of C++ objects bound to JavaScript objects managed by V8. + +[float] +[[metric-nodejs.memory.arrayBuffers.bytes]] +=== `nodejs.memory.arrayBuffers.bytes` + +* *Type:* Long +* *Format:* Bytes + +Memory allocated for ArrayBuffers and SharedArrayBuffers, including all Node.js Buffers. +This is also included in the `nodejs.memory.external.bytes` value. + [float] [[metrics-transaction.duration.sum]] === `transaction.duration.sum` diff --git a/lib/metrics/runtime.js b/lib/metrics/runtime.js index 8263dd7ece..59bbb63886 100644 --- a/lib/metrics/runtime.js +++ b/lib/metrics/runtime.js @@ -19,7 +19,9 @@ class RuntimeCollector { 'nodejs.requests.active': 0, 'nodejs.eventloop.delay.ns': 0, 'nodejs.memory.heap.allocated.bytes': 0, - 'nodejs.memory.heap.used.bytes': 0 + 'nodejs.memory.heap.used.bytes': 0, + 'nodejs.memory.external.bytes': 0, + 'nodejs.memory.arrayBuffers.bytes': 0 } const monitor = eventLoopMonitor({ @@ -46,6 +48,9 @@ class RuntimeCollector { this.stats['nodejs.memory.heap.allocated.bytes'] = memoryUsage.heapTotal this.stats['nodejs.memory.heap.used.bytes'] = memoryUsage.heapUsed + this.stats['nodejs.memory.external.bytes'] = memoryUsage.external + this.stats['nodejs.memory.arrayBuffers.bytes'] = memoryUsage.arrayBuffers || 0 // Only available in NodeJS +13.0 + if (cb) process.nextTick(cb) } } diff --git a/test/metrics/index.js b/test/metrics/index.js index 67be31060c..a874075d9e 100644 --- a/test/metrics/index.js +++ b/test/metrics/index.js @@ -117,6 +117,12 @@ test('reports expected metrics', function (t) { 'nodejs.memory.heap.used.bytes': (value) => { t.ok(value >= 0, 'is positive') }, + 'nodejs.memory.external.bytes': (value) => { + t.ok(value >= 0, 'is positive') + }, + 'nodejs.memory.arrayBuffers.bytes': (value) => { + t.ok(value >= 0, 'is positive') + }, 'ws.connections': (value) => { t.equal(value, 23) } From 57915c55084a872a919a882cbd058228e2751aff Mon Sep 17 00:00:00 2001 From: Simon Schick Date: Thu, 23 Apr 2020 13:51:47 +0200 Subject: [PATCH 3/3] refactor(metrics): rename metric key Move `system.process.memory.rss.bytes` to `nodejs.memory.rss.bytes` --- docs/metrics.asciidoc | 20 ++++++++++---------- lib/metrics/platforms/generic/index.js | 5 ----- lib/metrics/platforms/linux/stats.js | 7 ++----- lib/metrics/runtime.js | 2 ++ test/metrics/index.js | 8 ++++---- 5 files changed, 18 insertions(+), 24 deletions(-) diff --git a/docs/metrics.asciidoc b/docs/metrics.asciidoc index 162a74fec9..c68d3f8c2c 100644 --- a/docs/metrics.asciidoc +++ b/docs/metrics.asciidoc @@ -51,16 +51,6 @@ Free memory of the system in bytes. The percentage of CPU time spent by the process since the last event. This value is normalized by the number of CPU cores and it ranges from 0 to 100%. -[float] -[[metric-system.process.memory.rss.bytes]] -=== `system.process.memory.rss.bytes` - -* *Type:* Long -* *Format:* Bytes - -The Resident Set Size, -the amount of memory the process occupies in main memory (RAM). - [float] [[metric-nodejs.handles.active]] === `nodejs.handles.active` @@ -111,6 +101,16 @@ Event loop delay is sampled every 10 milliseconds. Delays shorter than 10ms may not be observed, for example if a blocking operation starts and ends within the same sampling period. +[float] +[[metric-nodejs.memory.rss.bytes]] +=== `nodejs.memory.rss.bytes` + +* *Type:* Long +* *Format:* Bytes + +The Resident Set Size, +the amount of memory the process occupies in main memory (RAM). + [float] [[metric-nodejs.memory.heap.allocated.bytes]] === `nodejs.memory.heap.allocated.bytes` diff --git a/lib/metrics/platforms/generic/index.js b/lib/metrics/platforms/generic/index.js index 54cc33f511..b54d10feb8 100644 --- a/lib/metrics/platforms/generic/index.js +++ b/lib/metrics/platforms/generic/index.js @@ -32,9 +32,4 @@ module.exports = function createSystemMetrics (registry) { for (const metric of metrics) { registry.getOrCreateGauge(metric, () => stats.toJSON()[metric]) } - - registry.getOrCreateGauge( - 'system.process.memory.rss.bytes', - () => process.memoryUsage().rss - ) } diff --git a/lib/metrics/platforms/linux/stats.js b/lib/metrics/platforms/linux/stats.js index c26a8f94a4..fb76c13f19 100644 --- a/lib/metrics/platforms/linux/stats.js +++ b/lib/metrics/platforms/linux/stats.js @@ -34,8 +34,7 @@ class Stats { 'system.process.cpu.total.norm.pct': 0, 'system.process.cpu.system.norm.pct': 0, 'system.process.cpu.user.norm.pct': 0, - 'system.process.memory.size': 0, - 'system.process.memory.rss.bytes': 0 + 'system.process.memory.size': 0 } this.inProgress = false @@ -150,8 +149,7 @@ class Stats { memAvailable, utime, stime, - vsize, - rss: process.memoryUsage().rss // TODO: Calculate using field 24 (rss) * PAGE_SIZE + vsize } } @@ -186,7 +184,6 @@ class Stats { stats['system.process.cpu.user.norm.pct'] = cpuProcessUserPercent stats['system.process.cpu.system.norm.pct'] = cpuProcessSystemPercent stats['system.process.memory.size'] = next.vsize - stats['system.process.memory.rss.bytes'] = next.rss this.previous = next this.inProgress = false diff --git a/lib/metrics/runtime.js b/lib/metrics/runtime.js index 59bbb63886..faadbed594 100644 --- a/lib/metrics/runtime.js +++ b/lib/metrics/runtime.js @@ -20,6 +20,7 @@ class RuntimeCollector { 'nodejs.eventloop.delay.ns': 0, 'nodejs.memory.heap.allocated.bytes': 0, 'nodejs.memory.heap.used.bytes': 0, + 'nodejs.memory.rss.bytes': 0, 'nodejs.memory.external.bytes': 0, 'nodejs.memory.arrayBuffers.bytes': 0 } @@ -48,6 +49,7 @@ class RuntimeCollector { this.stats['nodejs.memory.heap.allocated.bytes'] = memoryUsage.heapTotal this.stats['nodejs.memory.heap.used.bytes'] = memoryUsage.heapUsed + this.stats['nodejs.memory.rss.bytes'] = memoryUsage.rss this.stats['nodejs.memory.external.bytes'] = memoryUsage.external this.stats['nodejs.memory.arrayBuffers.bytes'] = memoryUsage.arrayBuffers || 0 // Only available in NodeJS +13.0 diff --git a/test/metrics/index.js b/test/metrics/index.js index a874075d9e..6cac342f00 100644 --- a/test/metrics/index.js +++ b/test/metrics/index.js @@ -81,10 +81,6 @@ test('reports expected metrics', function (t) { t.ok(isRoughly(value, free, 0.1), `is close to current free memory (value: ${value}, free: ${free})`) } }, - 'system.process.memory.rss.bytes': (value) => { - const rss = process.memoryUsage().rss - t.ok(isRoughly(value, rss, 0.1), `is close to current rss (value: ${value}, rss: ${rss})`) - }, 'system.process.cpu.total.norm.pct': (value) => { if (count === 1) { t.ok(value >= 0 && value <= 1, 'is betewen 0 and 1') @@ -117,6 +113,10 @@ test('reports expected metrics', function (t) { 'nodejs.memory.heap.used.bytes': (value) => { t.ok(value >= 0, 'is positive') }, + 'nodejs.memory.rss.bytes': (value) => { + const rss = process.memoryUsage().rss + t.ok(isRoughly(value, rss, 0.1), `is close to current rss (value: ${value}, rss: ${rss})`) + }, 'nodejs.memory.external.bytes': (value) => { t.ok(value >= 0, 'is positive') },