From 025f8e06759fa6137c472398c704e3c556f3bb35 Mon Sep 17 00:00:00 2001 From: Renan Duarte <38355185+r3na@users.noreply.github.com> Date: Thu, 9 Jul 2020 18:30:00 +0200 Subject: [PATCH] feat: CPU usage stat (#12) --- stats.js | 42 +++++++++++++++++++++++++++++++++++- test.js | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/stats.js b/stats.js index ac0518d..3e25846 100644 --- a/stats.js +++ b/stats.js @@ -1,5 +1,34 @@ 'use strict' +var os = require('os') + +var startMeasure = cpuAverage() + +function cpuAverage () { + var totalIdle = 0 + var totalTick = 0 + var cpus = os.cpus() + for (var i = 0, len = cpus.length; i < len; i++) { + var cpu = cpus[i] + for (var type in cpu.times) { + totalTick += cpu.times[type] + } + totalIdle += cpu.times.idle + } + return { + idle: totalIdle / cpus.length, + total: totalTick / cpus.length + } +} + +function cpuCalculation () { + var endMeasure = cpuAverage() + var idleDifference = endMeasure.idle - startMeasure.idle + var totalDifference = endMeasure.total - startMeasure.total + var cpuPercentage = 100 - ~~(100 * idleDifference / totalDifference) + return cpuPercentage +} + function client () { this.stats.connectedClients++ if (this.stats.connectedClients > this.stats.maxConnectedClients) { @@ -35,7 +64,8 @@ function wire (aedesInstance, options) { connectedClients: 0, publishedMessages: 0, started: new Date(), - time: new Date() + time: new Date(), + cpuUsage: 0 } function doPub (topic, value) { @@ -48,12 +78,14 @@ function wire (aedesInstance, options) { } var timer = setInterval(iterate, options.interval || (1 * 1000)) + var cpuUsageTimer = setInterval(function () { aedesInstance.stats.cpuUsage = cpuCalculation() }, 1000) function iterate () { var stats = aedesInstance.stats stats.time = new Date() var uptime = Math.round((stats.time - stats.started) / 1000) var mem = process.memoryUsage() + var cpu = os.loadavg() doPub('uptime', uptime) doPub('time', aedesInstance.stats.time.toISOString()) doPub('clients/total', stats.connectedClients) @@ -61,6 +93,13 @@ function wire (aedesInstance, options) { doPub('messages/publish/sent', stats.publishedMessages) doPub('memory/heap/current', mem.heapUsed) doPub('memory/heap/maximum', mem.heapTotal) + doPub('cpu/usage', stats.cpuUsage) + if (cpu && cpu.length >= 3) { + // ref: http://nodejs.org/api/os.html#os_os_loadavg + doPub('cpu/avg/last/1', cpu[0]) + doPub('cpu/avg/last/5', cpu[1]) + doPub('cpu/avg/last/15', cpu[2]) + } } aedesEvents.forEach(function (event) { @@ -69,6 +108,7 @@ function wire (aedesInstance, options) { aedesInstance.once('closed', function () { clearInterval(timer) + clearInterval(cpuUsageTimer) aedesEvents.forEach(function (event) { aedesInstance.removeListener(event.name, event) }) diff --git a/test.js b/test.js index 67010a7..ba8603c 100644 --- a/test.js +++ b/test.js @@ -160,7 +160,7 @@ test('Connect a client and and subscribe to get current heap usage', function (t }) }) -test('Connect a client and and subscribe to get maximum heap usage', function (t) { +test('Connect a client and subscribe to get maximum heap usage', function (t) { t.plan(2) var sysTopic = '$SYS/+/memory/heap/maximum' @@ -175,3 +175,67 @@ test('Connect a client and and subscribe to get maximum heap usage', function (t t.end() }) }) + +test('Connect a client and subscribe to get cpu usage', function (t) { + t.plan(2) + + var sysTopic = '$SYS/+/cpu/usage' + var subscriber = connect(setup()) + + subscriber.subscribe(sysTopic) + + subscriber.on('message', function (topic, message) { + t.ok(checkTopic(topic, sysTopic)) + t.pass(message.toString(), 'cpu usage') + subscriber.end() + t.end() + }) +}) + +test('Connect a client and subscribe to get cpu avg of last 1 min', function (t) { + t.plan(2) + + var sysTopic = '$SYS/+/cpu/avg/last/1' + var subscriber = connect(setup()) + + subscriber.subscribe(sysTopic) + + subscriber.on('message', function (topic, message) { + t.ok(checkTopic(topic, sysTopic)) + t.pass(message.toString(), 'cpu avg of last 1 min') + subscriber.end() + t.end() + }) +}) + +test('Connect a client and subscribe to get cpu avg of last 5 min', function (t) { + t.plan(2) + + var sysTopic = '$SYS/+/cpu/avg/last/5' + var subscriber = connect(setup()) + + subscriber.subscribe(sysTopic) + + subscriber.on('message', function (topic, message) { + t.ok(checkTopic(topic, sysTopic)) + t.pass(message.toString(), 'cpu avg of last 5 min') + subscriber.end() + t.end() + }) +}) + +test('Connect a client and subscribe to get cpu avg of last 15 min', function (t) { + t.plan(2) + + var sysTopic = '$SYS/+/cpu/avg/last/15' + var subscriber = connect(setup()) + + subscriber.subscribe(sysTopic) + + subscriber.on('message', function (topic, message) { + t.ok(checkTopic(topic, sysTopic)) + t.pass(message.toString(), 'cpu avg of last 15 min') + subscriber.end() + t.end() + }) +})