systeminformation 5.31.17 → 5.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -7
- package/lib/audio.js +6 -5
- package/lib/battery.js +6 -2
- package/lib/bluetooth.js +6 -2
- package/lib/cpu.js +47 -39
- package/lib/docker.js +50 -62
- package/lib/dockerSocket.js +56 -261
- package/lib/filesystem.js +15 -12
- package/lib/graphics.js +134 -65
- package/lib/index.d.ts +6 -8
- package/lib/index.js +4 -2
- package/lib/memory.js +6 -3
- package/lib/network.js +19 -5
- package/lib/osinfo.js +20 -9
- package/lib/printer.js +5 -5
- package/lib/processes.js +49 -15
- package/lib/system.js +3 -4
- package/lib/usb.js +0 -4
- package/lib/util.js +32 -14
- package/lib/virtualbox.js +10 -4
- package/lib/wifi.js +19 -8
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -163,6 +163,8 @@ si.cpu()
|
|
|
163
163
|
|
|
164
164
|
(last 7 major and minor version releases)
|
|
165
165
|
|
|
166
|
+
- Version 5.33.0: `dockerContainer()` added status (healtthy, ...)
|
|
167
|
+
- Version 5.32.0: `graphics()` added temperature values (macOS), `dockerContainers()` added labels
|
|
166
168
|
- Version 5.31.0: `diskLayout()` added smartmontools support (macOS)
|
|
167
169
|
- Version 5.30.0: `processes()` added user (windows) - needed to be reverted
|
|
168
170
|
- Version 5.29.0: `osInfo()` added OS code name (windows)
|
|
@@ -404,14 +406,15 @@ Full function reference with examples can be found at
|
|
|
404
406
|
| | ...[0].external | | | X | | | is external GPU |
|
|
405
407
|
| | ...[0].cores | | | X | | | Apple silicon only |
|
|
406
408
|
| | ...[0].metalVersion | | | X | | | Apple Metal Version |
|
|
409
|
+
| | ...[0].temperatureGpu | X | | X | X | | GPU temperature (see notes below) |
|
|
407
410
|
| | displays[] | X | | X | X | | monitor/display array |
|
|
408
411
|
| | ...[0].vendor | | | | X | | monitor/display vendor |
|
|
409
412
|
| | ...[0].vendorId | | | X | | | vendor ID |
|
|
410
413
|
| | ...[0].deviceName | | | | X | | e.g. \\\\.\\DISPLAY1 |
|
|
411
414
|
| | ...[0].model | X | | X | X | | monitor/display model |
|
|
412
|
-
| | ...[0].productionYear | | | X |
|
|
413
|
-
| | ...[0].serial | | | X |
|
|
414
|
-
| | ...[0].displayId | | | X |
|
|
415
|
+
| | ...[0].productionYear | | | X | X | | production year |
|
|
416
|
+
| | ...[0].serial | | | X | X | | serial number |
|
|
417
|
+
| | ...[0].displayId | | | X | X | | display ID |
|
|
415
418
|
| | ...[0].main | X | | X | X | | true if main monitor |
|
|
416
419
|
| | ...[0].builtin | X | | X | | | true if built-in monitor |
|
|
417
420
|
| | ...[0].connection | X | | X | X | | e.g. DisplayPort or HDMI |
|
|
@@ -422,8 +425,8 @@ Full function reference with examples can be found at
|
|
|
422
425
|
| | ...[0].resolutionY | X | | X | X | | pixel vertical |
|
|
423
426
|
| | ...[0].currentResX | X | | X | X | | current pixel horizontal |
|
|
424
427
|
| | ...[0].currentResY | X | | X | X | | current pixel vertical |
|
|
425
|
-
| | ...[0].positionX |
|
|
426
|
-
| | ...[0].positionY |
|
|
428
|
+
| | ...[0].positionX | X | | X | X | | display position X |
|
|
429
|
+
| | ...[0].positionY | X | | X | X | | display position Y |
|
|
427
430
|
| | ...[0].currentRefreshRate | X | | X | X | | current screen refresh rate |
|
|
428
431
|
|
|
429
432
|
#### 7. Operating System
|
|
@@ -434,7 +437,7 @@ Full function reference with examples can be found at
|
|
|
434
437
|
| | platform | X | X | X | X | X | 'linux', 'darwin', 'Windows', ... |
|
|
435
438
|
| | distro | X | X | X | X | X | |
|
|
436
439
|
| | release | X | X | X | X | X | |
|
|
437
|
-
| | codename | X | | X | X
|
|
440
|
+
| | codename | X | | X | X | | |
|
|
438
441
|
| | kernel | X | X | X | X | X | kernel release - same as os.release() |
|
|
439
442
|
| | arch | X | X | X | X | X | same as os.arch() |
|
|
440
443
|
| | hostname | X | X | X | X | X | same as os.hostname() |
|
|
@@ -829,7 +832,9 @@ Full function reference with examples can be found at
|
|
|
829
832
|
| | [0].createdAt | X | X | X | X | X | creation date time string |
|
|
830
833
|
| | [0].startedAt | X | X | X | X | X | creation date time string |
|
|
831
834
|
| | [0].finishedAt | X | X | X | X | X | creation date time string |
|
|
835
|
+
| | [0].status | X | X | X | X | X | healthy, starting, unhealthy |
|
|
832
836
|
| | [0].state | X | X | X | X | X | created, running, exited |
|
|
837
|
+
| | [0].labels | X | X | X | X | X | object of labels (key-value pairs) |
|
|
833
838
|
| | [0].ports | X | X | X | X | X | array of ports |
|
|
834
839
|
| | [0].mounts | X | X | X | X | X | array of mounts |
|
|
835
840
|
| si.dockerContainerStats(ids, cb) | [{...}] | X | X | X | X | X | statistics for specific containers<br>container IDs: space or comma separated,<br>pass '*' for all containers |
|
|
@@ -1021,7 +1026,9 @@ $ npm install macos-temperature-sensor --save
|
|
|
1021
1026
|
```
|
|
1022
1027
|
|
|
1023
1028
|
`systeminformation` will then detect this additional library and return the
|
|
1024
|
-
temperature when calling systeminformations standard function `cpuTemperature()
|
|
1029
|
+
temperature when calling systeminformations standard function `cpuTemperature()`.
|
|
1030
|
+
On Apple Silicon machines `macos-temperature-sensor` also enables the GPU
|
|
1031
|
+
temperature (`temperatureGpu`) in the `graphics()` controllers
|
|
1025
1032
|
|
|
1026
1033
|
#### Windows Temperature, Battery, ...
|
|
1027
1034
|
|
package/lib/audio.js
CHANGED
|
@@ -103,16 +103,17 @@ function getLinuxAudioPci() {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
function parseWinAudioStatus(n) {
|
|
106
|
+
const num = parseInt(n, 10);
|
|
106
107
|
let status = n;
|
|
107
|
-
if (
|
|
108
|
+
if (num === 1) {
|
|
108
109
|
status = 'other';
|
|
109
|
-
} else if (
|
|
110
|
+
} else if (num === 2) {
|
|
110
111
|
status = 'unknown';
|
|
111
|
-
} else if (
|
|
112
|
+
} else if (num === 3) {
|
|
112
113
|
status = 'enabled';
|
|
113
|
-
} else if (
|
|
114
|
+
} else if (num === 4) {
|
|
114
115
|
status = 'disabled';
|
|
115
|
-
} else if (
|
|
116
|
+
} else if (num === 5) {
|
|
116
117
|
status = 'not applicable';
|
|
117
118
|
}
|
|
118
119
|
return status;
|
package/lib/battery.js
CHANGED
|
@@ -100,8 +100,12 @@ module.exports = (callback) =>
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
if (acPath) {
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
try {
|
|
104
|
+
const file = fs.readFileSync(acPath);
|
|
105
|
+
acConnected = file.toString().trim() === '1';
|
|
106
|
+
} catch {
|
|
107
|
+
util.noop();
|
|
108
|
+
}
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
if (battery_path) {
|
package/lib/bluetooth.js
CHANGED
|
@@ -175,8 +175,12 @@ function bluetoothDevices(callback) {
|
|
|
175
175
|
const macAddr1 = pathParts.length >= 6 ? pathParts[pathParts.length - 2] : null;
|
|
176
176
|
const macAddr2 = pathParts.length >= 7 ? pathParts[pathParts.length - 3] : null;
|
|
177
177
|
if (filename === 'info') {
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
try {
|
|
179
|
+
const infoFile = fs.readFileSync(element, { encoding: 'utf8' }).split('\n');
|
|
180
|
+
result.push(parseLinuxBluetoothInfo(infoFile, macAddr1, macAddr2));
|
|
181
|
+
} catch {
|
|
182
|
+
util.noop();
|
|
183
|
+
}
|
|
180
184
|
}
|
|
181
185
|
});
|
|
182
186
|
// determine "connected" with hcitool con
|
package/lib/cpu.js
CHANGED
|
@@ -979,8 +979,8 @@ function getCpu() {
|
|
|
979
979
|
}
|
|
980
980
|
}
|
|
981
981
|
_cpu_speed = result.speed;
|
|
982
|
-
result.speedMin = Math.round(parseFloat(util.getValue(lines, 'cpu min mhz').replace(/,/g, '.')) / 10.0) / 100;
|
|
983
|
-
result.speedMax = Math.round(parseFloat(util.getValue(lines, 'cpu max mhz').replace(/,/g, '.')) / 10.0) / 100;
|
|
982
|
+
result.speedMin = Math.round(parseFloat(util.getValue(lines, 'cpu min mhz').replace(/,/g, '.')) / 10.0) / 100 || result.speedMin;
|
|
983
|
+
result.speedMax = Math.round(parseFloat(util.getValue(lines, 'cpu max mhz').replace(/,/g, '.')) / 10.0) / 100 || result.speedMax;
|
|
984
984
|
|
|
985
985
|
result = cpuBrandManufacturer(result);
|
|
986
986
|
result.vendor = cpuManufacturer(util.getValue(lines, 'vendor id'));
|
|
@@ -1029,18 +1029,22 @@ function getCpu() {
|
|
|
1029
1029
|
|
|
1030
1030
|
// Test RISC-V
|
|
1031
1031
|
if (util.getValue(lines, 'architecture') === 'riscv64') {
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1032
|
+
try {
|
|
1033
|
+
const linesRiscV = fs.readFileSync('/proc/cpuinfo').toString().split('\n');
|
|
1034
|
+
const uarch = util.getValue(linesRiscV, 'uarch') || '';
|
|
1035
|
+
if (uarch.indexOf(',') > -1) {
|
|
1036
|
+
const split = uarch.split(',');
|
|
1037
|
+
result.manufacturer = cpuManufacturer(split[0]);
|
|
1038
|
+
result.brand = split[1];
|
|
1039
|
+
}
|
|
1040
|
+
} catch {
|
|
1041
|
+
util.noop();
|
|
1038
1042
|
}
|
|
1039
1043
|
}
|
|
1040
1044
|
|
|
1041
1045
|
// socket type
|
|
1042
1046
|
let lines2 = [];
|
|
1043
|
-
exec('export LC_ALL=C; dmidecode
|
|
1047
|
+
exec('export LC_ALL=C; dmidecode -t 4 2>/dev/null | grep "Upgrade: Socket"; unset LC_ALL', (error2, stdout2) => {
|
|
1044
1048
|
lines2 = stdout2.toString().split('\n');
|
|
1045
1049
|
if (lines2 && lines2.length) {
|
|
1046
1050
|
result.socket = util.getValue(lines2, 'Upgrade').replace('Socket', '').trim() || result.socket;
|
|
@@ -1055,7 +1059,7 @@ function getCpu() {
|
|
|
1055
1059
|
if (os.cpus()[0] && os.cpus()[0].model) {
|
|
1056
1060
|
modelline = os.cpus()[0].model;
|
|
1057
1061
|
}
|
|
1058
|
-
exec('export LC_ALL=C; dmidecode -t 4; dmidecode -t 7 unset LC_ALL', (error, stdout) => {
|
|
1062
|
+
exec('export LC_ALL=C; dmidecode -t 4; dmidecode -t 7; unset LC_ALL', (error, stdout) => {
|
|
1059
1063
|
let cache = [];
|
|
1060
1064
|
if (!error) {
|
|
1061
1065
|
const data = stdout.toString().split('# dmidecode');
|
|
@@ -1077,7 +1081,7 @@ function getCpu() {
|
|
|
1077
1081
|
}
|
|
1078
1082
|
_cpu_speed = result.speed;
|
|
1079
1083
|
result.speedMin = result.speed;
|
|
1080
|
-
result.speedMax = Math.round(parseFloat(util.getValue(lines, 'max speed').replace(/Mhz/g, '')) / 10.0) / 100;
|
|
1084
|
+
result.speedMax = Math.round(parseFloat(util.getValue(lines, 'max speed').replace(/Mhz/g, '')) / 10.0) / 100 || result.speed;
|
|
1081
1085
|
|
|
1082
1086
|
result = cpuBrandManufacturer(result);
|
|
1083
1087
|
result.vendor = cpuManufacturer(util.getValue(lines, 'manufacturer'));
|
|
@@ -1149,7 +1153,7 @@ function getCpu() {
|
|
|
1149
1153
|
result = cpuBrandManufacturer(result);
|
|
1150
1154
|
result.revision = util.getValue(lines, 'revision', ':');
|
|
1151
1155
|
result.vendor = util.getValue(lines, 'manufacturer', ':');
|
|
1152
|
-
result.speedMax = Math.round(parseFloat(util.getValue(lines, 'maxclockspeed', ':').replace(/,/g, '.')) / 10.0) / 100;
|
|
1156
|
+
result.speedMax = Math.round(parseFloat(util.getValue(lines, 'maxclockspeed', ':').replace(/,/g, '.')) / 10.0) / 100 || result.speedMax;
|
|
1153
1157
|
if (result.speed === 0 && (result.brand.indexOf('AMD') > -1 || result.brand.toLowerCase().indexOf('ryzen') > -1)) {
|
|
1154
1158
|
result.speed = getAMDSpeed(result.brand);
|
|
1155
1159
|
}
|
|
@@ -1440,28 +1444,28 @@ function cpuTemperature(callback) {
|
|
|
1440
1444
|
|
|
1441
1445
|
if (section === 'acpi') {
|
|
1442
1446
|
// socket temp
|
|
1443
|
-
if (firstPart.indexOf('TEMP') !== -1) {
|
|
1447
|
+
if (firstPart.indexOf('TEMP') !== -1 && temps) {
|
|
1444
1448
|
result.socket.push(parseFloat(temps));
|
|
1445
1449
|
}
|
|
1446
1450
|
} else if (section === 'pch') {
|
|
1447
1451
|
// chipset temp
|
|
1448
|
-
if (firstPart.indexOf('TEMP') !== -1 && !result.chipset) {
|
|
1452
|
+
if (firstPart.indexOf('TEMP') !== -1 && !result.chipset && temps) {
|
|
1449
1453
|
result.chipset = parseFloat(temps);
|
|
1450
1454
|
}
|
|
1451
1455
|
}
|
|
1452
1456
|
// cpu temp
|
|
1453
|
-
if (firstPart.indexOf('PHYSICAL') !== -1 || firstPart.indexOf('PACKAGE') !== -1 || (section === 'coreAMD' && firstPart.indexOf('TDIE') !== -1)) {
|
|
1457
|
+
if ((firstPart.indexOf('PHYSICAL') !== -1 || firstPart.indexOf('PACKAGE') !== -1 || (section === 'coreAMD' && firstPart.indexOf('TDIE') !== -1)) && temps) {
|
|
1454
1458
|
result.main = parseFloat(temps);
|
|
1455
1459
|
}
|
|
1456
|
-
if (firstPart.indexOf('CORE ') !== -1) {
|
|
1460
|
+
if (firstPart.indexOf('CORE ') !== -1 && temps) {
|
|
1457
1461
|
result.cores.push(parseFloat(temps));
|
|
1458
1462
|
}
|
|
1459
|
-
if (firstPart.indexOf('TDIE') !== -1 && tdieTemp === null) {
|
|
1463
|
+
if (firstPart.indexOf('TDIE') !== -1 && tdieTemp === null && temps) {
|
|
1460
1464
|
tdieTemp = parseFloat(temps);
|
|
1461
1465
|
}
|
|
1462
1466
|
|
|
1463
1467
|
// generic temp value from cpuThermal
|
|
1464
|
-
if (section === 'cpuThermal' && firstPart.indexOf('TEMP') !== -1 && cpuThermalTemp === null) {
|
|
1468
|
+
if (section === 'cpuThermal' && firstPart.indexOf('TEMP') !== -1 && cpuThermalTemp === null && temps) {
|
|
1465
1469
|
cpuThermalTemp = parseFloat(temps);
|
|
1466
1470
|
}
|
|
1467
1471
|
});
|
|
@@ -1509,7 +1513,7 @@ function cpuTemperature(callback) {
|
|
|
1509
1513
|
exec('/opt/vc/bin/vcgencmd measure_temp', (error, stdout) => {
|
|
1510
1514
|
if (!error) {
|
|
1511
1515
|
const lines = stdout.toString().split('\n');
|
|
1512
|
-
if (lines.length > 0 && lines[0].indexOf('=')) {
|
|
1516
|
+
if (lines.length > 0 && lines[0].indexOf('=') !== -1) {
|
|
1513
1517
|
result.main = parseFloat(lines[0].split('=')[1]);
|
|
1514
1518
|
result.max = result.main;
|
|
1515
1519
|
}
|
|
@@ -1863,10 +1867,10 @@ function cpuCache(callback) {
|
|
|
1863
1867
|
size = size * (unit === 'kb' ? 1024 : unit === 'mb' ? 1024 * 1024 : unit === 'gb' ? 1024 * 1024 * 1024 : 1);
|
|
1864
1868
|
if (cacheType) {
|
|
1865
1869
|
if (cacheType === 'l1') {
|
|
1866
|
-
result
|
|
1867
|
-
result
|
|
1870
|
+
result[cacheType + 'd'] = size / 2;
|
|
1871
|
+
result[cacheType + 'i'] = size / 2;
|
|
1868
1872
|
} else {
|
|
1869
|
-
result
|
|
1873
|
+
result[cacheType] = size;
|
|
1870
1874
|
}
|
|
1871
1875
|
}
|
|
1872
1876
|
}
|
|
@@ -1883,10 +1887,10 @@ function cpuCache(callback) {
|
|
|
1883
1887
|
lines.forEach((line) => {
|
|
1884
1888
|
let parts = line.split(':');
|
|
1885
1889
|
if (parts[0].toLowerCase().indexOf('hw.l1icachesize') !== -1) {
|
|
1886
|
-
result.
|
|
1890
|
+
result.l1i = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
|
|
1887
1891
|
}
|
|
1888
1892
|
if (parts[0].toLowerCase().indexOf('hw.l1dcachesize') !== -1) {
|
|
1889
|
-
result.
|
|
1893
|
+
result.l1d = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
|
|
1890
1894
|
}
|
|
1891
1895
|
if (parts[0].toLowerCase().indexOf('hw.l2cachesize') !== -1) {
|
|
1892
1896
|
result.l2 = parseInt(parts[1].trim()) * (parts[1].indexOf('K') !== -1 ? 1024 : 1);
|
|
@@ -2085,14 +2089,15 @@ function getLoad() {
|
|
|
2085
2089
|
_cpus[i].loadSteal = _cpus[i].steal - tmpSteal;
|
|
2086
2090
|
_cpus[i].loadGuest = _cpus[i].guest - tmpGuest;
|
|
2087
2091
|
cores[i] = {};
|
|
2088
|
-
|
|
2089
|
-
cores[i].
|
|
2090
|
-
cores[i].
|
|
2091
|
-
cores[i].
|
|
2092
|
-
cores[i].
|
|
2093
|
-
cores[i].
|
|
2094
|
-
cores[i].
|
|
2095
|
-
cores[i].
|
|
2092
|
+
const coreTick = _cpus[i].currentTick || 1;
|
|
2093
|
+
cores[i].load = (_cpus[i].load / coreTick) * 100;
|
|
2094
|
+
cores[i].loadUser = (_cpus[i].loadUser / coreTick) * 100;
|
|
2095
|
+
cores[i].loadSystem = (_cpus[i].loadSystem / coreTick) * 100;
|
|
2096
|
+
cores[i].loadNice = (_cpus[i].loadNice / coreTick) * 100;
|
|
2097
|
+
cores[i].loadIdle = (_cpus[i].loadIdle / coreTick) * 100;
|
|
2098
|
+
cores[i].loadIrq = (_cpus[i].loadIrq / coreTick) * 100;
|
|
2099
|
+
cores[i].loadSteal = (_cpus[i].loadSteal / coreTick) * 100;
|
|
2100
|
+
cores[i].loadGuest = (_cpus[i].loadGuest / coreTick) * 100;
|
|
2096
2101
|
cores[i].rawLoad = _cpus[i].load;
|
|
2097
2102
|
cores[i].rawLoadUser = _cpus[i].loadUser;
|
|
2098
2103
|
cores[i].rawLoadSystem = _cpus[i].loadSystem;
|
|
@@ -2104,7 +2109,7 @@ function getLoad() {
|
|
|
2104
2109
|
}
|
|
2105
2110
|
const totalTick = totalUser + totalSystem + totalNice + totalIrq + totalSteal + totalGuest + totalIdle;
|
|
2106
2111
|
const totalLoad = totalUser + totalSystem + totalNice + totalIrq + totalSteal + totalGuest;
|
|
2107
|
-
const currentTick = totalTick - _current_cpu.tick;
|
|
2112
|
+
const currentTick = totalTick - _current_cpu.tick || 1;
|
|
2108
2113
|
result = {
|
|
2109
2114
|
avgLoad: avgLoad,
|
|
2110
2115
|
currentLoad: ((totalLoad - _current_cpu.load) / currentTick) * 100,
|
|
@@ -2157,12 +2162,15 @@ function getLoad() {
|
|
|
2157
2162
|
const cores = [];
|
|
2158
2163
|
for (let i = 0; i < _corecount; i++) {
|
|
2159
2164
|
cores[i] = {};
|
|
2160
|
-
|
|
2161
|
-
cores[i].
|
|
2162
|
-
cores[i].
|
|
2163
|
-
cores[i].
|
|
2164
|
-
cores[i].
|
|
2165
|
-
cores[i].
|
|
2165
|
+
const coreTick = _cpus[i].currentTick || 1;
|
|
2166
|
+
cores[i].load = (_cpus[i].load / coreTick) * 100;
|
|
2167
|
+
cores[i].loadUser = (_cpus[i].loadUser / coreTick) * 100;
|
|
2168
|
+
cores[i].loadSystem = (_cpus[i].loadSystem / coreTick) * 100;
|
|
2169
|
+
cores[i].loadNice = (_cpus[i].loadNice / coreTick) * 100;
|
|
2170
|
+
cores[i].loadIdle = (_cpus[i].loadIdle / coreTick) * 100;
|
|
2171
|
+
cores[i].loadIrq = (_cpus[i].loadIrq / coreTick) * 100;
|
|
2172
|
+
cores[i].loadSteal = (_cpus[i].loadSteal / coreTick) * 100;
|
|
2173
|
+
cores[i].loadGuest = (_cpus[i].loadGuest / coreTick) * 100;
|
|
2166
2174
|
cores[i].rawLoad = _cpus[i].load;
|
|
2167
2175
|
cores[i].rawLoadUser = _cpus[i].loadUser;
|
|
2168
2176
|
cores[i].rawLoadSystem = _cpus[i].loadSystem;
|
package/lib/docker.js
CHANGED
|
@@ -19,9 +19,8 @@ const DockerSocket = require('./dockerSocket');
|
|
|
19
19
|
const _platform = process.platform;
|
|
20
20
|
const _windows = _platform === 'win32';
|
|
21
21
|
|
|
22
|
-
const
|
|
22
|
+
const _docker_cpu_last_read = {};
|
|
23
23
|
let _docker_socket;
|
|
24
|
-
let _docker_last_read = 0;
|
|
25
24
|
|
|
26
25
|
// --------------------------
|
|
27
26
|
// get containers (parameter all: get also inactive/exited containers)
|
|
@@ -123,7 +122,9 @@ function dockerImages(all, callback) {
|
|
|
123
122
|
if (element.Names && Object.prototype.toString.call(element.Names) === '[object Array]' && element.Names.length > 0) {
|
|
124
123
|
element.Name = element.Names[0].replace(/^\/|\/$/g, '');
|
|
125
124
|
}
|
|
126
|
-
|
|
125
|
+
if (element.Id && typeof element.Id === 'string') {
|
|
126
|
+
workload.push(dockerImagesInspect(element.Id.trim(), element));
|
|
127
|
+
}
|
|
127
128
|
});
|
|
128
129
|
if (workload.length) {
|
|
129
130
|
Promise.all(workload).then((data) => {
|
|
@@ -165,13 +166,13 @@ function dockerImagesInspect(imageID, payload) {
|
|
|
165
166
|
if (typeof imageID !== 'string') {
|
|
166
167
|
return resolve();
|
|
167
168
|
}
|
|
168
|
-
const imageIDSanitized =
|
|
169
|
+
const imageIDSanitized = util.isPrototypePolluted() ? '' : util.sanitizeImageID(imageID);
|
|
169
170
|
if (imageIDSanitized) {
|
|
170
171
|
if (!_docker_socket) {
|
|
171
172
|
_docker_socket = new DockerSocket();
|
|
172
173
|
}
|
|
173
174
|
|
|
174
|
-
_docker_socket.inspectImage(imageIDSanitized
|
|
175
|
+
_docker_socket.inspectImage(imageIDSanitized, (data) => {
|
|
175
176
|
try {
|
|
176
177
|
resolve({
|
|
177
178
|
id: payload.Id,
|
|
@@ -188,8 +189,8 @@ function dockerImagesInspect(imageID, payload) {
|
|
|
188
189
|
created: data.Created ? Math.round(new Date(data.Created).getTime() / 1000) : 0,
|
|
189
190
|
containerConfig: data.ContainerConfig ? data.ContainerConfig : {},
|
|
190
191
|
graphDriver: data.GraphDriver ? data.GraphDriver : {},
|
|
191
|
-
repoDigests: data.RepoDigests ? data.RepoDigests :
|
|
192
|
-
repoTags: data.RepoTags ? data.RepoTags :
|
|
192
|
+
repoDigests: data.RepoDigests ? data.RepoDigests : [],
|
|
193
|
+
repoTags: data.RepoTags ? data.RepoTags : [],
|
|
193
194
|
config: data.Config ? data.Config : {},
|
|
194
195
|
rootFS: data.RootFS ? data.RootFS : {}
|
|
195
196
|
});
|
|
@@ -208,14 +209,7 @@ exports.dockerImages = dockerImages;
|
|
|
208
209
|
|
|
209
210
|
function dockerContainers(all, callback) {
|
|
210
211
|
function inContainers(containers, id) {
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* @namespace
|
|
214
|
-
* @property {string} Id
|
|
215
|
-
*/
|
|
216
|
-
return obj.Id && obj.Id === id;
|
|
217
|
-
});
|
|
218
|
-
return filtered.length > 0;
|
|
212
|
+
return containers.some((obj) => obj.Id && obj.Id.indexOf(id) === 0);
|
|
219
213
|
}
|
|
220
214
|
|
|
221
215
|
// fallback - if only callback is given
|
|
@@ -244,11 +238,11 @@ function dockerContainers(all, callback) {
|
|
|
244
238
|
try {
|
|
245
239
|
docker_containers = data;
|
|
246
240
|
if (docker_containers && Object.prototype.toString.call(docker_containers) === '[object Array]' && docker_containers.length > 0) {
|
|
247
|
-
// GC in
|
|
248
|
-
for (let key in
|
|
249
|
-
if ({}.hasOwnProperty.call(
|
|
241
|
+
// GC in _docker_cpu_last_read
|
|
242
|
+
for (let key in _docker_cpu_last_read) {
|
|
243
|
+
if ({}.hasOwnProperty.call(_docker_cpu_last_read, key)) {
|
|
250
244
|
if (!inContainers(docker_containers, key)) {
|
|
251
|
-
delete
|
|
245
|
+
delete _docker_cpu_last_read[key];
|
|
252
246
|
}
|
|
253
247
|
}
|
|
254
248
|
}
|
|
@@ -257,7 +251,9 @@ function dockerContainers(all, callback) {
|
|
|
257
251
|
if (element.Names && Object.prototype.toString.call(element.Names) === '[object Array]' && element.Names.length > 0) {
|
|
258
252
|
element.Name = element.Names[0].replace(/^\/|\/$/g, '');
|
|
259
253
|
}
|
|
260
|
-
|
|
254
|
+
if (element.Id && typeof element.Id === 'string') {
|
|
255
|
+
workload.push(dockerContainerInspect(element.Id.trim(), element));
|
|
256
|
+
}
|
|
261
257
|
});
|
|
262
258
|
if (workload.length) {
|
|
263
259
|
Promise.all(workload).then((data) => {
|
|
@@ -279,14 +275,6 @@ function dockerContainers(all, callback) {
|
|
|
279
275
|
resolve(result);
|
|
280
276
|
}
|
|
281
277
|
} catch (err) {
|
|
282
|
-
// GC in _docker_container_stats
|
|
283
|
-
for (let key in _docker_container_stats) {
|
|
284
|
-
if ({}.hasOwnProperty.call(_docker_container_stats, key)) {
|
|
285
|
-
if (!inContainers(docker_containers, key)) {
|
|
286
|
-
delete _docker_container_stats[key];
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
278
|
if (callback) {
|
|
291
279
|
callback(result);
|
|
292
280
|
}
|
|
@@ -307,13 +295,13 @@ function dockerContainerInspect(containerID, payload) {
|
|
|
307
295
|
if (typeof containerID !== 'string') {
|
|
308
296
|
return resolve();
|
|
309
297
|
}
|
|
310
|
-
const containerIdSanitized =
|
|
298
|
+
const containerIdSanitized = util.isPrototypePolluted() ? '' : util.sanitizeContainerID(containerID);
|
|
311
299
|
if (containerIdSanitized) {
|
|
312
300
|
if (!_docker_socket) {
|
|
313
301
|
_docker_socket = new DockerSocket();
|
|
314
302
|
}
|
|
315
303
|
|
|
316
|
-
_docker_socket.getInspect(containerIdSanitized
|
|
304
|
+
_docker_socket.getInspect(containerIdSanitized, (data) => {
|
|
317
305
|
try {
|
|
318
306
|
resolve({
|
|
319
307
|
id: payload.Id,
|
|
@@ -327,10 +315,12 @@ function dockerContainerInspect(containerID, payload) {
|
|
|
327
315
|
createdAt: data.Created ? data.Created : '',
|
|
328
316
|
startedAt: data.State && data.State.StartedAt ? data.State.StartedAt : '',
|
|
329
317
|
finishedAt: data.State && data.State.FinishedAt && !data.State.FinishedAt.startsWith('0001-01-01') ? data.State.FinishedAt : '',
|
|
318
|
+
status: data.State && data.State.Health && data.State.Health.Status ? data.State.Health.Status : '',
|
|
330
319
|
state: payload.State,
|
|
331
320
|
restartCount: data.RestartCount || 0,
|
|
332
321
|
platform: data.Platform || '',
|
|
333
322
|
driver: data.Driver || '',
|
|
323
|
+
labels: data.Config && data.Config.Labels ? data.Config.Labels : {},
|
|
334
324
|
ports: payload.Ports,
|
|
335
325
|
mounts: payload.Mounts
|
|
336
326
|
// hostconfig: payload.HostConfig,
|
|
@@ -352,7 +342,7 @@ exports.dockerContainers = dockerContainers;
|
|
|
352
342
|
// --------------------------
|
|
353
343
|
// helper functions for calculation of docker stats
|
|
354
344
|
|
|
355
|
-
function docker_calcCPUPercent(cpu_stats, precpu_stats) {
|
|
345
|
+
function docker_calcCPUPercent(cpu_stats, precpu_stats, id) {
|
|
356
346
|
/**
|
|
357
347
|
* @namespace
|
|
358
348
|
* @property {object} cpu_usage
|
|
@@ -361,42 +351,47 @@ function docker_calcCPUPercent(cpu_stats, precpu_stats) {
|
|
|
361
351
|
* @property {object} cpu_usage
|
|
362
352
|
* @property {Array} cpu_usage.percpu_usage
|
|
363
353
|
*/
|
|
354
|
+
if (!cpu_stats || !cpu_stats.cpu_usage || !precpu_stats) {
|
|
355
|
+
return 0;
|
|
356
|
+
}
|
|
357
|
+
const precpuTotal = precpu_stats.cpu_usage && precpu_stats.cpu_usage.total_usage ? precpu_stats.cpu_usage.total_usage : 0;
|
|
364
358
|
|
|
365
359
|
if (!_windows) {
|
|
366
360
|
let cpuPercent = 0.0;
|
|
367
361
|
// calculate the change for the cpu usage of the container in between readings
|
|
368
|
-
|
|
362
|
+
const cpuDelta = cpu_stats.cpu_usage.total_usage - precpuTotal;
|
|
369
363
|
// calculate the change for the entire system between readings
|
|
370
|
-
|
|
364
|
+
const systemDelta = cpu_stats.system_cpu_usage - (precpu_stats.system_cpu_usage || 0);
|
|
371
365
|
|
|
372
366
|
if (systemDelta > 0.0 && cpuDelta > 0.0) {
|
|
373
367
|
// calculate the change for the cpu usage of the container in between readings
|
|
374
368
|
if (precpu_stats.online_cpus) {
|
|
375
369
|
cpuPercent = (cpuDelta / systemDelta) * precpu_stats.online_cpus * 100.0;
|
|
376
|
-
} else {
|
|
370
|
+
} else if (cpu_stats.cpu_usage.percpu_usage && cpu_stats.cpu_usage.percpu_usage.length) {
|
|
377
371
|
cpuPercent = (cpuDelta / systemDelta) * cpu_stats.cpu_usage.percpu_usage.length * 100.0;
|
|
378
372
|
}
|
|
379
373
|
}
|
|
380
374
|
|
|
381
375
|
return cpuPercent;
|
|
382
376
|
} else {
|
|
383
|
-
|
|
377
|
+
const nanoSecNow = util.nanoSeconds();
|
|
384
378
|
let cpuPercent = 0.0;
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
379
|
+
const lastRead = _docker_cpu_last_read[id] || 0;
|
|
380
|
+
if (lastRead > 0) {
|
|
381
|
+
const possIntervals = nanoSecNow - lastRead;
|
|
382
|
+
const intervalsUsed = cpu_stats.cpu_usage.total_usage - precpuTotal;
|
|
388
383
|
if (possIntervals > 0) {
|
|
389
384
|
cpuPercent = (100.0 * intervalsUsed) / possIntervals;
|
|
390
385
|
}
|
|
391
386
|
}
|
|
392
|
-
|
|
387
|
+
_docker_cpu_last_read[id] = nanoSecNow;
|
|
393
388
|
return cpuPercent;
|
|
394
389
|
}
|
|
395
390
|
}
|
|
396
391
|
|
|
397
392
|
function docker_calcNetworkIO(networks) {
|
|
398
|
-
let rx;
|
|
399
|
-
let wx;
|
|
393
|
+
let rx = 0;
|
|
394
|
+
let wx = 0;
|
|
400
395
|
for (let key in networks) {
|
|
401
396
|
// skip loop if the property is from prototype
|
|
402
397
|
if (!{}.hasOwnProperty.call(networks, key)) {
|
|
@@ -481,25 +476,16 @@ function dockerContainerStats(containerIDs, callback) {
|
|
|
481
476
|
Object.setPrototypeOf(containerIDsSanitized, util.stringObj);
|
|
482
477
|
}
|
|
483
478
|
|
|
484
|
-
containerIDsSanitized = containerIDs;
|
|
485
|
-
containerIDsSanitized = containerIDsSanitized.trim();
|
|
479
|
+
containerIDsSanitized = containerIDs.trim();
|
|
486
480
|
if (containerIDsSanitized !== '*') {
|
|
487
|
-
containerIDsSanitized = '';
|
|
488
|
-
const s = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(containerIDs, true)).trim();
|
|
489
|
-
const l = util.mathMin(s.length, 2000);
|
|
490
|
-
for (let i = 0; i <= l; i++) {
|
|
491
|
-
if (s[i] !== undefined) {
|
|
492
|
-
s[i].__proto__.toLowerCase = util.stringToLower;
|
|
493
|
-
const sl = s[i].toLowerCase();
|
|
494
|
-
if (sl && sl[0] && !sl[1]) {
|
|
495
|
-
containerIDsSanitized = containerIDsSanitized + sl[0];
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}
|
|
481
|
+
containerIDsSanitized = util.isPrototypePolluted() ? '' : util.sanitizeContainerID(containerIDs);
|
|
499
482
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
483
|
+
containerArray = containerIDsSanitized
|
|
484
|
+
.trim()
|
|
485
|
+
.toLowerCase()
|
|
486
|
+
.replace(/,+/g, '|')
|
|
487
|
+
.split('|')
|
|
488
|
+
.filter((item) => item.trim());
|
|
503
489
|
}
|
|
504
490
|
|
|
505
491
|
const result = [];
|
|
@@ -508,8 +494,10 @@ function dockerContainerStats(containerIDs, callback) {
|
|
|
508
494
|
if (containerArray.length && containerArray[0].trim() === '*') {
|
|
509
495
|
containerArray = [];
|
|
510
496
|
dockerContainers().then((allContainers) => {
|
|
511
|
-
for (let container of allContainers) {
|
|
512
|
-
|
|
497
|
+
for (let container of (allContainers || []).filter(Boolean)) {
|
|
498
|
+
if (container.id) {
|
|
499
|
+
containerArray.push(container.id.substring(0, 12));
|
|
500
|
+
}
|
|
513
501
|
}
|
|
514
502
|
if (containerArray.length) {
|
|
515
503
|
dockerContainerStats(containerArray.join(',')).then((result) => {
|
|
@@ -592,7 +580,7 @@ function dockerContainerStatsSingle(containerID) {
|
|
|
592
580
|
result.memUsage = stats.memory_stats && stats.memory_stats.usage ? stats.memory_stats.usage : 0;
|
|
593
581
|
result.memLimit = stats.memory_stats && stats.memory_stats.limit ? stats.memory_stats.limit : 0;
|
|
594
582
|
result.memPercent = stats.memory_stats && stats.memory_stats.usage && stats.memory_stats.limit ? (stats.memory_stats.usage / stats.memory_stats.limit) * 100.0 : 0;
|
|
595
|
-
result.cpuPercent = stats.cpu_stats && stats.precpu_stats ? docker_calcCPUPercent(stats.cpu_stats, stats.precpu_stats) : 0;
|
|
583
|
+
result.cpuPercent = stats.cpu_stats && stats.precpu_stats ? docker_calcCPUPercent(stats.cpu_stats, stats.precpu_stats, containerID) : 0;
|
|
596
584
|
result.pids = stats.pids_stats && stats.pids_stats.current ? stats.pids_stats.current : 0;
|
|
597
585
|
result.restartCount = dataInspect.RestartCount ? dataInspect.RestartCount : 0;
|
|
598
586
|
if (stats.networks) {
|
|
@@ -636,7 +624,7 @@ function dockerContainerProcesses(containerID, callback) {
|
|
|
636
624
|
if (typeof containerID !== 'string') {
|
|
637
625
|
return resolve(result);
|
|
638
626
|
}
|
|
639
|
-
const containerIdSanitized =
|
|
627
|
+
const containerIdSanitized = util.isPrototypePolluted() ? '' : util.sanitizeContainerID(containerID);
|
|
640
628
|
|
|
641
629
|
if (containerIdSanitized) {
|
|
642
630
|
if (!_docker_socket) {
|