rewritten processes current cpu usage linux

This commit is contained in:
Sebastian Hildebrandt 2016-08-30 10:28:14 +02:00
parent 0c1fbf9496
commit 7f0dacdeca
2 changed files with 184 additions and 21 deletions

View File

@ -256,6 +256,9 @@ This library is splitted in several sections:
| si.currentLoad(cb) | X | X | CPU-Load |
| - avgload | X | X | average load |
| - currentload | X | X | CPU-Load in % |
| - currentload_user | X | | CPU-Load User in % |
| - currentload_nice | X | | CPU-Load Nice in % |
| - currentload_system | X | | CPU-Load System in % |
| si.fullLoad(cb) | X | X | CPU-full load since bootup in % |
| si.services('mysql, apache2', cb) | X | X | pass comma separated string of services |
| - [0].name | X | X | name of service |
@ -369,6 +372,7 @@ I am happy to discuss any comments and suggestions. Please feel free to contact
| Version | Date | Comment |
| -------------- | -------------- | -------- |
| 3.3.1 | 2016-08-30 | rewritten processes current cpu usage |
| 3.3.0 | 2016-08-24 | process list added to processes |
| 3.2.1 | 2016-08-19 | updated docs, improvement system |
| 3.2.0 | 2016-08-19 | added battery information |

View File

