UNPKG

psaux

Version:

Display processes info in Node

185 lines (157 loc) 4.82 kB
const execa = require('execa'); const os = require('os'); const platform = os.platform() if (platform === 'freebsd') { module.exports = getFreeBSDProcess; } else if (platform != "win32") { module.exports = getProcess; } else { module.exports = getWinProcess; } function getWinProcess(options) { return new Promise((resolve, reject) => { execa('powershell', ['-noprofile', '$perf = get-wmiobject -class Win32_PerfFormattedData_PerfProc_Process;$proc = get-wmiobject -class win32_process -Property *;$TotalMem = get-wmiobject -class win32_computersystem | select -ExpandProperty TotalPhysicalMemory; $proc | foreach { $procID = $_; $procPerf = $perf | where {$_.creatingProcessID -eq $procID.ProcessID}; $procID | select name, @{n="user"; e= {$user = $_.getOwner(); if($user.user){"{0}\{1}" -f $user.domain, $user.user}else {"System"}}}, @{n="command"; e={$_.CommandLine}}, @{n="pid";e={$_.ProcessID}}, @{n="memory (MB)";e={"{0:N3}" -f ($_.ws / 1mb)}}, @{n="memory (%)";e={"{0:N3}" -f ($_.ws / $TotalMem)}}, @{n="started";e={$_.converttoDateTime($_.CreationDate)}}, @{n="cpu"; e={$item = $_;$COUNT = 0;if($procPerf.percentProcessorTime){$procPerf.PercentProcessorTime | foreach {$count += $_};$percent = $count / $procPerf.PercentProcessorTime.length;"{0:N3}" -f [double]$percent;} else {"{0:N3}" -f 0}}}, @{n="vsz"; e={$_.VirtualSize}},@{n="rss"; e={$_.WorkingSetSize}},@{n="tt"; e={$_.SessionID}},@{n="time"; e={$_.KernelModeTime+ ($_.UserModeTime *10000)}}}|convertto-json' ]).then(result => { var processes; try { processes = JSON.parse(result.stdout); } catch (err) { processes = []; reject(err); } processes = processes.reduce(parseWinProcesses, []); processes.query = query; resolve(processes); }); }); } function parseWinProcesses(list, ps) { list.push({ user: ps["user"], pid: ps["pid"], cpu: parseFloat(ps["cpu"]), mem: parseFloat(ps["memory (%)"]), name: ps["name"], vsz: ps["vsz"], rss: ps["rss"], tt: ps["tt"], started: new Date(ps["started"].DateTime), time: ps["time"], command: ps["command"] }); return list; } function getFreeBSDProcess(options) { return new Promise((resolve, reject) => { execa('ps', ['auxww']).then(result => { var processes = result.stdout.split('\n'); //Remove header processes.shift(); processes = processes.reduce(parseProcesses, []); processes.query = query; resolve(processes); }); }); } function getProcess(options) { return new Promise((resolve, reject) => { execa('ps', ['aux']).then(result => { var processes = result.stdout.split('\n'); //Remove header processes.shift(); processes = processes.reduce(parseProcesses, []); processes.query = query; resolve(processes); }); }); } /** * Normalizes the process payload into a readable object. * * @param {Array} list * @param {Array} ps * @return {Array} */ function parseProcesses(list, ps) { var p = ps.split(/ +/); list.push({ user: p[0], pid: p[1], cpu: parseFloat(p[2]), mem: parseFloat(p[3]), vsz: p[4], rss: p[5], tt: p[6], stat: p[7], started: p[8], time: p[9], command: p.slice(10).join(' ') }); return list; } /** * Return elements that match a certain query: * * @example * list.query({ * user: 'root', * cpu: '>10', * mem: '>5 <10', * command: '~chrome' * }) * * @param {Object} q * @return {Array} */ function query(q) { var filter = Object.keys(q); var isValid; var valid; var val; return this.reduce((list, ps) => { isValid = filter.every(key => { val = q[key]; valid = true; if (typeof val === 'string') { if (val.indexOf('<') > -1) { valid = ps[key] < cleanValue(val, '<'); } if (valid && val.indexOf('>') > -1) { valid = ps[key] > cleanValue(val, '>'); } if (valid && val.indexOf('~') > -1) { valid = ps[key].indexOf(q[key].replace('~', '')) > -1; } } else { valid = ps[key] === val; } return valid; }); if (isValid) list.push(ps); return list; }, []); } /** * Return the value for a certain condition * * @example * cleanValue('foo <100', '<') == 100 * cleanValue('>5 <1 bar', '>') == 5 * * @param {String} val * @param {String} char * @return {Float} */ function cleanValue(val, char) { var num; var conditions = val.split(' '); var i = 0; while (!num && i < conditions.length) { if (conditions[i].indexOf(char) > -1) { num = conditions[i].replace(/<|>|~/g, ''); } i++; } return parseFloat(num); }