const async = require('async'); const disk = require('diskusage'); const os = require('os'); const cdm = {}; const osutils = require('os-utils'); const statistics = require('simple-statistics'); const getCPU = (fn) => { return fn(null, { user: os.cpus().reduce((sum, cpu) => sum + cpu.times.user, 0), sys: os.cpus().reduce((sum, cpu) => sum + cpu.times.sys, 0) }); }; const getPerc = (fn) => { async.timesSeries(5, (n, next) => { osutils.cpuUsage((p) => { const percentage = p * 100; next(null, percentage); }); }, (err, sample) => { fn(err, { perc: { firstQuartile: statistics.quantile(sample, 0.25), median: statistics.median(sample), thirdQuartile: statistics.quantile(sample, 0.75), max: statistics.max(sample), min: statistics.min(sample), stddev: statistics.sampleStandardDeviation(sample) } }); }); }; const getMem = (fn) => { async.timesSeries(10, (n, next) => { const free = os.freemem(); const total = os.totalmem(); const using = total - free; const perc = (using / total) * 100; setTimeout(() => { next(null, perc); }, 500); }, (err, sample) => { fn(err, { perc: { firstQuartile: statistics.quantile(sample, 0.25), median: statistics.median(sample), thirdQuartile: statistics.quantile(sample, 0.75), max: statistics.max(sample), min: statistics.min(sample), stddev: statistics.sampleStandardDeviation(sample) } }); }); }; const getDisk = (fn) => { async.timesSeries(5, (n, next) => { disk.check('/', (err, data) => { setTimeout(() => { const perc = (data.available / data.total) * 100; next(err, perc); }, 2000); }); }, (err, sample) => { fn(err, { perc: { firstQuartile: statistics.quantile(sample, 0.25), median: statistics.median(sample), thirdQuartile: statistics.quantile(sample, 0.75), max: statistics.max(sample), min: statistics.min(sample), stddev: statistics.sampleStandardDeviation(sample) } }); }); }; const getStats = (fn) => { async.parallel({ cpu: getPerc, mem: getMem, disk: getDisk }, fn); }; module.exports = (server) => ({ on: (id) => { console.log('on', cdm[id]); if (cdm[id] && (cdm[id].sockets > 0)) { cdm[id].sockets += 1; return; } let messageId = 0; const interval = setInterval(() => { console.log(`publishing /stats/${id}`); getStats((err, stats) => { server.publish(`/stats/${id}`, { when: new Date().getTime(), stats }); }); }, 1000); cdm[id] = { interval, sockets: 1 }; }, off: (id) => { if (!(cdm[id].sockets -= 1)) { clearInterval(cdm[id].interval); } } });