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 |
| -------------- | -------------- | -------- |
| 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.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 |

View File

@ -50,6 +50,7 @@ async function cpu() {
## News and Changes
### 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.26.0: improved windows support `getDynamicData()`, updated docs
- 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) |
| | 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.processes(cb) | {...} | X | X | | # running processes |
| | 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 |
| | ...[0].pid | X | X | | process PID |
| | ...[0].pcpu | X | X | | process % CPU usage |
| | ...[0].pcpuu | X | | | process % CPU usage (user) |
| | ...[0].pcpus | X | | | process % CPU usage (system) |
| | ...[0].pmem | X | X | | process memory % |
| | ...[0].priority | X | X | | process priotity |
| | ...[0].mem_vsz | X | X | | process virtual memory size |
| | ...[0].mem_rss | X | X | | process mem resident set size |
| si.processes(cb) | {...} | X | X | X | # running processes |
| | all | X | X | X | # of all processes |
| | running | X | X | X | # of all processes running |
| | blocked | X | X | X | # of all processes blocked |
| | sleeping | X | X | X | # of all processes sleeping |
| | unknown | | | X | # of all processes unknown status |
| | list[] | X | X | X | list of all processes incl. details |
| | ...[0].pid | X | X | X | process PID |
| | ...[0].name | X | X | X | process name |
| | ...[0].pcpu | X | X | X | process % CPU usage |
| | ...[0].pcpuu | X | | X | process % CPU usage (user) |
| | ...[0].pcpus | X | | X | process % CPU usage (system) |
| | ...[0].pmem | X | X | X | process memory % |
| | ...[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].started | X | X | | process start time |
| | ...[0].state | X | X | | process state (e.g. sleeping) |
| | ...[0].started | X | X | X | process start time |
| | ...[0].state | X | X | X | process state (e.g. sleeping) |
| | ...[0].tty | X | X | | tty from which process was started |
| | ...[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 |
| | proc | X | X | | process name |
| | pid | X | X | | PID |

View File

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

View File

@ -14,7 +14,7 @@
const os = require('os');
const util = require('./util');
const DockerSocket = require('./dockerSocket');
const DockerSocket = require('./dockerSocket');
let _platform = os.type();

View File

@ -28,27 +28,6 @@ const NOT_SUPPORTED = 'not supported';
let _fs_speed = {};
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
@ -598,18 +577,18 @@ function diskLayout(callback) {
devices.forEach(function (device) {
let lines = device.split('\n');
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 {
mediumType = execSync('cat /sys/block/' + logical + '/queue/rotational').toString().split('\n')[0];
} 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') {
result.push({
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),
vendor: getValue(lines, 'vendor:', ':', true),
name: util.getValue(lines, 'product:', ':', true),
vendor: util.getValue(lines, 'vendor:', ':', true),
size: parseInt(size.match(/\(([^)]+)\)/)[1]) * 1000 * 1000 * 1000 * 1000,
bytesPerSector: -1,
totalCylinders: -1,
@ -618,8 +597,8 @@ function diskLayout(callback) {
totalTracks: -1,
tracksPerCylinder: -1,
sectorsPerTrack: -1,
firmwareRevision: getValue(lines, 'version:', ':', true).trim(),
serialNum: getValue(lines, 'serial:', ':', true).trim(),
firmwareRevision: util.getValue(lines, 'version:', ':', true).trim(),
serialNum: util.getValue(lines, 'serial:', ':', true).trim(),
interfaceType: '',
})
}
@ -639,8 +618,8 @@ function diskLayout(callback) {
devices.shift();
devices.forEach(function (device) {
let lines = device.split('\n');
const mediumType = getValue(lines, 'Medium Type', ':', true).trim();
const sizeStr = getValue(lines, 'capacity', ':', true).trim();
const mediumType = util.getValue(lines, 'Medium Type', ':', true).trim();
const sizeStr = util.getValue(lines, 'capacity', ':', true).trim();
if (sizeStr) {
let size = parseInt(sizeStr.match(/\(([^)]+)\)/)[1].replace(/\./g, ""));
if (!size) {
@ -649,7 +628,7 @@ function diskLayout(callback) {
if (size) {
result.push({
type: mediumType.startsWith('Solid') ? 'SSD' : 'HD',
name: getValue(lines, 'Model', ':', true).trim(),
name: util.getValue(lines, 'Model', ':', true).trim(),
vendor: '',
size: size,
bytesPerSector: -1,
@ -659,9 +638,9 @@ function diskLayout(callback) {
totalTracks: -1,
tracksPerCylinder: -1,
sectorsPerTrack: -1,
firmwareRevision: getValue(lines, 'Revision', ':', true).trim(),
serialNum: getValue(lines, 'Serial Number', ':', true).trim(),
interfaceType: getValue(lines, 'InterfaceType', ':', true).trim()
firmwareRevision: util.getValue(lines, 'Revision', ':', true).trim(),
serialNum: util.getValue(lines, 'Serial Number', ':', 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');
devices.forEach(function (device) {
let lines = device.split('\r\n');
const size = getValue(lines, 'Size', '=').trim();
const size = util.getValue(lines, 'Size', '=').trim();
if (size) {
result.push({
type: device.indexOf('SSD') > -1 ? 'SSD' : 'HD', // not really correct(!) ... maybe this obe is better: MSFT_PhysicalDisk - Media Type??
name: getValue(lines, 'Caption', '='),
vendor: getValue(lines, 'Manufacturer', '='),
name: util.getValue(lines, 'Caption', '='),
vendor: util.getValue(lines, 'Manufacturer', '='),
size: parseInt(size),
bytesPerSector: parseInt(getValue(lines, 'BytesPerSector', '=')),
totalCylinders: parseInt(getValue(lines, 'TotalCylinders', '=')),
totalHeads: parseInt(getValue(lines, 'TotalHeads', '=')),
totalSectors: parseInt(getValue(lines, 'TotalSectors', '=')),
totalTracks: parseInt(getValue(lines, 'TotalTracks', '=')),
tracksPerCylinder: parseInt(getValue(lines, 'TracksPerCylinder', '=')),
sectorsPerTrack: parseInt(getValue(lines, 'SectorsPerTrack', '=')),
firmwareRevision: getValue(lines, 'FirmwareRevision', '=').trim(),
serialNum: getValue(lines, 'SerialNumber', '=').trim(),
interfaceType: getValue(lines, 'InterfaceType', '=').trim()
bytesPerSector: parseInt(util.getValue(lines, 'BytesPerSector', '=')),
totalCylinders: parseInt(util.getValue(lines, 'TotalCylinders', '=')),
totalHeads: parseInt(util.getValue(lines, 'TotalHeads', '=')),
totalSectors: parseInt(util.getValue(lines, 'TotalSectors', '=')),
totalTracks: parseInt(util.getValue(lines, 'TotalTracks', '=')),
tracksPerCylinder: parseInt(util.getValue(lines, 'TracksPerCylinder', '=')),
sectorsPerTrack: parseInt(util.getValue(lines, 'SectorsPerTrack', '=')),
firmwareRevision: util.getValue(lines, 'FirmwareRevision', '=').trim(),
serialNum: util.getValue(lines, 'SerialNumber', '=').trim(),
interfaceType: util.getValue(lines, 'InterfaceType', '=').trim()
})
}
});

View File

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

View File

@ -24,26 +24,6 @@ const _darwin = (_platform === 'Darwin');
const _windows = (_platform === 'Windows_NT');
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 |
// |______________________|_________________________| | |
@ -213,16 +193,16 @@ function memLayout(callback) {
devices.forEach(function (device) {
let lines = device.split('\n');
result.push({
size: parseInt(getValue(lines, ' Size'))*1024*1024,
bank: getValue(lines, ' Bank Locator'),
type: getValue(lines, ' Type:'),
clockSpeed: (getValue(lines, ' Configured Clock Speed:') ? parseInt(getValue(lines, ' Configured Clock Speed:')) : parseInt(getValue(lines, ' Speed:'))),
formFactor: getValue(lines, ' Form Factor:'),
size: parseInt(util.getValue(lines, ' Size'))*1024*1024,
bank: util.getValue(lines, ' Bank Locator'),
type: util.getValue(lines, ' Type:'),
clockSpeed: (util.getValue(lines, ' Configured Clock Speed:') ? parseInt(util.getValue(lines, ' Configured Clock Speed:')) : parseInt(util.getValue(lines, ' Speed:'))),
formFactor: util.getValue(lines, ' Form Factor:'),
partNum: '',
serialNum: getValue(lines, ' Serial Number:'),
voltageConfigured: parseFloat(getValue(lines, ' Configured Voltage:')),
voltageMin: parseFloat(getValue(lines, ' Minimum Voltage:')),
voltageMax: parseFloat(getValue(lines, ' Maximum Voltage:')),
serialNum: util.getValue(lines, ' Serial Number:'),
voltageConfigured: parseFloat(util.getValue(lines, ' Configured Voltage:')),
voltageMin: parseFloat(util.getValue(lines, ' Minimum Voltage:')),
voltageMax: parseFloat(util.getValue(lines, ' Maximum Voltage:')),
})
});
}
@ -238,16 +218,16 @@ function memLayout(callback) {
devices.shift();
devices.forEach(function (device) {
let lines = device.split('\n');
const size = parseInt(getValue(lines, ' Size'));
const size = parseInt(util.getValue(lines, ' Size'));
if (size) {
result.push({
size: size * 1024 * 1024 * 1024,
bank: '',
type: getValue(lines, ' Type:'),
clockSpeed: parseInt(getValue(lines, ' Speed:')),
type: util.getValue(lines, ' Type:'),
clockSpeed: parseInt(util.getValue(lines, ' Speed:')),
formFactor: '',
partNum: getValue(lines, ' Part Number:'),
serialNum: getValue(lines, ' Serial Number:'),
partNum: util.getValue(lines, ' Part Number:'),
serialNum: util.getValue(lines, ' Serial Number:'),
voltageConfigured: -1,
voltageMin: -1,
voltageMax: -1,
@ -270,16 +250,16 @@ function memLayout(callback) {
devices.forEach(function (device) {
let lines = device.split('\r\n');
result.push({
size: parseInt(getValue(lines, 'Capacity', '=')),
bank: getValue(lines, 'abel', '='), // BankLabel
type: memoryTypes[parseInt(getValue(lines, 'MemoryType', '='))],
clockSpeed: parseInt(getValue(lines, 'ConfiguredClockSpeed', '=')),
formFactor: FormFactors[parseInt(getValue(lines, 'FormFactor', '='))],
partNum: getValue(lines, 'PartNumber', '='),
serialNum: getValue(lines, 'SerialNumber', '='),
voltageConfigured: parseInt(getValue(lines, 'ConfiguredVoltage', '=')) / 1000.0,
voltageMin: parseInt(getValue(lines, 'MinVoltage', '=')) / 1000.0,
voltageMax: parseInt(getValue(lines, 'MaxVoltage', '=')) / 1000.0,
size: parseInt(util.getValue(lines, 'Capacity', '=')),
bank: util.getValue(lines, 'abel', '='), // BankLabel
type: memoryTypes[parseInt(util.getValue(lines, 'MemoryType', '='))],
clockSpeed: parseInt(util.getValue(lines, 'ConfiguredClockSpeed', '=')),
formFactor: FormFactors[parseInt(util.getValue(lines, 'FormFactor', '='))],
partNum: util.getValue(lines, 'PartNumber', '='),
serialNum: util.getValue(lines, 'SerialNumber', '='),
voltageConfigured: parseInt(util.getValue(lines, 'ConfiguredVoltage', '=')) / 1000.0,
voltageMin: parseInt(util.getValue(lines, 'MinVoltage', '=')) / 1000.0,
voltageMax: parseInt(util.getValue(lines, 'MaxVoltage', '=')) / 1000.0,
})
});
}

View File

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

View File

@ -31,6 +31,30 @@ let _process_cpu = {
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
// 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) {
let offset = 0;
let offset2 = 0;
@ -193,6 +230,7 @@ function processes(callback) {
return ({
pid: pid,
name: _linux ? getName(command) : command,
pcpu: pcpu,
pcpuu: 0,
pcpus: 0,
@ -293,94 +331,198 @@ 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) => {
process.nextTick(() => {
if (_windows) {
let error = new Error(NOT_SUPPORTED);
if (callback) { callback(NOT_SUPPORTED) }
reject(error);
}
let result = {
all: 0,
running: 0,
blocked: 0,
sleeping: 0,
unknown: 0,
list: []
};
let cmd = "";
if ((_process_cpu.ms && Date.now() - _process_cpu.ms >= 500) || _process_cpu.ms === 0) {
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";
exec(cmd, function (error, stdout) {
if (!error) {
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 (_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 (_darwin) cmd = "ps acxo pid,pcpu,pmem,pri,vsz,rss,nice,start,state,tty,user,command -r";
exec(cmd, function (error, stdout) {
if (!error) {
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 (_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');
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());
// 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);
// process
let list_new = {};
let resultProcess = {};
for (let i = 0; i < curr_processes.length; i++) {
resultProcess = parseProcPidStat(curr_processes[i], all);
if (resultProcess.pid) {
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;
result.list[listPos].pcpuu = resultProcess.pcpuu;
result.list[listPos].pcpus = resultProcess.pcpus;
}
// 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,
cutime: resultProcess.cutime,
cstime: resultProcess.cstime
// 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;
_process_cpu.result = result;
// store old values
_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);
}
}
}
});
});
}
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 {
if (callback) { callback(_process_cpu.result) }
resolve(_process_cpu.result);

View File

@ -57,7 +57,30 @@ function 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.unique = unique;
exports.sortByKey= sortByKey;
exports.cores = cores;
exports.getValue = getValue;