514 lines
15 KiB
JavaScript
514 lines
15 KiB
JavaScript
'use strict';
|
|
// @ts-check
|
|
// ==================================================================================
|
|
// index.js
|
|
// ----------------------------------------------------------------------------------
|
|
// Description: System Information - library
|
|
// for Node.js
|
|
// Copyright: (c) 2014 - 2022
|
|
// Author: Sebastian Hildebrandt
|
|
// ----------------------------------------------------------------------------------
|
|
// Contributors: Guillaume Legrain (https://github.com/glegrain)
|
|
// Riccardo Novaglia (https://github.com/richy24)
|
|
// Quentin Busuttil (https://github.com/Buzut)
|
|
// Lapsio (https://github.com/lapsio)
|
|
// csy (https://github.com/csy1983)
|
|
// ----------------------------------------------------------------------------------
|
|
// License: MIT
|
|
// ==================================================================================
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
// Dependencies
|
|
// ----------------------------------------------------------------------------------
|
|
|
|
const lib_version = require('../package.json').version;
|
|
const util = require('./util');
|
|
const system = require('./system');
|
|
const osInfo = require('./osinfo');
|
|
const cpu = require('./cpu');
|
|
const memory = require('./memory');
|
|
const battery = require('./battery');
|
|
const graphics = require('./graphics');
|
|
const filesystem = require('./filesystem');
|
|
const network = require('./network');
|
|
const wifi = require('./wifi');
|
|
const processes = require('./processes');
|
|
const users = require('./users');
|
|
const internet = require('./internet');
|
|
const docker = require('./docker');
|
|
const vbox = require('./virtualbox');
|
|
const printer = require('./printer');
|
|
const usb = require('./usb');
|
|
const audio = require('./audio');
|
|
const bluetooth = require('./bluetooth');
|
|
|
|
let _platform = process.platform;
|
|
const _windows = (_platform === 'win32');
|
|
const _freebsd = (_platform === 'freebsd');
|
|
const _openbsd = (_platform === 'openbsd');
|
|
const _netbsd = (_platform === 'netbsd');
|
|
const _sunos = (_platform === 'sunos');
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
// init
|
|
// ----------------------------------------------------------------------------------
|
|
|
|
if (_windows) {
|
|
util.getCodepage();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
// General
|
|
// ----------------------------------------------------------------------------------
|
|
|
|
function version() {
|
|
return lib_version;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
// Get static and dynamic data (all)
|
|
// ----------------------------------------------------------------------------------
|
|
|
|
// --------------------------
|
|
// get static data - they should not change until restarted
|
|
|
|
function getStaticData(callback) {
|
|
|
|
return new Promise((resolve) => {
|
|
process.nextTick(() => {
|
|
|
|
let data = {};
|
|
|
|
data.version = version();
|
|
|
|
Promise.all([
|
|
system.system(),
|
|
system.bios(),
|
|
system.baseboard(),
|
|
system.chassis(),
|
|
osInfo.osInfo(),
|
|
osInfo.uuid(),
|
|
osInfo.versions(),
|
|
cpu.cpu(),
|
|
cpu.cpuFlags(),
|
|
graphics.graphics(),
|
|
network.networkInterfaces(),
|
|
memory.memLayout(),
|
|
filesystem.diskLayout()
|
|
]).then(res => {
|
|
data.system = res[0];
|
|
data.bios = res[1];
|
|
data.baseboard = res[2];
|
|
data.chassis = res[3];
|
|
data.os = res[4];
|
|
data.uuid = res[5];
|
|
data.versions = res[6];
|
|
data.cpu = res[7];
|
|
data.cpu.flags = res[8];
|
|
data.graphics = res[9];
|
|
data.net = res[10];
|
|
data.memLayout = res[11];
|
|
data.diskLayout = res[12];
|
|
if (callback) { callback(data); }
|
|
resolve(data);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
// --------------------------
|
|
// get all dynamic data - e.g. for monitoring agents
|
|
// may take some seconds to get all data
|
|
// --------------------------
|
|
// 2 additional parameters needed
|
|
// - srv: comma separated list of services to monitor e.g. "mysql, apache, postgresql"
|
|
// - iface: define network interface for which you like to monitor network speed e.g. "eth0"
|
|
|
|
function getDynamicData(srv, iface, callback) {
|
|
|
|
if (util.isFunction(iface)) {
|
|
callback = iface;
|
|
iface = '';
|
|
}
|
|
if (util.isFunction(srv)) {
|
|
callback = srv;
|
|
srv = '';
|
|
}
|
|
|
|
return new Promise((resolve) => {
|
|
process.nextTick(() => {
|
|
|
|
iface = iface || network.getDefaultNetworkInterface();
|
|
srv = srv || '';
|
|
|
|
// use closure to track ƒ completion
|
|
let functionProcessed = (function () {
|
|
let totalFunctions = 15;
|
|
if (_windows) { totalFunctions = 13; }
|
|
if (_freebsd || _openbsd || _netbsd) { totalFunctions = 11; }
|
|
if (_sunos) { totalFunctions = 6; }
|
|
|
|
return function () {
|
|
if (--totalFunctions === 0) {
|
|
if (callback) {
|
|
callback(data);
|
|
}
|
|
resolve(data);
|
|
}
|
|
};
|
|
})();
|
|
|
|
// var totalFunctions = 14;
|
|
// function functionProcessed() {
|
|
// if (--totalFunctions === 0) {
|
|
// if (callback) { callback(data) }
|
|
// resolve(data);
|
|
// }
|
|
// }
|
|
|
|
let data = {};
|
|
|
|
// get time
|
|
data.time = osInfo.time();
|
|
|
|
/**
|
|
* @namespace
|
|
* @property {Object} versions
|
|
* @property {string} versions.node
|
|
* @property {string} versions.v8
|
|
*/
|
|
data.node = process.versions.node;
|
|
data.v8 = process.versions.v8;
|
|
|
|
cpu.cpuCurrentSpeed().then(res => {
|
|
data.cpuCurrentSpeed = res;
|
|
functionProcessed();
|
|
});
|
|
|
|
users.users().then(res => {
|
|
data.users = res;
|
|
functionProcessed();
|
|
});
|
|
|
|
processes.processes().then(res => {
|
|
data.processes = res;
|
|
functionProcessed();
|
|
});
|
|
|
|
cpu.currentLoad().then(res => {
|
|
data.currentLoad = res;
|
|
functionProcessed();
|
|
});
|
|
|
|
if (!_sunos) {
|
|
cpu.cpuTemperature().then(res => {
|
|
data.temp = res;
|
|
functionProcessed();
|
|
});
|
|
}
|
|
|
|
if (!_openbsd && !_freebsd && !_netbsd && !_sunos) {
|
|
network.networkStats(iface).then(res => {
|
|
data.networkStats = res;
|
|
functionProcessed();
|
|
});
|
|
}
|
|
|
|
if (!_sunos) {
|
|
network.networkConnections().then(res => {
|
|
data.networkConnections = res;
|
|
functionProcessed();
|
|
});
|
|
}
|
|
|
|
memory.mem().then(res => {
|
|
data.mem = res;
|
|
functionProcessed();
|
|
});
|
|
|
|
if (!_sunos) {
|
|
battery().then(res => {
|
|
data.battery = res;
|
|
functionProcessed();
|
|
});
|
|
}
|
|
|
|
if (!_sunos) {
|
|
processes.services(srv).then(res => {
|
|
data.services = res;
|
|
functionProcessed();
|
|
});
|
|
}
|
|
|
|
if (!_sunos) {
|
|
filesystem.fsSize().then(res => {
|
|
data.fsSize = res;
|
|
functionProcessed();
|
|
});
|
|
}
|
|
|
|
if (!_windows && !_openbsd && !_freebsd && !_netbsd && !_sunos) {
|
|
filesystem.fsStats().then(res => {
|
|
data.fsStats = res;
|
|
functionProcessed();
|
|
});
|
|
}
|
|
|
|
if (!_windows && !_openbsd && !_freebsd && !_netbsd && !_sunos) {
|
|
filesystem.disksIO().then(res => {
|
|
data.disksIO = res;
|
|
functionProcessed();
|
|
});
|
|
}
|
|
|
|
if (!_openbsd && !_freebsd && !_netbsd && !_sunos) {
|
|
wifi.wifiNetworks().then(res => {
|
|
data.wifiNetworks = res;
|
|
functionProcessed();
|
|
});
|
|
}
|
|
|
|
internet.inetLatency().then(res => {
|
|
data.inetLatency = res;
|
|
functionProcessed();
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
// --------------------------
|
|
// get all data at once
|
|
// --------------------------
|
|
// 2 additional parameters needed
|
|
// - srv: comma separated list of services to monitor e.g. "mysql, apache, postgresql"
|
|
// - iface: define network interface for which you like to monitor network speed e.g. "eth0"
|
|
|
|
function getAllData(srv, iface, callback) {
|
|
|
|
return new Promise((resolve) => {
|
|
process.nextTick(() => {
|
|
let data = {};
|
|
|
|
if (iface && util.isFunction(iface) && !callback) {
|
|
callback = iface;
|
|
iface = '';
|
|
}
|
|
|
|
if (srv && util.isFunction(srv) && !iface && !callback) {
|
|
callback = srv;
|
|
srv = '';
|
|
iface = '';
|
|
}
|
|
|
|
getStaticData().then(res => {
|
|
data = res;
|
|
getDynamicData(srv, iface).then(res => {
|
|
for (let key in res) {
|
|
if ({}.hasOwnProperty.call(res, key)) {
|
|
data[key] = res[key];
|
|
}
|
|
}
|
|
if (callback) { callback(data); }
|
|
resolve(data);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
function get(valueObject, callback) {
|
|
return new Promise((resolve) => {
|
|
process.nextTick(() => {
|
|
const allPromises = Object.keys(valueObject)
|
|
.filter(func => ({}.hasOwnProperty.call(exports, func)))
|
|
.map(func => {
|
|
const params = valueObject[func].substring(valueObject[func].lastIndexOf('(') + 1, valueObject[func].lastIndexOf(')'));
|
|
let funcWithoutParams = func.indexOf(')') >= 0 ? func.split(')')[1].trim() : func;
|
|
funcWithoutParams = func.indexOf('|') >= 0 ? func.split('|')[0].trim() : funcWithoutParams;
|
|
if (params) {
|
|
return exports[funcWithoutParams](params);
|
|
} else {
|
|
return exports[funcWithoutParams]('');
|
|
}
|
|
});
|
|
|
|
Promise.all(allPromises).then(data => {
|
|
const result = {};
|
|
let i = 0;
|
|
for (let key in valueObject) {
|
|
if ({}.hasOwnProperty.call(valueObject, key) && {}.hasOwnProperty.call(exports, key) && data.length > i) {
|
|
if (valueObject[key] === '*' || valueObject[key] === 'all') {
|
|
result[key] = data[i];
|
|
} else {
|
|
let keys = valueObject[key];
|
|
// let params = '';
|
|
let filter = '';
|
|
let filterParts = [];
|
|
// remove params
|
|
if (keys.indexOf(')') >= 0) {
|
|
keys = keys.split(')')[1].trim();
|
|
}
|
|
// extract filter and remove it from keys
|
|
if (keys.indexOf('|') >= 0) {
|
|
filter = keys.split('|')[1].trim();
|
|
filterParts = filter.split(':');
|
|
|
|
keys = keys.split('|')[0].trim();
|
|
}
|
|
keys = keys.replace(/,/g, ' ').replace(/ +/g, ' ').split(' ');
|
|
if (data[i]) {
|
|
if (Array.isArray(data[i])) {
|
|
// result is in an array, go through all elements of array and pick only the right ones
|
|
const partialArray = [];
|
|
data[i].forEach(element => {
|
|
let partialRes = {};
|
|
if (keys.length === 1 && (keys[0] === '*' || keys[0] === 'all')) {
|
|
partialRes = element;
|
|
} else {
|
|
keys.forEach(k => {
|
|
if ({}.hasOwnProperty.call(element, k)) {
|
|
partialRes[k] = element[k];
|
|
}
|
|
});
|
|
}
|
|
// if there is a filter, then just take those elements
|
|
if (filter && filterParts.length === 2) {
|
|
if ({}.hasOwnProperty.call(partialRes, filterParts[0].trim())) {
|
|
const val = partialRes[filterParts[0].trim()];
|
|
if (typeof val == 'number') {
|
|
if (val === parseFloat(filterParts[1].trim())) {
|
|
partialArray.push(partialRes);
|
|
}
|
|
} else if (typeof val == 'string') {
|
|
if (val.toLowerCase() === filterParts[1].trim().toLowerCase()) {
|
|
partialArray.push(partialRes);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
partialArray.push(partialRes);
|
|
}
|
|
|
|
});
|
|
result[key] = partialArray;
|
|
} else {
|
|
const partialRes = {};
|
|
keys.forEach(k => {
|
|
if ({}.hasOwnProperty.call(data[i], k)) {
|
|
partialRes[k] = data[i][k];
|
|
}
|
|
});
|
|
result[key] = partialRes;
|
|
}
|
|
} else {
|
|
result[key] = {};
|
|
}
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
if (callback) { callback(result); }
|
|
resolve(result);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
function observe(valueObject, interval, callback) {
|
|
let _data = null;
|
|
|
|
const result = setInterval(() => {
|
|
get(valueObject).then(data => {
|
|
if (JSON.stringify(_data) !== JSON.stringify(data)) {
|
|
_data = Object.assign({}, data);
|
|
callback(data);
|
|
}
|
|
});
|
|
}, interval);
|
|
return result;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
// export all libs
|
|
// ----------------------------------------------------------------------------------
|
|
|
|
exports.version = version;
|
|
exports.system = system.system;
|
|
exports.bios = system.bios;
|
|
exports.baseboard = system.baseboard;
|
|
exports.chassis = system.chassis;
|
|
|
|
exports.time = osInfo.time;
|
|
exports.osInfo = osInfo.osInfo;
|
|
exports.versions = osInfo.versions;
|
|
exports.shell = osInfo.shell;
|
|
exports.uuid = osInfo.uuid;
|
|
|
|
exports.cpu = cpu.cpu;
|
|
exports.cpuFlags = cpu.cpuFlags;
|
|
exports.cpuCache = cpu.cpuCache;
|
|
exports.cpuCurrentSpeed = cpu.cpuCurrentSpeed;
|
|
exports.cpuTemperature = cpu.cpuTemperature;
|
|
exports.currentLoad = cpu.currentLoad;
|
|
exports.fullLoad = cpu.fullLoad;
|
|
|
|
exports.mem = memory.mem;
|
|
exports.memLayout = memory.memLayout;
|
|
|
|
exports.battery = battery;
|
|
|
|
exports.graphics = graphics.graphics;
|
|
|
|
exports.fsSize = filesystem.fsSize;
|
|
exports.fsOpenFiles = filesystem.fsOpenFiles;
|
|
exports.blockDevices = filesystem.blockDevices;
|
|
exports.fsStats = filesystem.fsStats;
|
|
exports.disksIO = filesystem.disksIO;
|
|
exports.diskLayout = filesystem.diskLayout;
|
|
|
|
exports.networkInterfaceDefault = network.networkInterfaceDefault;
|
|
exports.networkGatewayDefault = network.networkGatewayDefault;
|
|
exports.networkInterfaces = network.networkInterfaces;
|
|
exports.networkStats = network.networkStats;
|
|
exports.networkConnections = network.networkConnections;
|
|
|
|
exports.wifiNetworks = wifi.wifiNetworks;
|
|
exports.wifiInterfaces = wifi.wifiInterfaces;
|
|
exports.wifiConnections = wifi.wifiConnections;
|
|
|
|
exports.services = processes.services;
|
|
exports.processes = processes.processes;
|
|
exports.processLoad = processes.processLoad;
|
|
|
|
exports.users = users.users;
|
|
|
|
exports.inetChecksite = internet.inetChecksite;
|
|
exports.inetLatency = internet.inetLatency;
|
|
|
|
exports.dockerInfo = docker.dockerInfo;
|
|
exports.dockerImages = docker.dockerImages;
|
|
exports.dockerContainers = docker.dockerContainers;
|
|
exports.dockerContainerStats = docker.dockerContainerStats;
|
|
exports.dockerContainerProcesses = docker.dockerContainerProcesses;
|
|
exports.dockerVolumes = docker.dockerVolumes;
|
|
exports.dockerAll = docker.dockerAll;
|
|
|
|
exports.vboxInfo = vbox.vboxInfo;
|
|
|
|
exports.printer = printer.printer;
|
|
|
|
exports.usb = usb.usb;
|
|
|
|
exports.audio = audio.audio;
|
|
exports.bluetoothDevices = bluetooth.bluetoothDevices;
|
|
|
|
exports.getStaticData = getStaticData;
|
|
exports.getDynamicData = getDynamicData;
|
|
exports.getAllData = getAllData;
|
|
exports.get = get;
|
|
exports.observe = observe;
|
|
|
|
exports.powerShellStart = util.powerShellStart;
|
|
exports.powerShellRelease = util.powerShellRelease;
|