Storage
banshee/storage-collection/storage/synology/snmp/
disks
The status, health, temperature, bad sectors and remaining life of each disk of a Synology NAS by SNMP.
by banshee1 installation1 version
Published on October 27, 2026. First version.
// The disks of a Synology NAS, by SNMP (SYNOLOGY-DISK-MIB): the state and the temperature of each, and, from
// DSM 7.0, its bad sectors and remaining life, from DSM 7.1 its health. A column the agent does not serve
// (an older DSM) is left out of its row: what it would say is not returned, the rest is.
need('protocol:snmp');
per('disk', 'Disks');
output('status', 'text', array('label' => 'Status', 'per' => 'disk'));
output('health', 'text', array('label' => 'Health', 'per' => 'disk'));
output('temperature', 'number', array('label' => 'Temperature', 'unit' => '°C', 'per' => 'disk'));
output('bad-sectors', 'number', array('label' => 'Bad sectors', 'per' => 'disk'));
output('remaining-life', 'number', array('label' => 'Remaining life', 'unit' => '%', 'per' => 'disk'));
watch.state('failed', 'Disk failed', 'status', array('critical' => array('crashed', 'system-partition-failed', 'disconnected')));
watch.state('unhealthy', 'Disk health degraded', 'health', array('warning' => array('warning'), 'critical' => array('critical', 'failing')));
watch.above('hot', 'High temperature', 'temperature', array('warning' => 55, 'critical' => 60, 'for' => '3 runs'));
watch.above('bad-sectors', 'Bad sectors', 'bad-sectors', array('warning' => 0));
watch.below('worn', 'Disk worn out', 'remaining-life', array('warning' => 10, 'critical' => 3));
watch.missing('missing', 'Disk missing', 'status', array('enabled' => false));
// SYNOLOGY-DISK-MIB, diskTable (1.3.6.1.4.1.6574.2.1), by diskIndex: diskID (deprecated, the name before
// DSM 7.0), diskStatus, diskTemperature, diskBadSector, diskRemainLife, diskName and diskHealthStatus.
$disks = snmp.table(array(
'id' => '1.3.6.1.4.1.6574.2.1.1.2',
'status' => '1.3.6.1.4.1.6574.2.1.1.5',
'temperature' => '1.3.6.1.4.1.6574.2.1.1.6',
'bad-sectors' => '1.3.6.1.4.1.6574.2.1.1.9',
'life' => '1.3.6.1.4.1.6574.2.1.1.11',
'name' => '1.3.6.1.4.1.6574.2.1.1.12',
'health' => '1.3.6.1.4.1.6574.2.1.1.13',
));
$statuses = array(1 => 'normal', 2 => 'initialized', 3 => 'not-initialized', 4 => 'system-partition-failed',
5 => 'crashed', 6 => 'disconnected');
$healths = array(1 => 'normal', 2 => 'warning', 3 => 'critical', 4 => 'failing');
$read = 0;
foreach ($disks as $row) {
// The name in the OS ("sata1") from DSM 7.0; before, the deprecated diskID ("Disk 1").
$name = list.get($row, 'name', list.get($row, 'id', ''));
if ($name == '' || !list.has($row, 'status')) {
continue;
}
$read = $read + 1;
value('status', list.get($statuses, $row['status'], 'unknown'), $name);
if (list.has($row, 'health')) {
value('health', list.get($healths, $row['health'], 'unknown'), $name);
}
if (list.has($row, 'temperature')) {
value('temperature', $row['temperature'], $name);
}
if (list.has($row, 'bad-sectors')) {
value('bad-sectors', $row['bad-sectors'], $name);
}
// A disk that does not estimate its life (most hard disks) answers a negative number.
if (list.has($row, 'life') && $row['life'] >= 0) {
value('remaining-life', $row['life'], $name);
}
}
if ($read == 0) {
fail('misconfigured', 'The agent serves no disk (diskTable, SYNOLOGY-DISK-MIB)',
'Not a Synology, or a view that does not include 1.3.6.1.4.1.6574.');
}