From 9feb6c28aafa24b575da41f9b3abbf0b8f320cf3 Mon Sep 17 00:00:00 2001 From: Sebastian Hildebrandt Date: Wed, 24 Aug 2016 12:12:18 +0200 Subject: [PATCH] added process list --- README.md | 9 ++- lib/index.js | 155 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 124 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 7139395..4f6d3fb 100644 --- a/README.md +++ b/README.md @@ -40,11 +40,12 @@ si.cpu() ### Latest Activity +- Version 3.3.0: added process list. Get full process list including details like cpu and mem usage, status, command, ... - Version 3.2.0: added battery support. If a battery is installed, you get information about status and current capacity level - Version 3.1.0: added [Docker][docker-url] support. Now you can scan your docker containers and get their stats - Version 3.0.0: added DisksIO - overall diskIO and IOPS values for all mounted volumes -I also created a little CLI-Tool called [mmon][mmon-github-url] (micro-monitor), also available via [github][mmon-github-url] and [npm][mmon-npm-url] +I also created a little command line tool called [mmon][mmon-github-url] (micro-monitor), also available via [github][mmon-github-url] and [npm][mmon-npm-url] Here all changes more detailed: @@ -64,6 +65,7 @@ Here all changes more detailed: New Functions +- `processes`: now returns also a process list with all process details (new in version 3.3) - `battery`: retrieves battery status and charging level (new in version 3.2) - `dockerContainers`: returns a list of all docker containers (new in version 3.1) - `dockerContainerStats`: returns statistics for a specific docker container (new in version 3.1) @@ -264,6 +266,8 @@ This library is splitted in several sections: | - all | X | X | # of all processes | | - running | X | X | # of all processes running | | - blocked | X | X | # of all processes blocked | +| - sleeping | X | X | # of all processes sleeping | +| - list | X | X | # list of all processes incl. details | | si.processLoad('apache2',cb) | X | X | detailed information about given process | | - proc | X | X | process name | | - pid | X | X | PID | @@ -365,6 +369,7 @@ I am happy to discuss any comments and suggestions. Please feel free to contact | Version | Date | Comment | | -------------- | -------------- | -------- | +| 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 | | 3.1.1 | 2016-08-18 | improved system and os detection (vm, ...), bugfix disksIO | @@ -416,7 +421,7 @@ Written by Sebastian Hildebrandt [sebhildebrandt](https://github.com/sebhildebra Linux is a registered trademark of Linus Torvalds, OS X is a registered trademark of Apple Inc., Windows is a registered trademark of Microsoft Corporation. Node.js is a trademark of Joyent Inc., Intel is a trademark of Intel Corporation, Raspberry Pi is a trademark of the Raspberry Pi Foundation, -Debian is a trademark of the Debian Project, Ubuntu is a trademark of Canonical Ltd. +Debian is a trademark of the Debian Project, Ubuntu is a trademark of Canonical Ltd., Docker is a trademarks of Docker, Inc. All other trademarks are the property of their respective owners. ## License [![MIT license][license-img]][license-url] diff --git a/lib/index.js b/lib/index.js index 1949e86..f214a58 100644 --- a/lib/index.js +++ b/lib/index.js @@ -80,9 +80,10 @@ // -------------------------------- // // version date comment +// 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 -// 3.1.1 2016-08-18 improved system and os detection (vm, ...), bugfix disksIO +// 3.1.1 2016-08-18 improved system and os detection (vm, ...), bug fix disksIO // 3.1.0 2016-08-18 added docker stats // 3.0.1 2016-08-17 Bug-Fix disksIO, users, updated docs // 3.0.0 2016-08-03 new major version 3.0 @@ -855,7 +856,7 @@ function battery(callback) { if (_darwin) { exec("ioreg -n AppleSmartBattery -r | grep '\"CycleCount\"';ioreg -n AppleSmartBattery -r | grep '\"IsCharging\"';ioreg -n AppleSmartBattery -r | grep '\"MaxCapacity\"';ioreg -n AppleSmartBattery -r | grep '\"CurrentCapacity\"'", function (error, stdout) { if (!error) { - let lines = stdout.toString().replace(/ +/g, "").replace(/\"+/g, "").split('\n'); + let lines = stdout.toString().replace(/ +/g, "").replace(/"+/g, "").split('\n'); lines.forEach(function (line) { if (line.indexOf('=') != -1) { if (line.toLowerCase().indexOf('cyclecount') != -1) result.cyclecount = parseFloat(line.split('=')[1].trim()); @@ -1667,6 +1668,98 @@ exports.services = services; function processes(callback) { + let parsedhead = []; + + function parseHead(head, rights) { + let space = (rights > 0); + let count = 1; + let from = 0; + let to = 0; + let result = []; + for (let i = 0; i < head.length; i++) { + if (count <= rights) { + if (head[i] == ' ' && !space) { + to = i - 1; + result.push({ + from: from, + to: to+1, + cap: head.substring(from, to+1) + }); + from = to + 2; + count++; + } + space = head[i] == ' '; + } else { + if (head[i] != ' ' && space) { + to = i - 1; + if (from < to) { + result.push({ + from: from, + to: to, + cap: head.substring(from, to) + }); + } + from = to + 1; + count++; + } + space = head[i] == ' '; + } + } + to = 1000; + result.push({ + from: from, + to: to, + cap: head.substring(from, to) + }); + return result; + + } + + function parseLine(line) { + let pid = parseInt(line.substring(parsedhead[0].from,parsedhead[0].to)); + let pcpu = parseFloat(line.substring(parsedhead[1].from,parsedhead[1].to).replace(/,/g, ".")); + let pmem = parseFloat(line.substring(parsedhead[2].from,parsedhead[2].to).replace(/,/g, ".")); + let priority = parseInt(line.substring(parsedhead[3].from,parsedhead[3].to)); + let vsz = parseInt(line.substring(parsedhead[4].from,parsedhead[4].to)); + let rss = parseInt(line.substring(parsedhead[5].from,parsedhead[5].to)); + let started = line.substring(parsedhead[6].from,parsedhead[6].to).trim(); + let state = line.substring(parsedhead[7].from,parsedhead[7].to).trim(); + state = (state[0] == 'R' ? 'running': (state[0] == 'S' ? 'sleeping': (state[0] == 'T' ? 'stopped': (state[0] == 'W' ? 'paging': (state[0] == 'X' ? 'dead': (state[0] == 'Z' ? 'zombie': ((state[0] == 'D' || state[0] == 'U') ? 'blocked': 'unknown'))))))); + let tty = line.substring(parsedhead[8].from,parsedhead[8].to).trim(); + if (tty == '?' || tty == '??') tty = ''; + let user = line.substring(parsedhead[9].from,parsedhead[9].to).trim(); + let command = line.substring(parsedhead[10].from,parsedhead[10].to).trim().replace(/\[/g, "").replace(/]/g, ""); + + return ({ + pid: pid, + pcpu: pcpu, + pmem: pmem, + priority: priority, + mem_vsz: vsz, + mem_rss: rss, + started: started, + state: state, + tty: tty, + user: user, + command: command + }) + } + + function parseProcesses(lines) { + let result = []; + if (lines.length > 1) { + let head = lines[0]; + parsedhead = parseHead(head, 7); + lines.shift(); + lines.forEach(function (line) { + if (line.trim() != '') { + result.push(parseLine(line)); + } + }); + } + return result; + } + return new Promise((resolve, reject) => { process.nextTick(() => { if (_windows) { @@ -1674,47 +1767,33 @@ function processes(callback) { if (callback) { callback(NOT_SUPPORTED) } reject(error); } - - var result = { + let result = { all: 0, running: 0, - blocked: 0 + blocked: 0, + sleeping: 0, + list: [] }; - exec("ps aux | grep -v 'ps aux' | wc -l", function (error, stdout) { + + 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 (_darwin) cmd = "ps acxo pid,pcpu,pmem,pri,vsz,rss,start,state,tty,user,command -r"; + exec(cmd, function (error, stdout) { if (!error) { - result.all = parseInt(stdout.toString()); - if (_darwin) { - exec("ps axo state | grep 'R' | wc -l; ps axo state | grep 'U' | wc -l", function (error, stdout) { - if (!error) { - let lines = stdout.toString().split('\n'); - result.running = parseInt(lines[0]); - result.blocked = parseInt(lines[1]); - } - if (callback) { callback(result) } - resolve(result); - }) - } - if (_linux) { - exec("cat /proc/stat | grep procs_", function (error, stdout) { - if (!error) { - let lines = stdout.toString().split('\n'); - lines.forEach(function (line) { - if (line.toUpperCase().indexOf('PROCS_RUNNING') != -1) { - result.running = parseInt(line.replace(/ +/g, " ").split(' ')[1]); - } - if (line.toUpperCase().indexOf('PROCS_BLOCKED') != -1) { - result.blocked = parseInt(line.replace(/ +/g, " ").split(' ')[1]); - } - }) - } - if (callback) { callback(result) } - resolve(result); - }) - } - } else { - if (callback) { callback(result) } - resolve(result); + result.list = parseProcesses(stdout.toString().split('\n')); + result.all = result.list.length; + result.running = result.list.filter(function (e) { + return e.state == 'running' + }).length; + result.blocked = result.list.filter(function (e) { + return e.state == 'blocked' + }).length; + result.sleeping = result.list.filter(function (e) { + return e.state == 'sleeping' + }).length } + if (callback) { callback(result) } + resolve(result); }); }); });