added versions (kernel, ssl, node, npm, pm2, ...)
This commit is contained in:
parent
e1827fd78b
commit
d338e90e83
@ -42,6 +42,7 @@ si.cpu()
|
||||
|
||||
### Latest Activity
|
||||
|
||||
- Version 3.6.0: added versions (kernel, ssl, node, npm, pm2, ...).
|
||||
- Version 3.5.0: added graphics info (controller and display).
|
||||
- Version 3.4.0: rewritten currentLoad and CPU load for processes (linux). This is now much more accurate.
|
||||
- Version 3.3.0: added process list. Get full process list including details like cpu and mem usage, status, command, ...
|
||||
@ -69,6 +70,7 @@ Here all changes more detailed:
|
||||
|
||||
New Functions
|
||||
|
||||
- `versions`: returns object of versions - kernel, ssl, node, npm, ...(new in version 3.6)
|
||||
- `graphics`: returns arrays of graphics controllers and displays (new in version 3.5)
|
||||
- `networkInterfaceDefault`: returns default network interface (new in version 3.4)
|
||||
- `processes`: now returns also a process list with all process details (new in version 3.3)
|
||||
@ -188,6 +190,7 @@ This library is splitted in several sections:
|
||||
| - arch | X | X | same as os.arch() |
|
||||
| - hostname | X | X | same as os.hostname() |
|
||||
| - logofile | X | X | e.g. 'apple', 'debian', 'fedora', ... |
|
||||
| si.versions(cb) | X | X | Version information (kernel, ssl, node, ...) |
|
||||
| si.cpu(cb) | X | X | CPU information|
|
||||
| - manufacturer | X | X | e.g. 'Intel(R)' |
|
||||
| - brand | X | X | e.g. 'Core(TM)2 Duo' |
|
||||
@ -394,6 +397,7 @@ I am happy to discuss any comments and suggestions. Please feel free to contact
|
||||
|
||||
| Version | Date | Comment |
|
||||
| -------------- | -------------- | -------- |
|
||||
| 3.6.0 | 2016-09-14 | added versions (kernel, ssl, node, npm, pm2, ...) |
|
||||
| 3.5.1 | 2016-09-14 | bugfix graphics info |
|
||||
| 3.5.0 | 2016-09-14 | added graphics info (controller, display) |
|
||||
| 3.4.4 | 2016-09-02 | tiny fixes system.model, getDefaultNetworkInterface |
|
||||
|
||||
194
lib/index.js
194
lib/index.js
@ -81,6 +81,7 @@
|
||||
// --------------------------------
|
||||
//
|
||||
// version date comment
|
||||
// 3.6.0 2016-09-16 added versions (kernel, ssl, node, npm, pm2, ...)
|
||||
// 3.5.1 2016-09-14 bugfix graphics info
|
||||
// 3.5.0 2016-09-14 added graphics info (controller, display)
|
||||
// 3.4.4 2016-09-02 tiny fixes system.model, getDefaultNetworkInterface
|
||||
@ -391,25 +392,25 @@ function osInfo(callback) {
|
||||
|
||||
exec("cat /etc/*-release", function (error, stdout) {
|
||||
//if (!error) {
|
||||
/**
|
||||
* @namespace
|
||||
* @property {string} DISTRIB_ID
|
||||
* @property {string} NAME
|
||||
* @property {string} DISTRIB_RELEASE
|
||||
* @property {string} VERSION_ID
|
||||
* @property {string} DISTRIB_CODENAME
|
||||
*/
|
||||
var release = {};
|
||||
var lines = stdout.toString().split('\n');
|
||||
lines.forEach(function (line) {
|
||||
if (line.indexOf('=') != -1) {
|
||||
release[line.split('=')[0].trim().toUpperCase()] = line.split('=')[1].trim();
|
||||
}
|
||||
});
|
||||
result.distro = (release.DISTRIB_ID || release.NAME || 'unknown').replace(/"/g, '');
|
||||
result.logofile = getLogoFile(result.distro);
|
||||
result.release = (release.DISTRIB_RELEASE || release.VERSION_ID || 'unknown').replace(/"/g, '');
|
||||
result.codename = (release.DISTRIB_CODENAME || '').replace(/"/g, '');
|
||||
/**
|
||||
* @namespace
|
||||
* @property {string} DISTRIB_ID
|
||||
* @property {string} NAME
|
||||
* @property {string} DISTRIB_RELEASE
|
||||
* @property {string} VERSION_ID
|
||||
* @property {string} DISTRIB_CODENAME
|
||||
*/
|
||||
var release = {};
|
||||
var lines = stdout.toString().split('\n');
|
||||
lines.forEach(function (line) {
|
||||
if (line.indexOf('=') != -1) {
|
||||
release[line.split('=')[0].trim().toUpperCase()] = line.split('=')[1].trim();
|
||||
}
|
||||
});
|
||||
result.distro = (release.DISTRIB_ID || release.NAME || 'unknown').replace(/"/g, '');
|
||||
result.logofile = getLogoFile(result.distro);
|
||||
result.release = (release.DISTRIB_RELEASE || release.VERSION_ID || 'unknown').replace(/"/g, '');
|
||||
result.codename = (release.DISTRIB_CODENAME || '').replace(/"/g, '');
|
||||
//}
|
||||
if (callback) { callback(result) }
|
||||
resolve(result);
|
||||
@ -435,6 +436,45 @@ function osInfo(callback) {
|
||||
|
||||
exports.osInfo = osInfo;
|
||||
|
||||
function versions(callback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
process.nextTick(() => {
|
||||
if (_windows) {
|
||||
let error = new Error(NOT_SUPPORTED);
|
||||
if (callback) { callback(NOT_SUPPORTED) }
|
||||
reject(error);
|
||||
}
|
||||
|
||||
let result = {
|
||||
kernel: os.release(),
|
||||
node: process.versions.node,
|
||||
v8: process.versions.v8,
|
||||
npm: '',
|
||||
pm2: '',
|
||||
openssl: process.versions.openssl
|
||||
};
|
||||
let lines = [];
|
||||
exec("npm -v", function (error, stdout) {
|
||||
if (!error) {
|
||||
result.npm = stdout.toString().split('\n')[0];
|
||||
}
|
||||
exec("pm2 -v", function (error, stdout) {
|
||||
if (!error) {
|
||||
lines = stdout.toString().split('\n');
|
||||
if (lines.length >= 2) {
|
||||
result.pm2 = lines[lines.length-2];
|
||||
}
|
||||
}
|
||||
if (callback) { callback(result) }
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
exports.versions = versions;
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// 4. CPU
|
||||
// ----------------------------------------------------------------------------------
|
||||
@ -816,7 +856,6 @@ function mem(callback) {
|
||||
|
||||
exports.mem = mem;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// 6. Battery
|
||||
// ----------------------------------------------------------------------------------
|
||||
@ -1013,8 +1052,7 @@ function graphics(callback) {
|
||||
is_vga = true;
|
||||
let endpos = lines[i].search(/\[[0-9a-f]{4}:[0-9a-f]{4}]|$/);
|
||||
let parts = lines[i].substr(vgapos, endpos - vgapos).split(':');
|
||||
if (parts.length > 1)
|
||||
{
|
||||
if (parts.length > 1) {
|
||||
parts[1] = parts[1].trim();
|
||||
if (parts[1].toLowerCase().indexOf('corporation')) {
|
||||
currentController.vendor = parts[1].substr(0, parts[1].toLowerCase().indexOf('corporation') + 11).trim();
|
||||
@ -1059,30 +1097,30 @@ function graphics(callback) {
|
||||
let result = {};
|
||||
// find first "Detailed Timing Description"
|
||||
let start = 108;
|
||||
if (edid.substr(start,6) == '000000') {
|
||||
if (edid.substr(start, 6) == '000000') {
|
||||
start += 36;
|
||||
}
|
||||
if (edid.substr(start,6) == '000000') {
|
||||
if (edid.substr(start, 6) == '000000') {
|
||||
start += 36;
|
||||
}
|
||||
if (edid.substr(start,6) == '000000') {
|
||||
if (edid.substr(start, 6) == '000000') {
|
||||
start += 36;
|
||||
}
|
||||
if (edid.substr(start,6) == '000000') {
|
||||
if (edid.substr(start, 6) == '000000') {
|
||||
start += 36;
|
||||
}
|
||||
result.resolutionx = parseInt('0x0' + edid.substr(start + 8,1) + edid.substr(start + 4,2));
|
||||
result.resolutiony = parseInt('0x0' + edid.substr(start + 14,1) + edid.substr(start + 10,2));
|
||||
result.sizex = parseInt('0x0' + edid.substr(start + 28,1) + edid.substr(start + 24,2));
|
||||
result.sizey = parseInt('0x0' + edid.substr(start + 29,1) + edid.substr(start + 26,2));
|
||||
result.resolutionx = parseInt('0x0' + edid.substr(start + 8, 1) + edid.substr(start + 4, 2));
|
||||
result.resolutiony = parseInt('0x0' + edid.substr(start + 14, 1) + edid.substr(start + 10, 2));
|
||||
result.sizex = parseInt('0x0' + edid.substr(start + 28, 1) + edid.substr(start + 24, 2));
|
||||
result.sizey = parseInt('0x0' + edid.substr(start + 29, 1) + edid.substr(start + 26, 2));
|
||||
// monitor name
|
||||
start = edid.indexOf('000000fc00'); // find first "Monitor Description Data"
|
||||
if (start >= 0) {
|
||||
let model_raw = edid.substr(start+10, 26);
|
||||
let model_raw = edid.substr(start + 10, 26);
|
||||
if (model_raw.indexOf('0a') != -1) {
|
||||
model_raw = model_raw.substr(0,model_raw.indexOf('0a'))
|
||||
model_raw = model_raw.substr(0, model_raw.indexOf('0a'))
|
||||
}
|
||||
result.model = model_raw.match(/.{1,2}/g).map(function(v){
|
||||
result.model = model_raw.match(/.{1,2}/g).map(function (v) {
|
||||
return String.fromCharCode(parseInt(v, 16));
|
||||
}).join('');
|
||||
} else {
|
||||
@ -1099,7 +1137,7 @@ function graphics(callback) {
|
||||
let start = 0;
|
||||
for (let i = 1; i < lines.length; i++) { // start with second line
|
||||
if ('' != lines[i].trim()) {
|
||||
if (' ' != lines[i][0] && '\t' != lines[i][0] && lines[i].toLowerCase().indexOf(' connected ') != -1 ) { // first line of new entry
|
||||
if (' ' != lines[i][0] && '\t' != lines[i][0] && lines[i].toLowerCase().indexOf(' connected ') != -1) { // first line of new entry
|
||||
if (Object.keys(currentDisplay).length > 0) { // push last display to array
|
||||
displays.push(currentDisplay);
|
||||
currentDisplay = {};
|
||||
@ -1126,7 +1164,7 @@ function graphics(callback) {
|
||||
is_edid = false;
|
||||
}
|
||||
}
|
||||
if (lines[i].toLowerCase().indexOf('edid:') != -1 ) {
|
||||
if (lines[i].toLowerCase().indexOf('edid:') != -1) {
|
||||
is_edid = true;
|
||||
start = lines[i].search(/\S|$/);
|
||||
}
|
||||
@ -2072,8 +2110,8 @@ function processes(callback) {
|
||||
to = i - 1;
|
||||
result.push({
|
||||
from: from,
|
||||
to: to+1,
|
||||
cap: head.substring(from, to+1)
|
||||
to: to + 1,
|
||||
cap: head.substring(from, to + 1)
|
||||
});
|
||||
from = to + 2;
|
||||
count++;
|
||||
@ -2106,19 +2144,19 @@ function processes(callback) {
|
||||
}
|
||||
|
||||
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();
|
||||
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, "");
|
||||
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,
|
||||
@ -2164,6 +2202,7 @@ function processes(callback) {
|
||||
let guest_nice = (parts.length >= 11 ? parseInt(parts[10]) : 0);
|
||||
return user + nice + system + idle + iowait + irq + softirq + steal + guest + guest_nice;
|
||||
}
|
||||
|
||||
function parseProcPidStat(line, all) {
|
||||
let parts = line.replace(/ +/g, " ").split(' ');
|
||||
if (parts.length >= 17) {
|
||||
@ -2240,7 +2279,7 @@ function processes(callback) {
|
||||
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++) {
|
||||
for (let i = 0; i < result.list.length; i++) {
|
||||
cmd += (';cat /proc/' + result.list[i].pid + '/stat')
|
||||
}
|
||||
exec(cmd, function (error, stdout) {
|
||||
@ -2252,13 +2291,13 @@ function processes(callback) {
|
||||
// process
|
||||
let list_new = {};
|
||||
let resultProcess = {};
|
||||
for (let i=0; i< curr_processes.length; i++) {
|
||||
for (let i = 0; i < curr_processes.length; i++) {
|
||||
resultProcess = parseProcPidStat(curr_processes[i], all);
|
||||
|
||||
if (resultProcess.pid) {
|
||||
|
||||
// store pcpu in outer array
|
||||
let listPos = result.list.map(function(e) { return e.pid; }).indexOf(resultProcess.pid);
|
||||
let listPos = result.list.map(function (e) { return e.pid; }).indexOf(resultProcess.pid);
|
||||
if (listPos >= 0) {
|
||||
result.list[listPos].pcpu = resultProcess.pcpuu + resultProcess.pcpus
|
||||
}
|
||||
@ -2387,19 +2426,19 @@ function parseUsers1(lines) {
|
||||
if (w_first) { // header
|
||||
w_header = l;
|
||||
w_headerline = line;
|
||||
w_header.forEach(function(item) {
|
||||
w_header.forEach(function (item) {
|
||||
w_pos.push(line.indexOf(item))
|
||||
});
|
||||
w_first = false;
|
||||
} else {
|
||||
// split by w_pos
|
||||
result_w.user = line.substring(w_pos[0], w_pos[1]-1).trim();
|
||||
result_w.tty = line.substring(w_pos[1], w_pos[2]-1).trim();
|
||||
result_w.ip = line.substring(w_pos[2], w_pos[3]-1).replace(/\(/g, "").replace(/\)/g, "").trim();
|
||||
result_w.user = line.substring(w_pos[0], w_pos[1] - 1).trim();
|
||||
result_w.tty = line.substring(w_pos[1], w_pos[2] - 1).trim();
|
||||
result_w.ip = line.substring(w_pos[2], w_pos[3] - 1).replace(/\(/g, "").replace(/\)/g, "").trim();
|
||||
result_w.command = line.substring(w_pos[7], 1000).trim();
|
||||
// find corresponding 'who' line
|
||||
who_line = result_who.filter(function(obj) {
|
||||
return (obj.user.substring(0,8).trim() == result_w.user && obj.tty == result_w.tty)
|
||||
who_line = result_who.filter(function (obj) {
|
||||
return (obj.user.substring(0, 8).trim() == result_w.user && obj.tty == result_w.tty)
|
||||
});
|
||||
if (who_line.length == 1) {
|
||||
result.push({
|
||||
@ -2447,8 +2486,8 @@ function parseUsers2(lines) {
|
||||
result_w.ip = (l[2] != '-') ? l[2] : '';
|
||||
result_w.command = l.slice(5, 1000).join(' ');
|
||||
// find corresponding 'who' line
|
||||
who_line = result_who.filter(function(obj) {
|
||||
return (obj.user == result_w.user && (obj.tty.substring(3,1000) == result_w.tty || obj.tty == result_w.tty))
|
||||
who_line = result_who.filter(function (obj) {
|
||||
return (obj.user == result_w.user && (obj.tty.substring(3, 1000) == result_w.tty || obj.tty == result_w.tty))
|
||||
});
|
||||
if (who_line.length == 1) {
|
||||
result.push({
|
||||
@ -2525,7 +2564,6 @@ function users(callback) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -2640,6 +2678,7 @@ function dockerContainers(all, callback) {
|
||||
});
|
||||
return (filtered.length > 0);
|
||||
}
|
||||
|
||||
// fallback - if only callback is given
|
||||
if (isFunction(all) && !callback) {
|
||||
callback = all;
|
||||
@ -2655,7 +2694,7 @@ function dockerContainers(all, callback) {
|
||||
if (callback) { callback(NOT_SUPPORTED) }
|
||||
reject(error);
|
||||
}
|
||||
let cmd = "curl --unix-socket /var/run/docker.sock http:/containers/json" + (all ? "?all=1": "");
|
||||
let cmd = "curl --unix-socket /var/run/docker.sock http:/containers/json" + (all ? "?all=1" : "");
|
||||
exec(cmd, function (error, stdout) {
|
||||
if (!error) {
|
||||
try {
|
||||
@ -2756,8 +2795,8 @@ function docker_calcNetworkIO(networks) {
|
||||
* @property {number} tx_bytes
|
||||
*/
|
||||
var obj = networks[key];
|
||||
rx =+ obj.rx_bytes;
|
||||
tx =+ obj.tx_bytes;
|
||||
rx = +obj.rx_bytes;
|
||||
tx = +obj.tx_bytes;
|
||||
}
|
||||
return {
|
||||
rx: rx,
|
||||
@ -2775,8 +2814,8 @@ function docker_calcBlockIO(blkio_stats) {
|
||||
* @namespace
|
||||
* @property {Array} io_service_bytes_recursive
|
||||
*/
|
||||
if (blkio_stats && blkio_stats.io_service_bytes_recursive && Object.prototype.toString.call( blkio_stats.io_service_bytes_recursive ) === '[object Array]' && blkio_stats.io_service_bytes_recursive.length > 0) {
|
||||
blkio_stats.io_service_bytes_recursive.forEach( function(element) {
|
||||
if (blkio_stats && blkio_stats.io_service_bytes_recursive && Object.prototype.toString.call(blkio_stats.io_service_bytes_recursive) === '[object Array]' && blkio_stats.io_service_bytes_recursive.length > 0) {
|
||||
blkio_stats.io_service_bytes_recursive.forEach(function (element) {
|
||||
/**
|
||||
* @namespace
|
||||
* @property {string} op
|
||||
@ -2875,9 +2914,9 @@ function dockerAll(callback) {
|
||||
reject(error);
|
||||
}
|
||||
dockerContainers(true).then(result => {
|
||||
if (result && Object.prototype.toString.call( result ) === '[object Array]' && result.length > 0) {
|
||||
if (result && Object.prototype.toString.call(result) === '[object Array]' && result.length > 0) {
|
||||
var l = result.length;
|
||||
result.forEach( function(element) {
|
||||
result.forEach(function (element) {
|
||||
dockerContainerStats(element.id).then(res => {
|
||||
// include stats in array
|
||||
element.mem_usage = res.mem_usage;
|
||||
@ -2932,14 +2971,17 @@ function getStaticData(callback) {
|
||||
data.system = res;
|
||||
osInfo().then(res => {
|
||||
data.os = res;
|
||||
cpu().then(res => {
|
||||
data.cpu = res;
|
||||
graphics().then(res => {
|
||||
data.graphics = res;
|
||||
networkInterfaces().then(res => {
|
||||
data.net = res;
|
||||
if (callback) { callback(data) }
|
||||
resolve(data);
|
||||
versions().then(res => {
|
||||
data.versions = res;
|
||||
cpu().then(res => {
|
||||
data.cpu = res;
|
||||
graphics().then(res => {
|
||||
data.graphics = res;
|
||||
networkInterfaces().then(res => {
|
||||
data.net = res;
|
||||
if (callback) { callback(data) }
|
||||
resolve(data);
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user