Skip to content

Instantly share code, notes, and snippets.

@ryanwitt
Last active December 26, 2015 09:18
Show Gist options
  • Save ryanwitt/7127939 to your computer and use it in GitHub Desktop.
Save ryanwitt/7127939 to your computer and use it in GitHub Desktop.
cpuse: cpu monitor for node
//
// cpuse.js - simple continuous cpu monitor for node
//
// Intended for programs wanting to monitor and take action on overall CPU load.
//
// The monitor starts as soon as you require the module, then you can query it at
// any later time for the average cpu:
//
// > var cpuse = require('cpuse');
// > cpuse.averages();
// { '1 second': 0.041688434470403546,
// '10 second': 0.048103193628717615,
// '1 minute': 0.051149340772080894,
// '5 minute': 0.05174290700985427,
// '30 minute': 0.051857909889630564,
// '1 hour': 0.05188362865090424 }
//
// The numbers are exponentially weighted moving averages over the given period.
//
var os = require('os');
var load = 0;
var last = { user: 0, nice: 0, sys: 0, idle: 0, irq: 0 };
var last_update = new Date;
var smooth_data = {
'1 second': {
ms: 1000
, load: 0
}
, '10 second': {
ms: 1000*10
, load: 0
}
, '1 minute': {
ms: 1000*60
, load: 0
}
, '5 minute': {
ms: 1000*300
, load: 0
}
, '30 minute': {
ms: 1000*1200
, load: 0
}
, '1 hour': {
ms: 1000*3600
, load: 0
}
};
var update_cpus = function(first) {
var cpus = os.cpus();
var total = { user: 0, nice: 0, sys: 0, idle: 0, irq: 0 };
//console.log(cpus);
// Aggregate ticks from all cpus
for (var i=0; i < cpus.length; i++) {
cpu = cpus[i];
total.user += cpu.times.user;
total.nice += cpu.times.nice;
total.sys += cpu.times.sys;
total.idle += cpu.times.idle;
total.irq += cpu.times.irq;
}
//console.log(total);
// Figure out how they changed since last time
var diff = {
user: total.user - last.user
, nice: total.nice - last.nice
, sys: total.sys - last.sys
, idle: total.idle - last.idle
, irq: total.irq - last.irq
};
// Calculate load
var all = (diff.user + diff.nice + diff.sys + diff.idle + diff.irq);
load = (all - diff.idle) / all;
//
// Average load using equation:
// AVG[n] = alpha * OBS[n] + (1 - alpha) * AVG[n-1]
// where alpha = 1 - e^-( (T[n]-T[n-1]) / AVERAGE_PERIOD )
//
var now = new Date
var diff_ms = now - last_update;
for (var interval in smooth_data) {
var alpha = 1 - Math.exp( - diff_ms / smooth_data[interval].ms );
if (first) smooth_data[interval].load = load;
else smooth_data[interval].load = alpha * load + (1-alpha) * smooth_data[interval].load;
}
last_update = now;
// Update state for next time
last = total;
}
update_cpus(true);
setInterval(update_cpus, 1000);
var averages = function() {
var data = {};
for (var interval in smooth_data) data[interval] = smooth_data[interval].load;
return data;
}
if (require.main === module) {
setInterval(function() {
console.log(averages());
}, 1000);
} else {
exports.averages = averages;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment