diff --git a/CHANGELOG.md b/CHANGELOG.md index c0ef745..3fc7221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -100,6 +100,7 @@ Other changes | Version | Date | Comment | | -------------- | -------------- | -------- | +| 3.51.0 | 2018-11-25 | `processLoad()` added for windows | | 3.50.3 | 2018-11-25 | `processLoad()`, `services()` fixed cpu data (linux) | | 3.50.2 | 2018-11-23 | network mac adresses: ip support fix | | 3.50.1 | 2018-11-23 | `services()` added possibility to specify ALL services "*" for win | diff --git a/README.md b/README.md index b921422..d571feb 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ async function cpu() { (last 7 major and minor version releases) +- Version 3.51.0: `processLoad()` added for windows - Version 3.50.0: `services()` added possibility to specify ALL services "*" for linux/win - Version 3.49.0: `uuid()` added - os specific uuid (per installation) - Version 3.48.0: `osInfo()` added build, serial (Windows/macOS) @@ -373,11 +374,11 @@ I also created a nice little command line tool called [mmon][mmon-github-url] ( | | ...[0].tty | X | X | X | | X | tty from which process was started | | | ...[0].user | X | X | X | | X | user who started process | | | ...[0].command | X | X | X | X | X | process starting command | -| si.processLoad('apache2',cb) | {...} | X | X | X | | | detailed information about given process | -| | proc | X | X | X | | | process name | -| | pid | X | X | X | | | PID | -| | cpu | X | X | X | | | process % CPU | -| | mem | X | X | X | | | process % MEM | +| si.processLoad('apache2',cb) | {...} | X | X | X | X | | detailed information about given process | +| | proc | X | X | X | X | | process name | +| | pid | X | X | X | X | | PID | +| | cpu | X | X | X | X | | process % CPU | +| | mem | X | X | X | X | | process % MEM | | si.services('mysql, apache2', cb) | [{...}] | X | X | X | X | | pass comma separated string of services
pass "*" for ALL services (linux/win only) | | | [0].name | X | X | X | X | | name of service | | | [0].running | X | X | X | X | | true / false | diff --git a/lib/processes.js b/lib/processes.js index 7dbd04c..145f7fa 100644 --- a/lib/processes.js +++ b/lib/processes.js @@ -27,8 +27,6 @@ const _freebsd = (_platform === 'freebsd'); const _openbsd = (_platform === 'openbsd'); const _sunos = (_platform === 'sunos'); -const NOT_SUPPORTED = 'not supported'; - let _processes_cpu = { all: 0, list: {}, @@ -835,14 +833,8 @@ function processLoad(proc, callback) { proc = ''; } - return new Promise((resolve, reject) => { + return new Promise((resolve) => { process.nextTick(() => { - if (_windows) { - let error = new Error(NOT_SUPPORTED); - if (callback) { callback(NOT_SUPPORTED); } - reject(error); - } - let result = { 'proc': proc, 'pid': -1, @@ -851,90 +843,168 @@ function processLoad(proc, callback) { }; if (proc) { - exec('ps -axo pid,pcpu,pmem,comm | grep -i ' + proc + ' | grep -v grep', { maxBuffer: 1024 * 2000 }, function (error, stdout) { - if (!error) { - let lines = stdout.toString().split('\n'); - - let pid = 0; - let pids = []; - let cpu = 0; - let mem = 0; - - lines.forEach(function (line) { - let data = line.trim().replace(/ +/g, ' ').split(' '); - if (data.length > 3) { - pid = (!pid ? parseInt(data[0]) : 0); - pids.push(parseInt(data[0], 10)); - cpu = cpu + parseFloat(data[1].replace(',', '.')); - mem = mem + parseFloat(data[2].replace(',', '.')); - } - }); - - result = { - 'proc': proc, - 'pid': pid, - 'pids': pids, - 'cpu': parseFloat((cpu / lines.length).toFixed(2)), - 'mem': parseFloat((mem / lines.length).toFixed(2)) - }; - if (_linux) { - // calc process_cpu - ps is not accurate in linux! - let cmd = 'cat /proc/stat | grep "cpu "'; - for (let i = 0; i < result.pids.length; i++) { - cmd += (';cat /proc/' + result.pids[i] + '/stat'); - } - - exec(cmd, { maxBuffer: 1024 * 2000 }, function (error, stdout) { - let curr_processes = stdout.toString().split('\n'); - - // first line (all - /proc/stat) - let all = parseProcStat(curr_processes.shift()); - - // process + if (_windows) { + try { + exec(util.getWmic() + ' process get /value', util.execOptsWin, function (error, stdout) { + if (!error) { + let processSections = stdout.split(/\n\s*\n/); + let procs = []; + let procStats = {}; let list_new = {}; - let resultProcess = {}; - result.cpu = 0; - for (let i = 0; i < curr_processes.length; i++) { - resultProcess = calcProcStatLinux(curr_processes[i], all, _process_cpu); + let allcpuu = 0; + let allcpus = 0; + for (let i = 0; i < processSections.length; i++) { + if (processSections[i].trim() !== '') { + let lines = processSections[i].trim().split('\r\n'); + let pid = parseInt(util.getValue(lines, 'ProcessId', '=', true), 10); + let name = util.getValue(lines, 'Caption', '=', true); + let utime = parseInt(util.getValue(lines, 'UserModeTime', '=', true), 10); + let stime = parseInt(util.getValue(lines, 'KernelModeTime', '=', true), 10); + let mem = parseInt(util.getValue(lines, 'WorkingSetSize', '=', true), 10); + allcpuu = allcpuu + utime; + allcpus = allcpus + stime; - if (resultProcess.pid) { + procStats = { + pid: pid, + utime: utime, + stime: stime, + pcpu: 0, + pcpuu: 0, + pcpus: 0, + }; + if (name.toLowerCase().indexOf(name.toLowerCase()) >= 0) { + result = { + proc: name, + pid: pid, + pids: [pid], + cpu: 0, + mem: mem / os.totalmem() * 100 + }; + } + } + result.sleeping = result.all - result.running - result.blocked - result.unknown; + result.list = procs; + for (let i = 0; i < procStats.length; i++) { + let resultProcess = calcProcStatWin(procStats[i], allcpuu + allcpus, _process_cpu); - // store pcpu in outer result - result.cpu += resultProcess.pcpuu + resultProcess.pcpus; + // store pcpu in outer array + let listPos = result.map(function (e) { return e.pid; }).indexOf(resultProcess.pid); + if (listPos >= 0) { + result.cpu = 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 + stime: resultProcess.stime }; } + // store old values + _process_cpu.all = allcpuu + allcpus; + _process_cpu.list = list_new; + _process_cpu.ms = Date.now() - _process_cpu.ms; + _process_cpu.result = result; + } + if (callback) { + callback(result); + } + resolve(result); + } + }); + } catch (e) { + if (callback) { callback(result); } + resolve(result); + } + } + + if (_darwin || _linux) { + exec('ps -axo pid,pcpu,pmem,comm | grep -i ' + proc + ' | grep -v grep', { maxBuffer: 1024 * 2000 }, function (error, stdout) { + if (!error) { + let lines = stdout.toString().split('\n'); + + let pid = 0; + let pids = []; + let cpu = 0; + let mem = 0; + + lines.forEach(function (line) { + let data = line.trim().replace(/ +/g, ' ').split(' '); + if (data.length > 3) { + pid = (!pid ? parseInt(data[0]) : 0); + pids.push(parseInt(data[0], 10)); + cpu = cpu + parseFloat(data[1].replace(',', '.')); + mem = mem + parseFloat(data[2].replace(',', '.')); + } + }); + + result = { + 'proc': proc, + 'pid': pid, + 'pids': pids, + 'cpu': parseFloat((cpu / lines.length).toFixed(2)), + 'mem': parseFloat((mem / lines.length).toFixed(2)) + }; + if (_linux) { + // calc process_cpu - ps is not accurate in linux! + let cmd = 'cat /proc/stat | grep "cpu "'; + for (let i = 0; i < result.pids.length; i++) { + cmd += (';cat /proc/' + result.pids[i] + '/stat'); } - result.cpu = Math.round(result.cpu * 100) / 100; + exec(cmd, { maxBuffer: 1024 * 2000 }, function (error, stdout) { + let curr_processes = stdout.toString().split('\n'); - _process_cpu.all = all; - _process_cpu.list = list_new; - _process_cpu.ms = Date.now() - _process_cpu.ms; - _process_cpu.result = result; + // first line (all - /proc/stat) + let all = parseProcStat(curr_processes.shift()); + + // process + let list_new = {}; + let resultProcess = {}; + result.cpu = 0; + for (let i = 0; i < curr_processes.length; i++) { + resultProcess = calcProcStatLinux(curr_processes[i], all, _process_cpu); + + if (resultProcess.pid) { + + // store pcpu in outer result + result.cpu += 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 + }; + } + } + + result.cpu = Math.round(result.cpu * 100) / 100; + + _process_cpu.all = all; + _process_cpu.list = list_new; + _process_cpu.ms = Date.now() - _process_cpu.ms; + _process_cpu.result = result; + if (callback) { callback(result); } + resolve(result); + }); + } else { if (callback) { callback(result); } resolve(result); - }); + } } else { if (callback) { callback(result); } resolve(result); } - } else { - if (callback) { callback(result); } - resolve(result); - } - }); - } else { - if (callback) { callback(result); } - resolve(result); + }); + } else { + if (callback) { callback(result); } + resolve(result); + } } }); });