@ -80,6 +80,7 @@
// --------------------------------
//
// version date comment
// 3.3.1 2016-08-30 current process cpu usage
// 3.3.0 2016-08-24 added process list
// 3.2.1 2016-08-20 updated docs, improvement system
// 3.2.0 2016-08-19 added battery info
@ -127,6 +128,24 @@ var _fs_speed = {};
var _disk_io = {};
var _default_iface;
var _docker_container_stats = {};
var _process_cpu = {
all: 0,
list: {},
ms: 0
};
var _current_cpu = {
user: 0,
nice: 0,
system: 0,
idle: 0,
iowait: 0,
irq: 0,
softirq: 0,
steal: 0,
guest: 0,
guest_nice: 0,
all: 0
};
const NOT_SUPPORTED = 'not supported';
@ -1487,19 +1506,61 @@ function getLoad() {
let loads = os.loadavg().map(function (x) { return x / _cores; });
result.avgload = parseFloat((Math.max.apply(Math, loads)).toFixed(2));
result.currentload = -1;
result.currentload_user = -1;
result.currentload_nice = -1;
result.currentload_system = -1;
let cmd = (_darwin) ? "ps -cax -o pcpu" : "ps axo pcpu";
exec(cmd, function (error, stdout) {
if (!error) {
let lines = stdout.toString().replace(/,+/g, ".").split('\n');
lines.shift();
lines.pop();
result.currentload = parseFloat(((lines.reduce(function (pv, cv) {
return pv + parseFloat(cv.trim());
}, 0)) / _cores).toFixed(2));
}
resolve(result);
});
if (_darwin) {
exec("ps -cax -o pcpu", function (error, stdout) {
if (!error) {
let lines = stdout.toString().replace(/,+/g, ".").split('\n');
lines.shift();
lines.pop();
result.currentload = parseFloat(((lines.reduce(function (pv, cv) {
return pv + parseFloat(cv.trim());
}, 0)) / _cores).toFixed(2));
}
resolve(result);
});
}
if (_linux) {
exec("cat /proc/stat | grep 'cpu '", function (error, stdout) {
if (!error) {
let lines = stdout.toString().split('\n');
let parts = lines[0].replace(/ +/g, " ").split(' ');
let user = (parts.length >= 2 ? parseInt(parts[1]) : 0);
let nice = (parts.length >= 3 ? parseInt(parts[2]) : 0);
let system = (parts.length >= 4 ? parseInt(parts[3]) : 0);
let idle = (parts.length >= 5 ? parseInt(parts[4]) : 0);
let iowait = (parts.length >= 6 ? parseInt(parts[5]) : 0);
let irq = (parts.length >= 7 ? parseInt(parts[6]) : 0);
let softirq = (parts.length >= 8 ? parseInt(parts[7]) : 0);
let steal = (parts.length >= 9 ? parseInt(parts[8]) : 0);
let guest = (parts.length >= 10 ? parseInt(parts[9]) : 0);
let guest_nice = (parts.length >= 11 ? parseInt(parts[10]) : 0);
let all = user + nice + system + idle + iowait + irq + softirq + steal + guest + guest_nice;
result.currentload = (user + nice + system - _current_cpu.user - _current_cpu.nice - _current_cpu.system) / (all - _current_cpu.all) * 100;
result.currentload_user = (user - _current_cpu.user) / (all - _current_cpu.all) * 100;
result.currentload_nice = (nice - _current_cpu.nice) / (all - _current_cpu.all) * 100;
result.currentload_system = (system - _current_cpu.system) / (all - _current_cpu.all) * 100;
_current_cpu = {
user: user,
nice: nice,
system: system,
idle: idle,
iowait: iowait,
irq: irq,
softirq: softirq,
steal: steal,
guest: guest,
guest_nice: guest_nice,
all: all
}
}
resolve(result);
});
}
});
});
}
@ -1760,6 +1821,61 @@ function processes(callback) {
return result;
}
function parseProcStat(line) {
let parts = line.replace(/ +/g, " ").split(' ');
let user = (parts.length >= 2 ? parseInt(parts[1]) : 0);
let nice = (parts.length >= 3 ? parseInt(parts[2]) : 0);
let system = (parts.length >= 4 ? parseInt(parts[3]) : 0);
let idle = (parts.length >= 5 ? parseInt(parts[4]) : 0);
let iowait = (parts.length >= 6 ? parseInt(parts[5]) : 0);
let irq = (parts.length >= 7 ? parseInt(parts[6]) : 0);
let softirq = (parts.length >= 8 ? parseInt(parts[7]) : 0);
let steal = (parts.length >= 9 ? parseInt(parts[8]) : 0);
let guest = (parts.length >= 10 ? parseInt(parts[9]) : 0);
let guest_nice = (parts.length >= 11 ? parseInt(parts[10]) : 0);
return user + nice + system + idle + iowait + irq + softirq + steal + guest + guest_nice;
}
function parseProcPidStat(line, all) {
let parts = line.replace(/ +/g, " ").split(' ');
if (parts.length >= 17) {
let pid = parseInt(parts[0]);
let utime = parseInt(parts[13]);
let stime = parseInt(parts[14]);
let cutime = parseInt(parts[15]);
let cstime = parseInt(parts[16]);
// calc
let pcpuu = 0;
let pcpus = 0;
if (_process_cpu.all > 0 && _process_cpu.list[pid]) {
pcpuu = (utime + cutime - _process_cpu.list[pid].utime - _process_cpu.list[pid].cutime) / (all - _process_cpu.all) * 100; // user
pcpus = (stime + cstime - _process_cpu.list[pid].stime - _process_cpu.list[pid].cstime) / (all - _process_cpu.all) * 100; // system
} else {
pcpuu = (utime + cutime) / (all) * 100; // user
pcpus = (stime + cstime) / (all) * 100; // system
}
return {
pid: pid,
utime: utime,
stime: stime,
cutime: cutime,
cstime: cstime,
pcpuu: pcpuu,
pcpus: pcpus
}
} else {
return {
pid: 0,
utime: 0,
stime: 0,
cutime: 0,
cstime: 0,
pcpuu: 0,
pcpus: 0
}
}
}
return new Promise((resolve, reject) => {
process.nextTick(() => {
if (_windows) {
@ -1776,7 +1892,7 @@ function processes(callback) {
};
let cmd = "";
if (_linux) cmd = "ps axo pid:10,pcpu:6,pmem:6,pri:5,vsz:10,rss:10,start:20,state:20,tty:20,user:20,command --sort=-pcpu";
if (_linux) cmd = "ps axo pid:10,pcpu:6,pmem:6,pri:5,vsz:10,rss:10,start:20,state:20,tty:20,user:20,command";
if (_darwin) cmd = "ps acxo pid,pcpu,pmem,pri,vsz,rss,start,state,tty,user,command -r";
exec(cmd, function (error, stdout) {
if (!error) {
@ -1790,10 +1906,58 @@ function processes(callback) {
}).length;
result.sleeping = result.list.filter(function (e) {
return e.state == 'sleeping'
}).length
}).length;
if (_linux) {
// calc process_cpu - ps is not accurate in linux!
cmd = "cat /proc/stat | grep 'cpu '";
for (let i=0; i< result.list.length; i++) {
cmd += (';cat /proc/' + result.list[i].pid + '/stat')
}
exec(cmd, function (error, stdout) {
let curr_processes = stdout.toString().split('\n');
// first line (all - /proc/stat)
let all = parseProcStat(curr_processes.shift());
// process
let list_new = {};
let resultProcess = {};
for (let i=0; i< curr_processes.length; i++) {
resultProcess = parseProcPidStat(curr_processes[i], all);
if (resultProcess.pid) {
// store pcpu in outer array
let listPos = result.list.map(function(e) { return e.pid; }).indexOf(resultProcess.pid);
if (listPos >= 0) {
result.list[listPos].pcpu = resultProcess.pcpuu + resultProcess.pcpus
}
// save new values
list_new[resultProcess.pid] = {
pcpuu: resultProcess.pcpuu,
pcpus: resultProcess.pcpus,
utime: resultProcess.utime,
stime: resultProcess.stime,
cutime: resultProcess.cutime,
cstime: resultProcess.cstime
}
}
}
// store old values
_process_cpu.all = all;
_process_cpu.list = list_new;
_process_cpu.ms = Date.now() - _process_cpu.ms;
if (callback) { callback(result) }
resolve(result);
})
} else {
if (callback) { callback(result) }
resolve(result);
}
}
if (callback) { callback(result) }
resolve(result);
});
});
});
@ -1898,15 +2062,12 @@ function parseUsers1(lines) {
w_pos.push(line.indexOf(item))
});
w_first = false;
// console.log(w_pos);
// console.log(result_who);
} else {
// split by w_pos
result_w.user = line.substring(w_pos[0], w_pos[1]-1).trim();
result_w.tty = line.substring(w_pos[1], w_pos[2]-1).trim();
result_w.ip = line.substring(w_pos[2], w_pos[3]-1).replace(/\(/g, "").replace(/\)/g, "").trim();
result_w.command = line.substring(w_pos[7], 1000).trim();
// console.log(result_w);
// find corresponding 'who' line
who_line = result_who.filter(function(obj) {
return (obj.user.substring(0,8).trim() == result_w.user && obj.tty == result_w.tty)
@ -2171,7 +2332,6 @@ function dockerContainers(all, callback) {
try {
let jsonString = stdout.toString();
var docker_containers = JSON.parse(jsonString);
// console.log(docker_containers)
if (docker_containers && Object.prototype.toString.call(docker_containers) === '[object Array]' && docker_containers.length > 0) {
docker_containers.forEach(function (element) {
/**
@ -2352,7 +2512,6 @@ function dockerContainerStats(containerID, callback) {
* @property {Object} blkio_stats
*/
//console.log(stats);
if (!stats.message) {
result.mem_usage = (stats.memory_stats && stats.memory_stats.usage ? stats.memory_stats.usage : 0);
result.mem_limit = (stats.memory_stats && stats.memory_stats.limit ? stats.memory_stats.limit : 0);