Last active
December 26, 2015 09:18
-
-
Save ryanwitt/7127939 to your computer and use it in GitHub Desktop.
cpuse: cpu monitor for node
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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