improved docs, windows support (networkStats(), cpuCache())), bug fix getStaticData()

This commit is contained in:
Sebastian Hildebrandt
2017-08-07 07:24:45 +02:00
parent 374cbbeb78
commit 83db7166bc
7 changed files with 221 additions and 49 deletions
+46 -7
View File
@@ -167,6 +167,8 @@ function getCpu() {
_cpu_speed = result.speed;
result = cpuBrandManufacturer(result);
result.revision = getValue(lines, 'revision', '=');
result.cache.l1d = 0;
result.cache.l1i = 0;
result.cache.l2 = getValue(lines, 'l2cachesize', '=');
result.cache.l3 = getValue(lines, 'l3cachesize', '=');
if (result.cache.l2) { result.cache.l2 = parseInt(result.cache.l2) * 1024}
@@ -188,7 +190,25 @@ function getCpu() {
}
}
}
resolve(result);
exec("wmic path Win32_CacheMemory get CacheType,InstalledSize,Purpose", function (error, stdout) {
if (!error) {
let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0);
lines.forEach(function (line) {
if (line !== '') {
line = line.trim().split(/\s\s+/);
// L1 Instructions
if (line[2] === 'L1 Cache' && line[0] === '3') {
result.cache.l1i = parseInt(line[1], 10)
}
// L1 Data
if (line[2] === 'L1 Cache' && line[0] === '4') {
result.cache.l1d = parseInt(line[1], 10)
}
}
});
}
resolve(result);
})
})
}
});
@@ -374,13 +394,12 @@ function cpuFlags(callback) {
return new Promise((resolve, reject) => {
process.nextTick(() => {
let result = '';
if (_windows) {
let error = new Error(NOT_SUPPORTED);
if (callback) { callback(NOT_SUPPORTED) }
reject(error);
if (callback) { callback(result) }
resolve(result);
}
let result = '';
if (_linux) {
exec("lscpu", function (error, stdout) {
if (!error) {
@@ -474,13 +493,33 @@ function cpuCache(callback) {
exec("wmic cpu get l2cachesize, l3cachesize /value", function (error, stdout) {
if (!error) {
let lines = stdout.split('\r\n');
result.l1d = 0;
result.l1i = 0;
result.l2 = getValue(lines, 'l2cachesize', '=');
result.l3 = getValue(lines, 'l3cachesize', '=');
if (result.l2) { result.l2 = parseInt(result.l2) * 1024}
if (result.l3) { result.l3 = parseInt(result.l3) * 1024}
}
if (callback) { callback(result) }
resolve(result);
exec("wmic path Win32_CacheMemory get CacheType,InstalledSize,Purpose", function (error, stdout) {
if (!error) {
let lines = stdout.split('\r\n').filter(line => line.trim() !== '').filter((line, idx) => idx > 0);
lines.forEach(function (line) {
if (line !== '') {
line = line.trim().split(/\s\s+/);
// L1 Instructions
if (line[2] === 'L1 Cache' && line[0] === '3') {
result.l1i = parseInt(line[1], 10)
}
// L1 Data
if (line[2] === 'L1 Cache' && line[0] === '4') {
result.l1d = parseInt(line[1], 10)
}
}
});
}
if (callback) { callback(result) }
resolve(result);
})
})
}
});
+12
View File
@@ -1,4 +1,16 @@
'use strict';
// ==================================================================================
// dockerSockets.js
// ----------------------------------------------------------------------------------
// Description: System Information - library
// for Node.js
// Copyright: (c) 2014 - 2017
// Author: Sebastian Hildebrandt
// ----------------------------------------------------------------------------------
// License: MIT
// ==================================================================================
// 13. DockerSockets
// ----------------------------------------------------------------------------------
const net = require('net');
const isWin = require('os').type() === 'Windows_NT';
+30 -5
View File
@@ -23,6 +23,9 @@ const _linux = (_platform === 'Linux');
const _darwin = (_platform === 'Darwin');
const _windows = (_platform === 'Windows_NT');
const NOT_SUPPORTED = 'not supported';
let _resolutionx = 0;
let _resolutiony = 0;
let _pixeldepth = 0;
function getValue(lines, property, separator) {
separator = separator || ':';
@@ -38,6 +41,14 @@ function getValue(lines, property, separator) {
return '';
}
function toInt(value) {
let result = parseInt(value,10);
if (isNaN(result)) {
result = 0;
}
return result
}
function graphics(callback) {
function parseLinesDarwin(lines) {
@@ -313,7 +324,7 @@ function graphics(callback) {
}
if (_windows) {
// https://blogs.technet.microsoft.com/heyscriptingguy/2013/10/03/use-powershell-to-discover-multi-monitor-information/
exec("wmic path win32_VideoController get AdapterCompatibility, AdapterDACType, name, PNPDeviceID, CurrentVerticalResolution, CurrentHorizontalResolution, CurrentNumberOfColors, AdapterRAM, CurrentBitsPerPixel, CurrentRefreshRate, MinRefreshRate, MaxRefreshRate /value", function (error, stdout) {
exec("wmic path win32_VideoController get AdapterCompatibility, AdapterDACType, name, PNPDeviceID, CurrentVerticalResolution, CurrentHorizontalResolution, CurrentNumberOfColors, AdapterRAM, CurrentBitsPerPixel, CurrentRefreshRate, MinRefreshRate, MaxRefreshRate, VideoMemoryType /value", function (error, stdout) {
if (!error) {
let csections = stdout.split(/\n\s*\n/);
result.controllers = parseLinesWindowsControllers(csections);
@@ -321,6 +332,17 @@ function graphics(callback) {
let dsections = stdout.split(/\n\s*\n/);
if (!error) {
result.displays = parseLinesWindowsDisplays(dsections);
if (result.controllers.length === 1 && result.displays.length === 1) {
if (_resolutionx && !result.displays[0].resolutionx) {
result.displays[0].resolutionx = _resolutionx
}
if (_resolutiony && !result.displays[0].resolutiony) {
result.displays[0].resolutiony = _resolutiony
}
if (_pixeldepth) {
result.displays[0].pixeldepth = _pixeldepth
}
}
}
if (callback) {
callback(result)
@@ -330,7 +352,6 @@ function graphics(callback) {
}
})
}
});
});
@@ -345,8 +366,12 @@ function graphics(callback) {
model: getValue(lines, 'name', '='),
vendor: getValue(lines, 'AdapterCompatibility', '='),
bus: getValue(lines, 'PNPDeviceID', '=').startsWith('PCI') ? 'PCI' : '',
vram: getValue(lines, 'AdapterRAM', '=')
vram: getValue(lines, 'AdapterRAM', '='),
vramDynamic: (getValue(lines, 'VideoMemoryType', '=') === '2')
});
_resolutionx = toInt(getValue(lines, 'CurrentHorizontalResolution', '='));
_resolutiony = toInt(getValue(lines, 'CurrentVerticalResolution', '='));
_pixeldepth = toInt(getValue(lines, 'CurrentBitsPerPixel', '='));
}
}
}
@@ -361,8 +386,8 @@ function graphics(callback) {
let lines = sections[i].trim().split('\r\n');
displays.push({
model: getValue(lines, 'MonitorManufacturer', '='),
resolutionx: getValue(lines, 'ScreenWidth', '='),
resolutiony: getValue(lines, 'ScreenHeight', '=')
resolutionx: toInt(getValue(lines, 'ScreenWidth', '=')),
resolutiony: toInt(getValue(lines, 'ScreenHeight', '=')),
});
}
}
+119 -26
View File
@@ -28,26 +28,49 @@ const NOT_SUPPORTED = 'not supported';
let _network = {};
let _default_iface;
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) {
let ifacename = '';
let scopeid = 9999;
if (_linux || _darwin) {
let cmd = (_linux ? "route 2>/dev/null | grep default | awk '{print $8}'" : "route get 0.0.0.0 2>/dev/null | grep interface: | awk '{print $2}'");
let result = execSync(cmd);
ifacename = result.toString().split('\n')[0];
}
if (!ifacename) { // fallback - "first" external interface
const sortObject = o => Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {});
if (!ifacename) { // fallback - "first" external interface (sorted by scopeid)
let ifaces = sortObject(os.networkInterfaces());
const compare = function(a,b) {
if (a.scopeid < b.scopeid)
return -1;
if (a.scopeid > b.scopeid)
return 1;
return 0;
}
let ifaces = os.networkInterfaces();
for (let dev in ifaces) {
if (ifaces.hasOwnProperty(dev)) {
ifaces[dev].forEach(function (details) {
if (details && details.internal === false) {
ifacename = ifacename || dev;
if (details && details.internal === false && details.scopeid && details.scopeid < scopeid) {
ifacename = dev;
scopeid = details.scopeid;
}
})
}
@@ -64,12 +87,6 @@ function networkInterfaceDefault(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 = getDefaultNetworkInterface();
if (callback) { callback(result) }
resolve(result);
@@ -157,6 +174,46 @@ function calcNetworkSpeed(iface, rx, tx, operstate) {
function networkStats(iface, callback) {
function parseLinesWindowsNics(sections){
let nics = [];
for (let i in sections) {
if (sections.hasOwnProperty(i)) {
if (sections[i].trim() !== "") {
let lines = sections[i].trim().split('\r\n');
let netEnabled = getValue(lines, 'NetEnabled', '=');
if (netEnabled) {
nics.push({
mac: getValue(lines, 'MACAddress', '=').toLowerCase(),
name: getValue(lines, 'Name', '=').replace(/[()\[\] ]+/g, "").toLowerCase(),
netEnabled: netEnabled === 'TRUE'
});
}
}
}
}
return nics;
}
function parseLinesWindowsPerfData(sections){
let perfData = [];
for (let i in sections) {
if (sections.hasOwnProperty(i)) {
if (sections[i].trim() !== "") {
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)
});
}
}
}
return perfData;
}
// fallback - if only callback is given
if (util.isFunction(iface) && !callback) {
callback = iface;
@@ -168,9 +225,6 @@ function networkStats(iface, callback) {
_default_iface = _default_iface || getDefaultNetworkInterface();
iface = iface || _default_iface; // (_darwin ? 'en0' : 'eth0');
if (_windows) {
iface = 'all'
}
let result = {
iface: iface,
@@ -239,21 +293,60 @@ function networkStats(iface, callback) {
});
}
if (_windows) {
cmd = "netstat -e";
// NICs
let perfData = [];
let nics = [];
cmd = "wmic nic get MACAddress, name, NetEnabled /value";
exec(cmd, function (error, stdout) {
const lines = stdout.split('\r\n');
for (let i = 0; i < lines.length; i++) {
if (lines[i].toLowerCase().startsWith('bytes')) {
const parts = lines[i].substr(5).trim().replace(/ +/g, " ").split(' ');
if (parts.length > 1) {
rx = parseInt(parts[0]);
tx = parseInt(parts[1]);
result = calcNetworkSpeed(iface, rx, tx, operstate);
if (!error) {
const nsections = stdout.split(/\n\s*\n/);
nics = parseLinesWindowsNics(nsections);
// Performance Data
cmd = "wmic path Win32_PerfRawData_Tcpip_NetworkInterface Get name,BytesReceivedPersec,BytesSentPersec,BytesTotalPersec /value";
exec(cmd, function (error, stdout) {
if (!error) {
const psections = stdout.split(/\n\s*\n/);
perfData = parseLinesWindowsPerfData(psections);
}
}
// Network Interfaces
networkInterfaces().then(interfaces => {
// get mac from 'interfaces' by interfacename
let mac = '';
interfaces.forEach(detail => {
if (detail.iface === iface) {
mac = detail.mac;
}
})
// get name from 'nics' (by macadress)
let name = '';
nics.forEach(detail => {
if (detail.mac === mac) {
name = detail.name;
operstate = (detail.netEnabled ? 'up' : 'down')
}
})
// get bytes sent, received from perfData by name
rx = 0;
tx = 0;
perfData.forEach(detail => {
if (detail.name === name) {
rx = detail.rx;
tx = detail.tx;
}
});
if (rx && tx) {
result = calcNetworkSpeed(iface, parseInt(rx), parseInt(tx), operstate);
}
if (callback) { callback(result) }
resolve(result);
})
})
}
if (callback) { callback(result) }
resolve(result);
});
}
} else {