diskLayout() added S.M.A.R.T. status
This commit is contained in:
parent
f424ceee3c
commit
68d0d1427f
@ -100,6 +100,7 @@ Other changes
|
|||||||
|
|
||||||
| Version | Date | Comment |
|
| Version | Date | Comment |
|
||||||
| -------------- | -------------- | -------- |
|
| -------------- | -------------- | -------- |
|
||||||
|
| 3.45.0 | 2018-09-04 | `diskLayout()` added smartStatus |
|
||||||
| 3.44.2 | 2018-08-28 | added code quality badges |
|
| 3.44.2 | 2018-08-28 | added code quality badges |
|
||||||
| 3.44.1 | 2018-08-28 | code cleanup |
|
| 3.44.1 | 2018-08-28 | code cleanup |
|
||||||
| 3.44.0 | 2018-08-25 | `battery()` bugfix & added type, model, manufacturer, serial |
|
| 3.44.0 | 2018-08-25 | `battery()` bugfix & added type, model, manufacturer, serial |
|
||||||
|
|||||||
@ -56,13 +56,13 @@ async function cpu() {
|
|||||||
|
|
||||||
(last 7 major and minor version releases)
|
(last 7 major and minor version releases)
|
||||||
|
|
||||||
|
- Version 3.45.0: `diskLayout()` added S.M.A.R.T. status
|
||||||
- Version 3.44.0: `battery()` added type, model, manufacturer, serial, timeremaining
|
- Version 3.44.0: `battery()` added type, model, manufacturer, serial, timeremaining
|
||||||
- Version 3.43.0: added speed per CPU core `cpuCurrentspeed()`
|
- Version 3.43.0: added speed per CPU core `cpuCurrentspeed()`
|
||||||
- Version 3.42.0: added parent process PID `processes()`
|
- Version 3.42.0: added parent process PID `processes()`
|
||||||
- Version 3.41.0: first partial `SunOS` support
|
- Version 3.41.0: first partial `SunOS` support
|
||||||
- Version 3.40.0: extended `versions()` (php, redis, mongodb)
|
- Version 3.40.0: extended `versions()` (php, redis, mongodb)
|
||||||
- Version 3.39.0: added `versions().mysql` and `versions().nginx`, start implementing `SunOS` support
|
- Version 3.39.0: added `versions().mysql` and `versions().nginx`, start implementing `SunOS` support
|
||||||
- Version 3.38.0: added `battery.acconnected`
|
|
||||||
- ...
|
- ...
|
||||||
|
|
||||||
You can find all changes here: [detailed changelog][changelog-url]
|
You can find all changes here: [detailed changelog][changelog-url]
|
||||||
@ -193,6 +193,7 @@ I also created a nice little command line tool called [mmon][mmon-github-url] (
|
|||||||
| | [0].sectorsPerTrack | | | | X | | sectors per track |
|
| | [0].sectorsPerTrack | | | | X | | sectors per track |
|
||||||
| | [0].totalSectors | | | | X | | total sectors |
|
| | [0].totalSectors | | | | X | | total sectors |
|
||||||
| | [0].bytesPerSector | | | | X | | bytes per sector |
|
| | [0].bytesPerSector | | | | X | | bytes per sector |
|
||||||
|
| | [0].smartStatus | X | | X | X | | S.M.A.R.T Status (see Known Issues) |
|
||||||
| si.battery(cb) | {...} | X | X | X | X | | battery information |
|
| si.battery(cb) | {...} | X | X | X | X | | battery information |
|
||||||
| | hasbattery | X | X | X | X | | indicates presence of battery |
|
| | hasbattery | X | X | X | X | | indicates presence of battery |
|
||||||
| | cyclecount | X | | X | | | numbers of recharges |
|
| | cyclecount | X | | X | | | numbers of recharges |
|
||||||
@ -518,6 +519,10 @@ In some cases we also discovered that `wmic` returned incorrect temperature valu
|
|||||||
In some cases you need to install the linux `sensors` package to be able to measure temperature
|
In some cases you need to install the linux `sensors` package to be able to measure temperature
|
||||||
e.g. on DEBIAN based systems by running `sudo apt-get install lm-sensors`
|
e.g. on DEBIAN based systems by running `sudo apt-get install lm-sensors`
|
||||||
|
|
||||||
|
#### Linux S.M.A.R.T. Status
|
||||||
|
|
||||||
|
To be able to detect S.M.A.R.T. status on Linux you need to install `smartmontools`. On DEBIAN based linux distributions you can install it by running `sudo apt-get install smartmontools`
|
||||||
|
|
||||||
## *: Additional Notes
|
## *: Additional Notes
|
||||||
|
|
||||||
In `fsStats`, `disksIO` and `networkStats` the `results / sec.` values (rx_sec, IOPS, ...) are calculated correctly beginning
|
In `fsStats`, `disksIO` and `networkStats` the `results / sec.` values (rx_sec, IOPS, ...) are calculated correctly beginning
|
||||||
|
|||||||
@ -608,6 +608,7 @@ function diskLayout(callback) {
|
|||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
|
|
||||||
let result = [];
|
let result = [];
|
||||||
|
let cmd = '';
|
||||||
|
|
||||||
if (_linux) {
|
if (_linux) {
|
||||||
exec('export LC_ALL=C; lshw -class disk; unset LC_ALL', function (error, stdout) {
|
exec('export LC_ALL=C; lshw -class disk; unset LC_ALL', function (error, stdout) {
|
||||||
@ -617,6 +618,7 @@ function diskLayout(callback) {
|
|||||||
devices.forEach(function (device) {
|
devices.forEach(function (device) {
|
||||||
let lines = device.split('\n');
|
let lines = device.split('\n');
|
||||||
let mediumType = '';
|
let mediumType = '';
|
||||||
|
const BSDName = util.getValue(lines, 'logical name', ':', true).trim();
|
||||||
const logical = util.getValue(lines, 'logical name', ':', true).trim().replace(/\/dev\//g, '');
|
const logical = util.getValue(lines, 'logical name', ':', true).trim().replace(/\/dev\//g, '');
|
||||||
try {
|
try {
|
||||||
mediumType = execSync('cat /sys/block/' + logical + '/queue/rotational').toString().split('\n')[0];
|
mediumType = execSync('cat /sys/block/' + logical + '/queue/rotational').toString().split('\n')[0];
|
||||||
@ -642,14 +644,53 @@ function diskLayout(callback) {
|
|||||||
firmwareRevision: util.getValue(lines, 'version:', ':', true).trim(),
|
firmwareRevision: util.getValue(lines, 'version:', ':', true).trim(),
|
||||||
serialNum: util.getValue(lines, 'serial:', ':', true).trim(),
|
serialNum: util.getValue(lines, 'serial:', ':', true).trim(),
|
||||||
interfaceType: '',
|
interfaceType: '',
|
||||||
|
smartStatus: 'unknown',
|
||||||
|
BSDName: BSDName
|
||||||
});
|
});
|
||||||
|
cmd = cmd + 'printf "\n' + BSDName + '|"; smartctl -H ' + BSDName + ' | grep overall;';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (callback) {
|
if (cmd) {
|
||||||
callback(result);
|
cmd = cmd + 'printf "\n"';
|
||||||
|
exec(cmd, function (error, stdout) {
|
||||||
|
let lines = stdout.toString().split('\n');
|
||||||
|
lines.forEach(line => {
|
||||||
|
if (line) {
|
||||||
|
let parts = line.split('|');
|
||||||
|
if (parts.length === 2) {
|
||||||
|
let BSDName = parts[0];
|
||||||
|
parts[1] = parts[1].trim();
|
||||||
|
let parts2 = parts[1].split(':');
|
||||||
|
if (parts2.length === 2) {
|
||||||
|
parts2[1] = parts2[1].trim();
|
||||||
|
let status = parts2[1].toLowerCase();
|
||||||
|
for (let i = 0; i < result.length; i++) {
|
||||||
|
if (result[i].BSDName === BSDName) {
|
||||||
|
result[i].smartStatus = (status === 'passed' ? 'Ok' : (status === 'failed!' ? 'Predicted Failure' : 'unknown'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (let i = 0; i < result.length; i++) {
|
||||||
|
delete result[i].BSDName;
|
||||||
|
}
|
||||||
|
if (callback) {
|
||||||
|
callback(result);
|
||||||
|
}
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < result.length; i++) {
|
||||||
|
delete result[i].BSDName;
|
||||||
|
}
|
||||||
|
if (callback) {
|
||||||
|
callback(result);
|
||||||
|
}
|
||||||
|
resolve(result);
|
||||||
}
|
}
|
||||||
resolve(result);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (_freebsd || _openbsd) {
|
if (_freebsd || _openbsd) {
|
||||||
@ -673,6 +714,7 @@ function diskLayout(callback) {
|
|||||||
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();
|
||||||
|
const BSDName = util.getValue(lines, 'BSD Name', ':', true).trim();
|
||||||
if (sizeStr) {
|
if (sizeStr) {
|
||||||
let sizeValue = 0;
|
let sizeValue = 0;
|
||||||
if (sizeStr.indexOf('(') >= 0) {
|
if (sizeStr.indexOf('(') >= 0) {
|
||||||
@ -696,8 +738,11 @@ function diskLayout(callback) {
|
|||||||
sectorsPerTrack: -1,
|
sectorsPerTrack: -1,
|
||||||
firmwareRevision: util.getValue(lines, 'Revision', ':', true).trim(),
|
firmwareRevision: util.getValue(lines, 'Revision', ':', true).trim(),
|
||||||
serialNum: util.getValue(lines, 'Serial Number', ':', true).trim(),
|
serialNum: util.getValue(lines, 'Serial Number', ':', true).trim(),
|
||||||
interfaceType: util.getValue(lines, 'InterfaceType', ':', true).trim()
|
interfaceType: util.getValue(lines, 'InterfaceType', ':', true).trim(),
|
||||||
|
smartStatus: 'unknown',
|
||||||
|
BSDName: BSDName
|
||||||
});
|
});
|
||||||
|
cmd = cmd + 'printf "\n' + BSDName + '|"; diskutil info /dev/' + BSDName + ' | grep SMART;';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -709,6 +754,7 @@ function diskLayout(callback) {
|
|||||||
let lines = device.split('\n');
|
let lines = device.split('\n');
|
||||||
const linkWidth = util.getValue(lines, 'link width', ':', true).trim();
|
const linkWidth = util.getValue(lines, 'link width', ':', true).trim();
|
||||||
const sizeStr = util.getValue(lines, '!capacity', ':', true).trim();
|
const sizeStr = util.getValue(lines, '!capacity', ':', true).trim();
|
||||||
|
const BSDName = util.getValue(lines, 'BSD Name', ':', true).trim();
|
||||||
if (sizeStr) {
|
if (sizeStr) {
|
||||||
let sizeValue = 0;
|
let sizeValue = 0;
|
||||||
if (sizeStr.indexOf('(') >= 0) {
|
if (sizeStr.indexOf('(') >= 0) {
|
||||||
@ -733,16 +779,55 @@ function diskLayout(callback) {
|
|||||||
firmwareRevision: util.getValue(lines, 'Revision', ':', true).trim(),
|
firmwareRevision: util.getValue(lines, 'Revision', ':', true).trim(),
|
||||||
serialNum: util.getValue(lines, 'Serial Number', ':', true).trim(),
|
serialNum: util.getValue(lines, 'Serial Number', ':', true).trim(),
|
||||||
interfaceType: ('PCIe ' + linkWidth).trim(),
|
interfaceType: ('PCIe ' + linkWidth).trim(),
|
||||||
|
smartStatus: 'unknown',
|
||||||
|
BSDName: BSDName
|
||||||
});
|
});
|
||||||
|
cmd = cmd + 'printf "\n' + BSDName + '|"; diskutil info /dev/' + BSDName + ' | grep SMART;';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (callback) {
|
if (cmd) {
|
||||||
callback(result);
|
cmd = cmd + 'printf "\n"';
|
||||||
|
exec(cmd, function (error, stdout) {
|
||||||
|
let lines = stdout.toString().split('\n');
|
||||||
|
lines.forEach(line => {
|
||||||
|
if (line) {
|
||||||
|
let parts = line.split('|');
|
||||||
|
if (parts.length === 2) {
|
||||||
|
let BSDName = parts[0];
|
||||||
|
parts[1] = parts[1].trim();
|
||||||
|
let parts2 = parts[1].split(':');
|
||||||
|
if (parts2.length === 2) {
|
||||||
|
parts2[1] = parts2[1].trim();
|
||||||
|
let status = parts2[1].toLowerCase();
|
||||||
|
for (let i = 0; i < result.length; i++) {
|
||||||
|
if (result[i].BSDName === BSDName) {
|
||||||
|
result[i].smartStatus = (status === 'not supported' ? 'not supported' : (status === 'verified' ? 'Ok' : (status === 'failing' ? 'Predicted Failure' : 'unknown')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (let i = 0; i < result.length; i++) {
|
||||||
|
delete result[i].BSDName;
|
||||||
|
}
|
||||||
|
if (callback) {
|
||||||
|
callback(result);
|
||||||
|
}
|
||||||
|
resolve(result);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < result.length; i++) {
|
||||||
|
delete result[i].BSDName;
|
||||||
|
}
|
||||||
|
if (callback) {
|
||||||
|
callback(result);
|
||||||
|
}
|
||||||
|
resolve(result);
|
||||||
}
|
}
|
||||||
resolve(result);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (_windows) {
|
if (_windows) {
|
||||||
@ -753,6 +838,7 @@ function diskLayout(callback) {
|
|||||||
devices.forEach(function (device) {
|
devices.forEach(function (device) {
|
||||||
let lines = device.split('\r\n');
|
let lines = device.split('\r\n');
|
||||||
const size = util.getValue(lines, 'Size', '=').trim();
|
const size = util.getValue(lines, 'Size', '=').trim();
|
||||||
|
const status = util.getValue(lines, 'Status', '=').trim();
|
||||||
if (size) {
|
if (size) {
|
||||||
result.push({
|
result.push({
|
||||||
type: device.indexOf('SSD') > -1 ? 'SSD' : 'HD', // not really correct(!) ... maybe this one is better: MSFT_PhysicalDisk - Media Type??
|
type: device.indexOf('SSD') > -1 ? 'SSD' : 'HD', // not really correct(!) ... maybe this one is better: MSFT_PhysicalDisk - Media Type??
|
||||||
@ -768,7 +854,8 @@ function diskLayout(callback) {
|
|||||||
sectorsPerTrack: parseInt(util.getValue(lines, 'SectorsPerTrack', '=')),
|
sectorsPerTrack: parseInt(util.getValue(lines, 'SectorsPerTrack', '=')),
|
||||||
firmwareRevision: util.getValue(lines, 'FirmwareRevision', '=').trim(),
|
firmwareRevision: util.getValue(lines, 'FirmwareRevision', '=').trim(),
|
||||||
serialNum: util.getValue(lines, 'SerialNumber', '=').trim(),
|
serialNum: util.getValue(lines, 'SerialNumber', '=').trim(),
|
||||||
interfaceType: util.getValue(lines, 'InterfaceType', '=').trim()
|
interfaceType: util.getValue(lines, 'InterfaceType', '=').trim(),
|
||||||
|
smartStatus: (status === 'Ok' ? 'Ok' : (status === 'Degraded' ? 'Degraded' : (status === 'Pred Fail' ? 'Predicted Failure' : 'Unknown')))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -40,7 +40,9 @@
|
|||||||
"graphics",
|
"graphics",
|
||||||
"graphic card",
|
"graphic card",
|
||||||
"graphic controller",
|
"graphic controller",
|
||||||
"display"
|
"display",
|
||||||
|
"smart",
|
||||||
|
"disk layout"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -57,4 +59,4 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.0.0"
|
"node": ">=4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user