extended windows support processes()

This commit is contained in:
Sebastian Hildebrandt 2017-09-14 15:11:10 +02:00
parent c25c24e99f
commit 53cd61b67e
11 changed files with 350 additions and 278 deletions

View File

@ -98,6 +98,7 @@ Other changes
| Version | Date | Comment | | Version | Date | Comment |
| -------------- | -------------- | -------- | | -------------- | -------------- | -------- |
| 3.28.0 | 2017-09-14 | extended windows support `processes()` |
| 3.27.1 | 2017-09-13 | updated Raspberry version detection `system()` (Pi 3, Zero) | | 3.27.1 | 2017-09-13 | updated Raspberry version detection `system()` (Pi 3, Zero) |
| 3.27.0 | 2017-09-12 | added raw data to `currentLoad()`, fixed `networkInterfaces()` MAC problem node 8.x | | 3.27.0 | 2017-09-12 | added raw data to `currentLoad()`, fixed `networkInterfaces()` MAC problem node 8.x |
| 3.26.2 | 2017-09-01 | removed redundant code | | 3.26.2 | 2017-09-01 | removed redundant code |

View File

@ -50,6 +50,7 @@ async function cpu() {
## News and Changes ## News and Changes
### Latest Activity ### Latest Activity
- Version 3.28.0: extended windows support `processes()`
- Version 3.27.0: added raw data to `currentLoad()`, fixed `networkInterfaces()` MAC problem node 8.x - Version 3.27.0: added raw data to `currentLoad()`, fixed `networkInterfaces()` MAC problem node 8.x
- Version 3.26.0: improved windows support `getDynamicData()`, updated docs - Version 3.26.0: improved windows support `getDynamicData()`, updated docs
- Version 3.25.0: improved windows support `networkStats()`, `cpuCache()`, bug fix `getStaticData()` - Version 3.25.0: improved windows support `networkStats()`, `cpuCache()`, bug fix `getStaticData()`
@ -329,26 +330,28 @@ I also created a nice little command line tool called [mmon][mmon-github-url] (
| | raw_currentload... | X | X | X | CPU-Load raw values (ticks) | | | raw_currentload... | X | X | X | CPU-Load raw values (ticks) |
| | cpus[] | X | X | X | current loads per CPU in % + raw ticks | | | cpus[] | X | X | X | current loads per CPU in % + raw ticks |
| si.fullLoad(cb) | : integer | X | X | X | CPU-full load since bootup in % | | si.fullLoad(cb) | : integer | X | X | X | CPU-full load since bootup in % |
| si.processes(cb) | {...} | X | X | | # running processes | | si.processes(cb) | {...} | X | X | X | # running processes |
| | all | X | X | | # of all processes | | | all | X | X | X | # of all processes |
| | running | X | X | | # of all processes running | | | running | X | X | X | # of all processes running |
| | blocked | X | X | | # of all processes blocked | | | blocked | X | X | X | # of all processes blocked |
| | sleeping | X | X | | # of all processes sleeping | | | sleeping | X | X | X | # of all processes sleeping |
| | list[] | X | X | | list of all processes incl. details | | | unknown | | | X | # of all processes unknown status |
| | ...[0].pid | X | X | | process PID | | | list[] | X | X | X | list of all processes incl. details |
| | ...[0].pcpu | X | X | | process % CPU usage | | | ...[0].pid | X | X | X | process PID |
| | ...[0].pcpuu | X | | | process % CPU usage (user) | | | ...[0].name | X | X | X | process name |
| | ...[0].pcpus | X | | | process % CPU usage (system) | | | ...[0].pcpu | X | X | X | process % CPU usage |
| | ...[0].pmem | X | X | | process memory % | | | ...[0].pcpuu | X | | X | process % CPU usage (user) |
| | ...[0].priority | X | X | | process priotity | | | ...[0].pcpus | X | | X | process % CPU usage (system) |
| | ...[0].mem_vsz | X | X | | process virtual memory size | | | ...[0].pmem | X | X | X | process memory % |
| | ...[0].mem_rss | X | X | | process mem resident set size | | | ...[0].priority | X | X | X | process priotity |
| | ...[0].mem_vsz | X | X | X | process virtual memory size |
| | ...[0].mem_rss | X | X | X | process mem resident set size |
| | ...[0].nice | X | X | | process nice value | | | ...[0].nice | X | X | | process nice value |
| | ...[0].started | X | X | | process start time | | | ...[0].started | X | X | X | process start time |
| | ...[0].state | X | X | | process state (e.g. sleeping) | | | ...[0].state | X | X | X | process state (e.g. sleeping) |
| | ...[0].tty | X | X | | tty from which process was started | | | ...[0].tty | X | X | | tty from which process was started |
| | ...[0].user | X | X | | user who started process | | | ...[0].user | X | X | | user who started process |
| | ...[0].command | X | X | | process starting command | | | ...[0].command | X | X | X | process starting command |
| si.processLoad('apache2',cb) | {...} | X | X | | detailed information about given process | | si.processLoad('apache2',cb) | {...} | X | X | | detailed information about given process |
| | proc | X | X | | process name | | | proc | X | X | | process name |
| | pid | X | X | | PID | | | pid | X | X | | PID |

View File

@ -24,20 +24,6 @@ const _darwin = (_platform === 'Darwin');
const _windows = (_platform === 'Windows_NT'); const _windows = (_platform === 'Windows_NT');
const NOT_SUPPORTED = 'not supported'; const NOT_SUPPORTED = 'not supported';
function getValue(lines, property, separator) {
separator = separator || ':';
property = property.toLowerCase();
for (let i = 0; i < lines.length; i++) {
if (lines[i].toLowerCase().startsWith(property)) {
const parts = lines[i].split(separator);
if (parts.length > 1) {
return parts[1].trim();
}
}
}
return '';
}
module.exports = function (callback) { module.exports = function (callback) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -119,12 +105,12 @@ module.exports = function (callback) {
exec("WMIC Path Win32_Battery Get BatteryStatus, DesignCapacity, EstimatedChargeRemaining /value", function (error, stdout) { exec("WMIC Path Win32_Battery Get BatteryStatus, DesignCapacity, EstimatedChargeRemaining /value", function (error, stdout) {
if (stdout) { if (stdout) {
let lines = stdout.split('\r\n'); let lines = stdout.split('\r\n');
let status = getValue(lines, 'BatteryStatus', '=').trim(); let status = util.getValue(lines, 'BatteryStatus', '=').trim();
if (status) { if (status) {
status = parseInt(status || '2'); status = parseInt(status || '2');
result.hasbattery = true; result.hasbattery = true;
result.maxcapacity = parseInt(getValue(lines, 'DesignCapacity', '=') || 0); result.maxcapacity = parseInt(util.getValue(lines, 'DesignCapacity', '=') || 0);
result.percent = parseInt(getValue(lines, 'EstimatedChargeRemaining', '=') || 0); result.percent = parseInt(util.getValue(lines, 'EstimatedChargeRemaining', '=') || 0);
result.currentcapacity = parseInt(result.maxcapacity * result.percent / 100); result.currentcapacity = parseInt(result.maxcapacity * result.percent / 100);
result.ischarging = (status >= 6 && status <= 9) || (!(status === 3) && !(status === 1) && result.percent < 100); result.ischarging = (status >= 6 && status <= 9) || (!(status === 3) && !(status === 1) && result.percent < 100);
} }

View File

@ -63,20 +63,6 @@ function cpuBrandManufacturer(res) {
return res; return res;
} }
function getValue(lines, property, separator) {
separator = separator || ':';
property = property.toLowerCase();
for (let i = 0; i < lines.length; i++) {
if (lines[i].toLowerCase().startsWith(property)) {
const parts = lines[i].split(separator);
if (parts.length > 1) {
return parts[1].trim();
}
}
}
return '';
}
// -------------------------- // --------------------------
// CPU - brand, speed // CPU - brand, speed
@ -103,18 +89,18 @@ function getCpu() {
exec("sysctl machdep.cpu hw.cpufrequency_max hw.cpufrequency_min", function (error, stdout) { exec("sysctl machdep.cpu hw.cpufrequency_max hw.cpufrequency_min", function (error, stdout) {
if (!error) { if (!error) {
let lines = stdout.toString().split('\n'); let lines = stdout.toString().split('\n');
const modelline = getValue(lines, 'machdep.cpu.brand_string'); const modelline = util.getValue(lines, 'machdep.cpu.brand_string');
result.brand = modelline.split('@')[0].trim(); result.brand = modelline.split('@')[0].trim();
result.speed = modelline.split('@')[1].trim(); result.speed = modelline.split('@')[1].trim();
result.speed = parseFloat(result.speed.replace(/GHz+/g, "")).toFixed(2); result.speed = parseFloat(result.speed.replace(/GHz+/g, "")).toFixed(2);
_cpu_speed = result.speed; _cpu_speed = result.speed;
result = cpuBrandManufacturer(result); result = cpuBrandManufacturer(result);
result.speedmin = (getValue(lines, 'hw.cpufrequency_min') / 1000000000.0 ).toFixed(2); result.speedmin = (util.getValue(lines, 'hw.cpufrequency_min') / 1000000000.0 ).toFixed(2);
result.speedmax = (getValue(lines, 'hw.cpufrequency_max') / 1000000000.0 ).toFixed(2); result.speedmax = (util.getValue(lines, 'hw.cpufrequency_max') / 1000000000.0 ).toFixed(2);
result.vendor = getValue(lines, 'machdep.cpu.vendor'); result.vendor = util.getValue(lines, 'machdep.cpu.vendor');
result.family = getValue(lines, 'machdep.cpu.family'); result.family = util.getValue(lines, 'machdep.cpu.family');
result.model = getValue(lines, 'machdep.cpu.model'); result.model = util.getValue(lines, 'machdep.cpu.model');
result.stepping = getValue(lines, 'machdep.cpu.stepping'); result.stepping = util.getValue(lines, 'machdep.cpu.stepping');
} }
cpuCache().then(res => { cpuCache().then(res => {
@ -127,7 +113,7 @@ function getCpu() {
exec("export LC_ALL=C; lscpu; unset LC_ALL", function (error, stdout) { exec("export LC_ALL=C; lscpu; unset LC_ALL", function (error, stdout) {
if (!error) { if (!error) {
let lines = stdout.toString().split('\n'); let lines = stdout.toString().split('\n');
const modelline = getValue(lines, 'model name'); const modelline = util.getValue(lines, 'model name');
result.brand = modelline.split('@')[0].trim(); result.brand = modelline.split('@')[0].trim();
result.speed = modelline.split('@')[1] ? parseFloat(modelline.split('@')[1].trim()).toFixed(2) : '0.00'; result.speed = modelline.split('@')[1] ? parseFloat(modelline.split('@')[1].trim()).toFixed(2) : '0.00';
if (result.speed === '0.00') { if (result.speed === '0.00') {
@ -135,27 +121,27 @@ function getCpu() {
if (current !== '0.00') result.speed = current; if (current !== '0.00') result.speed = current;
} }
_cpu_speed = result.speed; _cpu_speed = result.speed;
result.speedmin = Math.round(parseFloat(getValue(lines, 'cpu min mhz').replace(/,/g, '.')) / 10.0) / 100; result.speedmin = Math.round(parseFloat(util.getValue(lines, 'cpu min mhz').replace(/,/g, '.')) / 10.0) / 100;
result.speedmin = result.speedmin ? parseFloat(result.speedmin).toFixed(2) : '' result.speedmin = result.speedmin ? parseFloat(result.speedmin).toFixed(2) : ''
result.speedmax = Math.round(parseFloat(getValue(lines, 'cpu max mhz').replace(/,/g, '.')) / 10.0) / 100; result.speedmax = Math.round(parseFloat(util.getValue(lines, 'cpu max mhz').replace(/,/g, '.')) / 10.0) / 100;
result.speedmax = result.speedmax ? parseFloat(result.speedmax).toFixed(2) : '' result.speedmax = result.speedmax ? parseFloat(result.speedmax).toFixed(2) : ''
result = cpuBrandManufacturer(result); result = cpuBrandManufacturer(result);
result.vendor = getValue(lines, 'vendor id'); result.vendor = util.getValue(lines, 'vendor id');
// if (!result.vendor) { result.vendor = getValue(lines, 'anbieterkennung'); } // if (!result.vendor) { result.vendor = util.getValue(lines, 'anbieterkennung'); }
result.family = getValue(lines, 'cpu family'); result.family = util.getValue(lines, 'cpu family');
// if (!result.family) { result.family = getValue(lines, 'prozessorfamilie'); } // if (!result.family) { result.family = util.getValue(lines, 'prozessorfamilie'); }
result.model = getValue(lines, 'model:'); result.model = util.getValue(lines, 'model:');
// if (!result.model) { result.model = getValue(lines, 'modell:'); } // if (!result.model) { result.model = util.getValue(lines, 'modell:'); }
result.stepping = getValue(lines, 'stepping'); result.stepping = util.getValue(lines, 'stepping');
result.revision = getValue(lines, 'cpu revision'); result.revision = util.getValue(lines, 'cpu revision');
result.cache.l1d = getValue(lines, 'l1d cache'); result.cache.l1d = util.getValue(lines, 'l1d cache');
if (result.cache.l1d) { result.cache.l1d = parseInt(result.cache.l1d) * (result.cache.l1d.indexOf('K') !== -1 ? 1024 : 1)} if (result.cache.l1d) { result.cache.l1d = parseInt(result.cache.l1d) * (result.cache.l1d.indexOf('K') !== -1 ? 1024 : 1)}
result.cache.l1i = getValue(lines, 'l1i cache'); result.cache.l1i = util.getValue(lines, 'l1i cache');
if (result.cache.l1i) { result.cache.l1i = parseInt(result.cache.l1i) * (result.cache.l1i.indexOf('K') !== -1 ? 1024 : 1)} if (result.cache.l1i) { result.cache.l1i = parseInt(result.cache.l1i) * (result.cache.l1i.indexOf('K') !== -1 ? 1024 : 1)}
result.cache.l2 = getValue(lines, 'l2 cache'); result.cache.l2 = util.getValue(lines, 'l2 cache');
if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2) * (result.cache.l2.indexOf('K') !== -1 ? 1024 : 1)} if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2) * (result.cache.l2.indexOf('K') !== -1 ? 1024 : 1)}
result.cache.l3 = getValue(lines, 'l3 cache'); result.cache.l3 = util.getValue(lines, 'l3 cache');
if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3) * (result.cache.l3.indexOf('K') !== -1 ? 1024 : 1)} if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3) * (result.cache.l3.indexOf('K') !== -1 ? 1024 : 1)}
} else { } else {
@ -167,7 +153,7 @@ function getCpu() {
exec("wmic cpu get name, description, revision, l2cachesize, l3cachesize, manufacturer, currentclockspeed, maxclockspeed /value", function (error, stdout) { exec("wmic cpu get name, description, revision, l2cachesize, l3cachesize, manufacturer, currentclockspeed, maxclockspeed /value", function (error, stdout) {
if (!error) { if (!error) {
let lines = stdout.split('\r\n'); let lines = stdout.split('\r\n');
let name = getValue(lines, 'name', '=') || ''; let name = util.getValue(lines, 'name', '=') || '';
if (name.indexOf('@') >= 0) { if (name.indexOf('@') >= 0) {
result.brand = name.split('@')[0].trim(); result.brand = name.split('@')[0].trim();
result.speed = name.split('@')[1].trim(); result.speed = name.split('@')[1].trim();
@ -178,21 +164,21 @@ function getCpu() {
result.speed = 0; result.speed = 0;
} }
result = cpuBrandManufacturer(result); result = cpuBrandManufacturer(result);
result.revision = getValue(lines, 'revision', '='); result.revision = util.getValue(lines, 'revision', '=');
result.cache.l1d = 0; result.cache.l1d = 0;
result.cache.l1i = 0; result.cache.l1i = 0;
result.cache.l2 = getValue(lines, 'l2cachesize', '='); result.cache.l2 = util.getValue(lines, 'l2cachesize', '=');
result.cache.l3 = getValue(lines, 'l3cachesize', '='); result.cache.l3 = util.getValue(lines, 'l3cachesize', '=');
if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2) * 1024} if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2) * 1024}
if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3) * 1024} if (result.cache.l3) { result.cache.l3 = parseInt(result.cache.l3) * 1024}
result.vendor = getValue(lines, 'manufacturer', '='); result.vendor = util.getValue(lines, 'manufacturer', '=');
result.speedmax = Math.round(parseFloat(getValue(lines, 'maxclockspeed', '=').replace(/,/g, '.')) / 10.0) / 100; result.speedmax = Math.round(parseFloat(util.getValue(lines, 'maxclockspeed', '=').replace(/,/g, '.')) / 10.0) / 100;
result.speedmax = result.speedmax ? parseFloat(result.speedmax).toFixed(2) : ''; result.speedmax = result.speedmax ? parseFloat(result.speedmax).toFixed(2) : '';
if (!result.speed) { if (!result.speed) {
result.speed = result.speedmax result.speed = result.speedmax
} }
let description = getValue(lines, 'description', '=').split(' '); let description = util.getValue(lines, 'description', '=').split(' ');
for (let i = 0; i < description.length; i++) { for (let i = 0; i < description.length; i++) {
if (description[i].toLowerCase().startsWith('family') && (i+1) < description.length && description[i+1]) { if (description[i].toLowerCase().startsWith('family') && (i+1) < description.length && description[i+1]) {
result.family = description[i+1] result.family = description[i+1]
@ -510,8 +496,8 @@ function cpuCache(callback) {
let lines = stdout.split('\r\n'); let lines = stdout.split('\r\n');
result.l1d = 0; result.l1d = 0;
result.l1i = 0; result.l1i = 0;
result.l2 = getValue(lines, 'l2cachesize', '='); result.l2 = util.getValue(lines, 'l2cachesize', '=');
result.l3 = getValue(lines, 'l3cachesize', '='); result.l3 = util.getValue(lines, 'l3cachesize', '=');
if (result.l2) { result.l2 = parseInt(result.l2) * 1024} if (result.l2) { result.l2 = parseInt(result.l2) * 1024}
if (result.l3) { result.l3 = parseInt(result.l3) * 1024} if (result.l3) { result.l3 = parseInt(result.l3) * 1024}
} }

View File

@ -28,27 +28,6 @@ const NOT_SUPPORTED = 'not supported';
let _fs_speed = {}; let _fs_speed = {};
let _disk_io = {}; let _disk_io = {};
function getValue(lines, property, separator, trimmed) {
separator = separator || ':';
property = property.toLowerCase();
for (let i = 0; i < lines.length; i++) {
let line = lines[i].toLowerCase();
if (trimmed) {
line = line.trim();
}
if (line.toLowerCase().startsWith(property)) {
const parts = lines[i].split(separator);
if (parts.length >= 2) {
parts.shift();
return parts.join(':').trim();
} else {
return ''
}
}
}
return '';
}
// -------------------------- // --------------------------
// FS - mounted file systems // FS - mounted file systems
@ -598,18 +577,18 @@ function diskLayout(callback) {
devices.forEach(function (device) { devices.forEach(function (device) {
let lines = device.split('\n'); let lines = device.split('\n');
let mediumType = ''; let mediumType = '';
const logical = getValue(lines, 'logical name', ':', true).trim().replace(/\/dev\//g, ''); const logical = util.getValue(lines, 'logical name', ':', true).trim().replace(/\/dev\//g, '');
try { try {
mediumType = execSync('cat /sys/block/' + logical + '/queue/rotational').toString().split('\n')[0]; mediumType = execSync('cat /sys/block/' + logical + '/queue/rotational').toString().split('\n')[0];
} catch (e) { } catch (e) {
} }
const size = getValue(lines, 'size', ':', true).trim(); const size = util.getValue(lines, 'size', ':', true).trim();
if (size && lines.length > 0 && lines[0].trim() === 'disk') { if (size && lines.length > 0 && lines[0].trim() === 'disk') {
result.push({ result.push({
type: (mediumType === '0' ? 'SSD' : (mediumType === '1' ? 'HD' : (device.indexOf('SSD') > -1 ? 'SSD' : 'HD'))), // to be tested ... /sys/block/sda/queue/rotational type: (mediumType === '0' ? 'SSD' : (mediumType === '1' ? 'HD' : (device.indexOf('SSD') > -1 ? 'SSD' : 'HD'))), // to be tested ... /sys/block/sda/queue/rotational
name: getValue(lines, 'product:', ':', true), name: util.getValue(lines, 'product:', ':', true),
vendor: getValue(lines, 'vendor:', ':', true), vendor: util.getValue(lines, 'vendor:', ':', true),
size: parseInt(size.match(/\(([^)]+)\)/)[1]) * 1000 * 1000 * 1000 * 1000, size: parseInt(size.match(/\(([^)]+)\)/)[1]) * 1000 * 1000 * 1000 * 1000,
bytesPerSector: -1, bytesPerSector: -1,
totalCylinders: -1, totalCylinders: -1,
@ -618,8 +597,8 @@ function diskLayout(callback) {
totalTracks: -1, totalTracks: -1,
tracksPerCylinder: -1, tracksPerCylinder: -1,
sectorsPerTrack: -1, sectorsPerTrack: -1,
firmwareRevision: getValue(lines, 'version:', ':', true).trim(), firmwareRevision: util.getValue(lines, 'version:', ':', true).trim(),
serialNum: getValue(lines, 'serial:', ':', true).trim(), serialNum: util.getValue(lines, 'serial:', ':', true).trim(),
interfaceType: '', interfaceType: '',
}) })
} }
@ -639,8 +618,8 @@ function diskLayout(callback) {
devices.shift(); devices.shift();
devices.forEach(function (device) { devices.forEach(function (device) {
let lines = device.split('\n'); let lines = device.split('\n');
const mediumType = getValue(lines, 'Medium Type', ':', true).trim(); const mediumType = util.getValue(lines, 'Medium Type', ':', true).trim();
const sizeStr = getValue(lines, 'capacity', ':', true).trim(); const sizeStr = util.getValue(lines, 'capacity', ':', true).trim();
if (sizeStr) { if (sizeStr) {
let size = parseInt(sizeStr.match(/\(([^)]+)\)/)[1].replace(/\./g, "")); let size = parseInt(sizeStr.match(/\(([^)]+)\)/)[1].replace(/\./g, ""));
if (!size) { if (!size) {
@ -649,7 +628,7 @@ function diskLayout(callback) {
if (size) { if (size) {
result.push({ result.push({
type: mediumType.startsWith('Solid') ? 'SSD' : 'HD', type: mediumType.startsWith('Solid') ? 'SSD' : 'HD',
name: getValue(lines, 'Model', ':', true).trim(), name: util.getValue(lines, 'Model', ':', true).trim(),
vendor: '', vendor: '',
size: size, size: size,
bytesPerSector: -1, bytesPerSector: -1,
@ -659,9 +638,9 @@ function diskLayout(callback) {
totalTracks: -1, totalTracks: -1,
tracksPerCylinder: -1, tracksPerCylinder: -1,
sectorsPerTrack: -1, sectorsPerTrack: -1,
firmwareRevision: getValue(lines, 'Revision', ':', true).trim(), firmwareRevision: util.getValue(lines, 'Revision', ':', true).trim(),
serialNum: getValue(lines, 'Serial Number', ':', true).trim(), serialNum: util.getValue(lines, 'Serial Number', ':', true).trim(),
interfaceType: getValue(lines, 'InterfaceType', ':', true).trim() interfaceType: util.getValue(lines, 'InterfaceType', ':', true).trim()
}) })
} }
} }
@ -680,23 +659,23 @@ function diskLayout(callback) {
let devices = stdout.toString().split('\r\n\r\n\r\n'); let devices = stdout.toString().split('\r\n\r\n\r\n');
devices.forEach(function (device) { devices.forEach(function (device) {
let lines = device.split('\r\n'); let lines = device.split('\r\n');
const size = getValue(lines, 'Size', '=').trim(); const size = util.getValue(lines, 'Size', '=').trim();
if (size) { if (size) {
result.push({ result.push({
type: device.indexOf('SSD') > -1 ? 'SSD' : 'HD', // not really correct(!) ... maybe this obe is better: MSFT_PhysicalDisk - Media Type?? type: device.indexOf('SSD') > -1 ? 'SSD' : 'HD', // not really correct(!) ... maybe this obe is better: MSFT_PhysicalDisk - Media Type??
name: getValue(lines, 'Caption', '='), name: util.getValue(lines, 'Caption', '='),
vendor: getValue(lines, 'Manufacturer', '='), vendor: util.getValue(lines, 'Manufacturer', '='),
size: parseInt(size), size: parseInt(size),
bytesPerSector: parseInt(getValue(lines, 'BytesPerSector', '=')), bytesPerSector: parseInt(util.getValue(lines, 'BytesPerSector', '=')),
totalCylinders: parseInt(getValue(lines, 'TotalCylinders', '=')), totalCylinders: parseInt(util.getValue(lines, 'TotalCylinders', '=')),
totalHeads: parseInt(getValue(lines, 'TotalHeads', '=')), totalHeads: parseInt(util.getValue(lines, 'TotalHeads', '=')),
totalSectors: parseInt(getValue(lines, 'TotalSectors', '=')), totalSectors: parseInt(util.getValue(lines, 'TotalSectors', '=')),
totalTracks: parseInt(getValue(lines, 'TotalTracks', '=')), totalTracks: parseInt(util.getValue(lines, 'TotalTracks', '=')),
tracksPerCylinder: parseInt(getValue(lines, 'TracksPerCylinder', '=')), tracksPerCylinder: parseInt(util.getValue(lines, 'TracksPerCylinder', '=')),
sectorsPerTrack: parseInt(getValue(lines, 'SectorsPerTrack', '=')), sectorsPerTrack: parseInt(util.getValue(lines, 'SectorsPerTrack', '=')),
firmwareRevision: getValue(lines, 'FirmwareRevision', '=').trim(), firmwareRevision: util.getValue(lines, 'FirmwareRevision', '=').trim(),
serialNum: getValue(lines, 'SerialNumber', '=').trim(), serialNum: util.getValue(lines, 'SerialNumber', '=').trim(),
interfaceType: getValue(lines, 'InterfaceType', '=').trim() interfaceType: util.getValue(lines, 'InterfaceType', '=').trim()
}) })
} }
}); });

View File

@ -27,20 +27,6 @@ let _resolutionx = 0;
let _resolutiony = 0; let _resolutiony = 0;
let _pixeldepth = 0; let _pixeldepth = 0;
function getValue(lines, property, separator) {
separator = separator || ':';
property = property.toLowerCase();
for (let i = 0; i < lines.length; i++) {
if (lines[i].toLowerCase().startsWith(property)) {
const parts = lines[i].split(separator);
if (parts.length > 1) {
return parts[1].trim();
}
}
}
return '';
}
function toInt(value) { function toInt(value) {
let result = parseInt(value,10); let result = parseInt(value,10);
if (isNaN(result)) { if (isNaN(result)) {
@ -363,15 +349,15 @@ function graphics(callback) {
let lines = sections[i].trim().split('\r\n'); let lines = sections[i].trim().split('\r\n');
controllers.push({ controllers.push({
model: getValue(lines, 'name', '='), model: util.getValue(lines, 'name', '='),
vendor: getValue(lines, 'AdapterCompatibility', '='), vendor: util.getValue(lines, 'AdapterCompatibility', '='),
bus: getValue(lines, 'PNPDeviceID', '=').startsWith('PCI') ? 'PCI' : '', bus: util.getValue(lines, 'PNPDeviceID', '=').startsWith('PCI') ? 'PCI' : '',
vram: getValue(lines, 'AdapterRAM', '='), vram: util.getValue(lines, 'AdapterRAM', '='),
vramDynamic: (getValue(lines, 'VideoMemoryType', '=') === '2') vramDynamic: (util.getValue(lines, 'VideoMemoryType', '=') === '2')
}); });
_resolutionx = toInt(getValue(lines, 'CurrentHorizontalResolution', '=')); _resolutionx = toInt(util.getValue(lines, 'CurrentHorizontalResolution', '='));
_resolutiony = toInt(getValue(lines, 'CurrentVerticalResolution', '=')); _resolutiony = toInt(util.getValue(lines, 'CurrentVerticalResolution', '='));
_pixeldepth = toInt(getValue(lines, 'CurrentBitsPerPixel', '=')); _pixeldepth = toInt(util.getValue(lines, 'CurrentBitsPerPixel', '='));
} }
} }
} }
@ -385,9 +371,9 @@ function graphics(callback) {
if (sections[i].trim() !== "") { if (sections[i].trim() !== "") {
let lines = sections[i].trim().split('\r\n'); let lines = sections[i].trim().split('\r\n');
displays.push({ displays.push({
model: getValue(lines, 'MonitorManufacturer', '='), model: util.getValue(lines, 'MonitorManufacturer', '='),
resolutionx: toInt(getValue(lines, 'ScreenWidth', '=')), resolutionx: toInt(util.getValue(lines, 'ScreenWidth', '=')),
resolutiony: toInt(getValue(lines, 'ScreenHeight', '=')), resolutiony: toInt(util.getValue(lines, 'ScreenHeight', '=')),
}); });
} }
} }

View File

@ -24,26 +24,6 @@ const _darwin = (_platform === 'Darwin');
const _windows = (_platform === 'Windows_NT'); const _windows = (_platform === 'Windows_NT');
const NOT_SUPPORTED = 'not supported'; const NOT_SUPPORTED = 'not supported';
function getValue(lines, property, separator, trimmed) {
separator = separator || ':';
property = property.toLowerCase();
for (let i = 0; i < lines.length; i++) {
let line = lines[i].toLowerCase();
if (trimmed) {
line = line.trim();
}
if (line.toLowerCase().startsWith(property)) {
const parts = lines[i].split(separator);
if (parts.length >= 2) {
parts.shift();
return parts.join(':').trim();
} else {
return ''
}
}
}
return '';
}
// _______________________________________________________________________________________ // _______________________________________________________________________________________
// | R A M | H D | // | R A M | H D |
// |______________________|_________________________| | | // |______________________|_________________________| | |
@ -213,16 +193,16 @@ function memLayout(callback) {
devices.forEach(function (device) { devices.forEach(function (device) {
let lines = device.split('\n'); let lines = device.split('\n');
result.push({ result.push({
size: parseInt(getValue(lines, ' Size'))*1024*1024, size: parseInt(util.getValue(lines, ' Size'))*1024*1024,
bank: getValue(lines, ' Bank Locator'), bank: util.getValue(lines, ' Bank Locator'),
type: getValue(lines, ' Type:'), type: util.getValue(lines, ' Type:'),
clockSpeed: (getValue(lines, ' Configured Clock Speed:') ? parseInt(getValue(lines, ' Configured Clock Speed:')) : parseInt(getValue(lines, ' Speed:'))), clockSpeed: (util.getValue(lines, ' Configured Clock Speed:') ? parseInt(util.getValue(lines, ' Configured Clock Speed:')) : parseInt(util.getValue(lines, ' Speed:'))),
formFactor: getValue(lines, ' Form Factor:'), formFactor: util.getValue(lines, ' Form Factor:'),
partNum: '', partNum: '',
serialNum: getValue(lines, ' Serial Number:'), serialNum: util.getValue(lines, ' Serial Number:'),
voltageConfigured: parseFloat(getValue(lines, ' Configured Voltage:')), voltageConfigured: parseFloat(util.getValue(lines, ' Configured Voltage:')),
voltageMin: parseFloat(getValue(lines, ' Minimum Voltage:')), voltageMin: parseFloat(util.getValue(lines, ' Minimum Voltage:')),
voltageMax: parseFloat(getValue(lines, ' Maximum Voltage:')), voltageMax: parseFloat(util.getValue(lines, ' Maximum Voltage:')),
}) })
}); });
} }
@ -238,16 +218,16 @@ function memLayout(callback) {
devices.shift(); devices.shift();
devices.forEach(function (device) { devices.forEach(function (device) {
let lines = device.split('\n'); let lines = device.split('\n');
const size = parseInt(getValue(lines, ' Size')); const size = parseInt(util.getValue(lines, ' Size'));
if (size) { if (size) {
result.push({ result.push({
size: size * 1024 * 1024 * 1024, size: size * 1024 * 1024 * 1024,
bank: '', bank: '',
type: getValue(lines, ' Type:'), type: util.getValue(lines, ' Type:'),
clockSpeed: parseInt(getValue(lines, ' Speed:')), clockSpeed: parseInt(util.getValue(lines, ' Speed:')),
formFactor: '', formFactor: '',
partNum: getValue(lines, ' Part Number:'), partNum: util.getValue(lines, ' Part Number:'),
serialNum: getValue(lines, ' Serial Number:'), serialNum: util.getValue(lines, ' Serial Number:'),
voltageConfigured: -1, voltageConfigured: -1,
voltageMin: -1, voltageMin: -1,
voltageMax: -1, voltageMax: -1,
@ -270,16 +250,16 @@ function memLayout(callback) {
devices.forEach(function (device) { devices.forEach(function (device) {
let lines = device.split('\r\n'); let lines = device.split('\r\n');
result.push({ result.push({
size: parseInt(getValue(lines, 'Capacity', '=')), size: parseInt(util.getValue(lines, 'Capacity', '=')),
bank: getValue(lines, 'abel', '='), // BankLabel bank: util.getValue(lines, 'abel', '='), // BankLabel
type: memoryTypes[parseInt(getValue(lines, 'MemoryType', '='))], type: memoryTypes[parseInt(util.getValue(lines, 'MemoryType', '='))],
clockSpeed: parseInt(getValue(lines, 'ConfiguredClockSpeed', '=')), clockSpeed: parseInt(util.getValue(lines, 'ConfiguredClockSpeed', '=')),
formFactor: FormFactors[parseInt(getValue(lines, 'FormFactor', '='))], formFactor: FormFactors[parseInt(util.getValue(lines, 'FormFactor', '='))],
partNum: getValue(lines, 'PartNumber', '='), partNum: util.getValue(lines, 'PartNumber', '='),
serialNum: getValue(lines, 'SerialNumber', '='), serialNum: util.getValue(lines, 'SerialNumber', '='),
voltageConfigured: parseInt(getValue(lines, 'ConfiguredVoltage', '=')) / 1000.0, voltageConfigured: parseInt(util.getValue(lines, 'ConfiguredVoltage', '=')) / 1000.0,
voltageMin: parseInt(getValue(lines, 'MinVoltage', '=')) / 1000.0, voltageMin: parseInt(util.getValue(lines, 'MinVoltage', '=')) / 1000.0,
voltageMax: parseInt(getValue(lines, 'MaxVoltage', '=')) / 1000.0, voltageMax: parseInt(util.getValue(lines, 'MaxVoltage', '=')) / 1000.0,
}) })
}); });
} }

View File

@ -29,20 +29,6 @@ let _network = {};
let _default_iface; let _default_iface;
let _mac = {}; let _mac = {};
function getValue(lines, property, separator) {
separator = separator || ':';
property = property.toLowerCase();
for (let i = 0; i < lines.length; i++) {
if (lines[i].toLowerCase().startsWith(property)) {
const parts = lines[i].split(separator);
if (parts.length > 1) {
return parts[1].trim();
}
}
}
return '';
}
function getDefaultNetworkInterface() { function getDefaultNetworkInterface() {
if (!_default_iface) { if (!_default_iface) {
@ -225,11 +211,11 @@ function networkStats(iface, callback) {
if (sections[i].trim() !== "") { if (sections[i].trim() !== "") {
let lines = sections[i].trim().split('\r\n'); let lines = sections[i].trim().split('\r\n');
let netEnabled = getValue(lines, 'NetEnabled', '='); let netEnabled = util.getValue(lines, 'NetEnabled', '=');
if (netEnabled) { if (netEnabled) {
nics.push({ nics.push({
mac: getValue(lines, 'MACAddress', '=').toLowerCase(), mac: util.getValue(lines, 'MACAddress', '=').toLowerCase(),
name: getValue(lines, 'Name', '=').replace(/[()\[\] ]+/g, "").toLowerCase(), name: util.getValue(lines, 'Name', '=').replace(/[()\[\] ]+/g, "").toLowerCase(),
netEnabled: netEnabled === 'TRUE' netEnabled: netEnabled === 'TRUE'
}); });
} }
@ -247,9 +233,9 @@ function networkStats(iface, callback) {
let lines = sections[i].trim().split('\r\n'); let lines = sections[i].trim().split('\r\n');
perfData.push({ perfData.push({
name: getValue(lines, 'Name', '=').replace(/[()\[\] ]+/g, "").toLowerCase(), name: util.getValue(lines, 'Name', '=').replace(/[()\[\] ]+/g, "").toLowerCase(),
rx: parseInt(getValue(lines, 'BytesReceivedPersec', '='),10), rx: parseInt(util.getValue(lines, 'BytesReceivedPersec', '='),10),
tx: parseInt(getValue(lines, 'BytesSentPersec', '='),10) tx: parseInt(util.getValue(lines, 'BytesSentPersec', '='),10)
}); });
} }
} }

View File

@ -31,6 +31,30 @@ let _process_cpu = {
result: {} result: {}
}; };
let _winStatusValues = {
'0': 'unknown',
'1': 'other',
'2': 'ready',
'3': 'running',
'4': 'blocked',
'5': 'suspended blocked',
'6': 'suspended ready',
'7': 'terminated',
'8': 'stopped',
'9': 'growing',
}
function parseTimeWin(time) {
time = time || '';
if (time) {
return (time.substr(0,4) + '-' + time.substr(4,2) + '-' + time.substr(6,2) + ' ' + time.substr(8,2) + ':' + time.substr(10,2) + ':' + time.substr(12,2))
} else {
return '';
}
}
// -------------------------- // --------------------------
// PS - services // PS - services
// pass a comma separated string with services to check (mysql, apache, postgresql, ...) // pass a comma separated string with services to check (mysql, apache, postgresql, ...)
@ -152,6 +176,19 @@ function processes(callback) {
} }
function getName(command) {
command = command || '';
let result = command.split(' ');
if (result.substr(-1) === ':') {
result = result.substr(0, result.length - 1);
}
if (result.substr(0,1) !== '[') {
let parts = part.split('/');
result = parts[parts.length];
}
return result
}
function parseLine(line) { function parseLine(line) {
let offset = 0; let offset = 0;
let offset2 = 0; let offset2 = 0;
@ -193,6 +230,7 @@ function processes(callback) {
return ({ return ({
pid: pid, pid: pid,
name: _linux ? getName(command) : command,
pcpu: pcpu, pcpu: pcpu,
pcpuu: 0, pcpuu: 0,
pcpus: 0, pcpus: 0,
@ -293,24 +331,41 @@ function processes(callback) {
} }
} }
function calcProcPidStat(procStat, all) {
// calc
let pcpuu = 0;
let pcpus = 0;
if (_process_cpu.all > 0 && _process_cpu.list[procStat.pid]) {
pcpuu = (procStat.utime - _process_cpu.list[procStat.pid].utime) / (all - _process_cpu.all) * 100; // user
pcpus = (procStat.stime - _process_cpu.list[procStat.pid].stime) / (all - _process_cpu.all) * 100; // system
} else {
pcpuu = (procStat.utime) / (all) * 100; // user
pcpus = (procStat.stime) / (all) * 100; // system
}
return {
pid: procStat.pid,
utime: procStat.utime,
stime: procStat.stime,
pcpuu: pcpuu,
pcpus: pcpus
}
}
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
process.nextTick(() => { process.nextTick(() => {
if (_windows) {
let error = new Error(NOT_SUPPORTED);
if (callback) { callback(NOT_SUPPORTED) }
reject(error);
}
let result = { let result = {
all: 0, all: 0,
running: 0, running: 0,
blocked: 0, blocked: 0,
sleeping: 0, sleeping: 0,
unknown: 0,
list: [] list: []
}; };
let cmd = ""; let cmd = "";
if ((_process_cpu.ms && Date.now() - _process_cpu.ms >= 500) || _process_cpu.ms === 0) { if ((_process_cpu.ms && Date.now() - _process_cpu.ms >= 500) || _process_cpu.ms === 0) {
if (_linux || _darwin) {
if (_linux) cmd = "ps axo pid:10,pcpu:6,pmem:6,pri:5,vsz:10,rss:10,ni:5,start:20,state:20,tty:20,user:20,command"; if (_linux) cmd = "ps axo pid:10,pcpu:6,pmem:6,pri:5,vsz:10,rss:10,ni:5,start:20,state:20,tty:20,user:20,command";
if (_darwin) cmd = "ps acxo pid,pcpu,pmem,pri,vsz,rss,nice,start,state,tty,user,command -r"; if (_darwin) cmd = "ps acxo pid,pcpu,pmem,pri,vsz,rss,nice,start,state,tty,user,command -r";
exec(cmd, function (error, stdout) { exec(cmd, function (error, stdout) {
@ -381,6 +436,93 @@ function processes(callback) {
} }
} }
}); });
}
if (_windows) {
exec("wmic process get /value", function (error, stdout) {
if (!error) {
let psections = stdout.split(/\n\s*\n/);
let procs = [];
let procStats = [];
let list_new = {};
let allcpuu = 0;
let allcpus = 0;
for (let i = 0; i < psections.length; i++) {
if (psections[i].trim() !== "") {
let lines = psections[i].trim().split('\r\n');
let pid = parseInt(util.getValue(lines, 'ProcessId', '=', true), 10);
let statusValue = util.getValue(lines, 'ExecutionState', '=')
let name = util.getValue(lines, 'Caption', '=', true);
let commandLine = util.getValue(lines, 'CommandLine', '=', 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;
result.all++;
if (!statusValue) { result.unknown++}
if (statusValue === '3') { result.running++}
if (statusValue === '4' || statusValue === '5') { result.blocked++}
procStats.push({
pid: pid,
utime: utime,
stime: stime,
pcpu: 0,
pcpuu: 0,
pcpus: 0,
});
procs.push({
pid: pid,
name: name,
pcpu: 0,
pcpuu: 0,
pcpus: 0,
pmem: mem / os.totalmem() * 100,
priority: parseInt(util.getValue(lines, 'Priority', '=', true), 10),
mem_vsz: parseInt(util.getValue(lines, 'PageFileUsage', '=', true), 10),
mem_rss: Math.floor(parseInt(util.getValue(lines, 'WorkingSetSize', '=', true), 10) / 1024),
nice: 0,
started: parseTimeWin(util.getValue(lines, 'CreationDate', '=', true)),
state: (!statusValue ? _winStatusValues[0] : _winStatusValues[statusValue]),
tty: '',
user: '',
command: commandLine || name
});
}
}
result.sleeping = result.all - result.running - result.blocked - result.unknown;
result.list = procs;
for (let i = 0; i < procStats.length; i++) {
let resultProcess = calcProcPidStat(procStats[i], allcpuu + allcpus);
// 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;
result.list[listPos].pcpuu = resultProcess.pcpuu;
result.list[listPos].pcpus = resultProcess.pcpus;
}
// save new values
list_new[resultProcess.pid] = {
pcpuu: resultProcess.pcpuu,
pcpus: resultProcess.pcpus,
utime: resultProcess.utime,
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);
})
}
} else { } else {
if (callback) { callback(_process_cpu.result) } if (callback) { callback(_process_cpu.result) }
resolve(_process_cpu.result); resolve(_process_cpu.result);

View File

@ -57,7 +57,30 @@ function cores() {
return _cores; return _cores;
} }
function getValue(lines, property, separator, trimmed) {
separator = separator || ':';
property = property.toLowerCase();
trimmed = trimmed || false;
for (let i = 0; i < lines.length; i++) {
let line = lines[i].toLowerCase();
if (trimmed) {
line = line.trim();
}
if (line.toLowerCase().startsWith(property)) {
const parts = lines[i].split(separator);
if (parts.length >= 2) {
parts.shift();
return parts.join(':').trim();
} else {
return ''
}
}
}
return '';
}
exports.isFunction = isFunction; exports.isFunction = isFunction;
exports.unique = unique; exports.unique = unique;
exports.sortByKey= sortByKey; exports.sortByKey= sortByKey;
exports.cores = cores; exports.cores = cores;
exports.getValue = getValue;