extended windows support services(), optimized diskLayout() (OSX), bugfixes

This commit is contained in:
Sebastian Hildebrandt 2017-09-15 15:04:20 +02:00
parent 219736d6b6
commit 9b644bbe2a
4 changed files with 125 additions and 40 deletions

View File

@ -98,6 +98,7 @@ Other changes
| Version | Date | Comment | | Version | Date | Comment |
| -------------- | -------------- | -------- | | -------------- | -------------- | -------- |
| 3.29.0 | 2017-09-15 | extended windows support `services()`, optimized `diskLayout()` (OSX), bugfixes |
| 3.28.0 | 2017-09-14 | extended windows support `processes()` | | 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 |

View File

@ -50,6 +50,7 @@ async function cpu() {
## News and Changes ## News and Changes
### Latest Activity ### Latest Activity
- Version 3.29.0: extended windows support `services()`
- Version 3.28.0: extended windows support `processes()` - 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
@ -357,9 +358,9 @@ I also created a nice little command line tool called [mmon][mmon-github-url] (
| | pid | X | X | | PID | | | pid | X | X | | PID |
| | cpu | X | X | | process % CPU | | | cpu | X | X | | process % CPU |
| | mem | X | X | | process % MEM | | | mem | X | X | | process % MEM |
| si.services('mysql, apache2', cb) | [{...}] | X | X | | pass comma separated string of services | | si.services('mysql, apache2', cb) | [{...}] | X | X | X | pass comma separated string of services |
| | [0].name | X | X | | name of service | | | [0].name | X | X | X | name of service |
| | [0].running | X | X | | true / false | | | [0].running | X | X | X | true / false |
| | [0].pcpu | X | X | | process % CPU | | | [0].pcpu | X | X | | process % CPU |
| | [0].pmem | X | X | | process % MEM | | | [0].pmem | X | X | | process % MEM |

View File

@ -612,11 +612,14 @@ function diskLayout(callback) {
} }
if (_darwin) { if (_darwin) {
exec("system_profiler SPSerialATADataType", function (error, stdout) { exec("system_profiler SPSerialATADataType SPNVMeDataType", function (error, stdout) {
if (!error) { if (!error) {
let devices = stdout.toString().split(' Physical Interconnect: SATA'); let parts = stdout.toString().split('NVMExpress:');
let devices = parts[0].split(' Physical Interconnect: ');
devices.shift(); devices.shift();
devices.forEach(function (device) { devices.forEach(function (device) {
device = 'InterfaceType: ' + device;
let lines = device.split('\n'); let lines = device.split('\n');
const mediumType = util.getValue(lines, 'Medium Type', ':', true).trim(); const mediumType = util.getValue(lines, 'Medium Type', ':', true).trim();
const sizeStr = util.getValue(lines, 'capacity', ':', true).trim(); const sizeStr = util.getValue(lines, 'capacity', ':', true).trim();
@ -645,6 +648,40 @@ function diskLayout(callback) {
} }
} }
}); });
if (parts.length > 1) {
let devices = parts[1].split('\n\n Capacity:');
devices.shift();
devices.forEach(function (device) {
device = '!Capacity: ' + device;
let lines = device.split('\n');
const linkWidth = util.getValue(lines, 'link width', ':', true).trim();
const sizeStr = util.getValue(lines, '!capacity', ':', true).trim();
if (sizeStr) {
let size = parseInt(sizeStr.match(/\(([^)]+)\)/)[1].replace(/\./g, ""));
if (!size) {
size = parseInt(sizeStr);
}
if (size) {
result.push({
type: 'NVMe',
name: util.getValue(lines, 'Model', ':', true).trim(),
vendor: '',
size: size,
bytesPerSector: -1,
totalCylinders: -1,
totalHeads: -1,
totalSectors: -1,
totalTracks: -1,
tracksPerCylinder: -1,
sectorsPerTrack: -1,
firmwareRevision: util.getValue(lines, 'Revision', ':', true).trim(),
serialNum: util.getValue(lines, 'Serial Number', ':', true).trim(),
interfaceType: ('PCIe ' + linkWidth).trim(),
})
}
}
});
}
} }
if (callback) { if (callback) {
callback(result) callback(result)

View File

@ -70,35 +70,84 @@ function services(srv, callback) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
process.nextTick(() => { process.nextTick(() => {
if (_windows) { srv = srv.trim().toLowerCase().replace(/,+/g, " ").replace(/ +/g, " ").replace(/ +/g, "|");
let error = new Error(NOT_SUPPORTED);
if (callback) { callback(NOT_SUPPORTED) }
reject(error);
}
srv = srv.trim().replace(/,+/g, " ").replace(/ +/g, " ").replace(/ +/g, "|");
let srvs = srv.split('|'); let srvs = srv.split('|');
let comm = (_darwin) ? "ps -caxm -o pcpu,pmem,comm" : "ps axo pcpu,pmem,comm";
let data = []; let data = [];
if (srv !== '' && srvs.length > 0) { let dataSrv = [];
exec(comm + " | grep -v grep | egrep '" + srv + "'", function (error, stdout) {
if (!error) { if (_linux || _darwin) {
let lines = stdout.toString().replace(/ +/g, " ").replace(/,+/g, ".").split('\n'); let comm = (_darwin) ? "ps -caxm -o pcpu,pmem,comm" : "ps axo pcpu,pmem,comm";
srvs.forEach(function (srv) { if (srv !== '' && srvs.length > 0) {
let ps = lines.filter(function (e) { exec(comm + " | grep -v grep | egrep '" + srv + "'", function (error, stdout) {
return e.indexOf(srv) !== -1 if (!error) {
let lines = stdout.toString().replace(/ +/g, " ").replace(/,+/g, ".").split('\n');
srvs.forEach(function (srv) {
let ps = lines.filter(function (e) {
return e.indexOf(srv) !== -1
});
data.push({
'name': srv,
'running': ps.length > 0,
'pcpu': parseFloat((ps.reduce(function (pv, cv) {
return pv + parseFloat(cv.trim().split(' ')[0]);
}, 0)).toFixed(2)),
'pmem': parseFloat((ps.reduce(function (pv, cv) {
return pv + parseFloat(cv.trim().split(' ')[1]);
}, 0)).toFixed(2))
})
}); });
if (callback) { callback(data) }
resolve(data);
} else {
srvs.forEach(function (srv) {
data.push({
'name': srv,
'running': false,
'pcpu': 0,
'pmem': 0
})
});
if (callback) { callback(data) }
resolve(data);
}
});
} else {
if (callback) { callback(data) }
resolve(data);
}
}
if (_windows) {
exec("wmic service get /value", {maxBuffer: 1024 * 1000}, function (error, stdout) {
if (!error) {
let serviceSections = stdout.split(/\n\s*\n/);
for (let i = 0; i < serviceSections.length; i++) {
if (serviceSections[i].trim() !== "") {
let lines = serviceSections[i].trim().split('\r\n');
let srv = util.getValue(lines, 'Name', '=', true).toLowerCase();
let started = util.getValue(lines, 'Started', '=', true);
if (srvs.indexOf(srv) >= 0) {
data.push({
'name': srv,
'running': (started === 'TRUE'),
'pcpu': 0,
'pmem': 0
})
dataSrv.push(srv);
}
}
}
let srvsMissing = srvs.filter(function (e) {
return dataSrv.indexOf(e) === -1
});
srvsMissing.forEach(function (srv) {
data.push({ data.push({
'name': srv, 'name': srv,
'running': ps.length > 0, 'running': false,
'pcpu': parseFloat((ps.reduce(function (pv, cv) { 'pcpu': 0,
return pv + parseFloat(cv.trim().split(' ')[0]); 'pmem': 0
}, 0)).toFixed(2)),
'pmem': parseFloat((ps.reduce(function (pv, cv) {
return pv + parseFloat(cv.trim().split(' ')[1]);
}, 0)).toFixed(2))
}) })
}); });
if (callback) { callback(data) } if (callback) { callback(data) }
resolve(data); resolve(data);
} else { } else {
@ -113,10 +162,7 @@ function services(srv, callback) {
if (callback) { callback(data) } if (callback) { callback(data) }
resolve(data); resolve(data);
} }
}); })
} else {
if (callback) { callback(data) }
resolve(data);
} }
}); });
}); });
@ -178,15 +224,15 @@ function processes(callback) {
function getName(command) { function getName(command) {
command = command || ''; command = command || '';
let result = command.split(' '); let result = command.split(' ')[0];
if (result.substr(-1) === ':') { if (result.substr(-1) === ':') {
result = result.substr(0, result.length - 1); result = result.substr(0, result.length - 1);
} }
if (result.substr(0,1) !== '[') { if (result.substr(0,1) !== '[') {
let parts = part.split('/'); let parts = result.split('/');
result = parts[parts.length]; result = parts[parts.length - 1];
} }
return result return result;
} }
function parseLine(line) { function parseLine(line) {
@ -438,17 +484,17 @@ function processes(callback) {
}); });
} }
if (_windows) { if (_windows) {
exec("wmic process get /value", function (error, stdout) { exec("wmic process get /value", {maxBuffer: 1024 * 1000}, function (error, stdout) {
if (!error) { if (!error) {
let psections = stdout.split(/\n\s*\n/); let processSections = stdout.split(/\n\s*\n/);
let procs = []; let procs = [];
let procStats = []; let procStats = [];
let list_new = {}; let list_new = {};
let allcpuu = 0; let allcpuu = 0;
let allcpus = 0; let allcpus = 0;
for (let i = 0; i < psections.length; i++) { for (let i = 0; i < processSections.length; i++) {
if (psections[i].trim() !== "") { if (processSections[i].trim() !== "") {
let lines = psections[i].trim().split('\r\n'); let lines = processSections[i].trim().split('\r\n');
let pid = parseInt(util.getValue(lines, 'ProcessId', '=', true), 10); let pid = parseInt(util.getValue(lines, 'ProcessId', '=', true), 10);
let statusValue = util.getValue(lines, 'ExecutionState', '=') let statusValue = util.getValue(lines, 'ExecutionState', '=')
let name = util.getValue(lines, 'Caption', '=', true); let name = util.getValue(lines, 'Caption', '=', true);