joyent-portal/spikes/graphs-matrix/chartjs-whiskers/server/metric.js

121 lines
2.8 KiB
JavaScript

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);
}
}
});