Linux
banshee/linux-collection/linux/snmp/
diskio
Disk input/output of a Linux host by SNMP: IOPS, throughput and busy time per disk.
par banshee1 installation2 versions
v2Dernière
Publiée le 28 octobre 2026. One naming convention across collections; documentation completed.
// The input/output of each disk of a Linux host, by SNMP, from diskIOTable (UCD-DISKIO-MIB, served by
// net-snmp): operations per second and throughput, for reads and writes, and the share of time the disk
// is busy when the agent serves it (diskIOBusyTime, missing from old agents). Everything comes from
// counters, over the interval between two runs: nothing on the first run.
// A partition is left out by the code: a device whose name is another's followed by digits (sda1, vdb2)
// or by "p" and digits (nvme0n1p1, mmcblk0p2), since its input/output is already counted on its disk.
// Loop, in-memory and optical devices are left out by the default selection. The operation counts are
// 32-bit counters, which wrap: that run returns nothing for that disk.
need('protocol:snmp');
per('disk', 'Disks', array('ignore' => array('loop*', 'ram*', 'zram*', 'sr*', 'fd*')));
output('read-iops', 'number', array('label' => 'Reads', 'unit' => 'op/s', 'per' => 'disk'));
output('write-iops', 'number', array('label' => 'Writes', 'unit' => 'op/s', 'per' => 'disk'));
output('iops', 'number', array('label' => 'Operations', 'unit' => 'op/s', 'per' => 'disk'));
output('read-rate', 'number', array('label' => 'Read throughput', 'unit' => 'MiB/s', 'per' => 'disk'));
output('write-rate', 'number', array('label' => 'Write throughput', 'unit' => 'MiB/s', 'per' => 'disk'));
output('busy', 'number', array('label' => 'Busy time', 'unit' => '%', 'per' => 'disk'));
// Not checked: an SSD or an array busy 100 % of the time still serves more.
watch.above('busy', 'Disk saturated', 'busy', array('warning' => 90, 'for' => '10 min', 'enabled' => false));
// No default threshold: what is normal depends on the disk and its use.
watch.above('iops-high', 'Too many operations', 'iops', array('enabled' => false));
// diskIOTable, by diskIOIndex: diskIODevice ("sda"), diskIOReads and diskIOWrites (operation counts,
// 32 bits), diskIONReadX and diskIONWrittenX (bytes, 64 bits), diskIOBusyTime (microseconds busy).
$disks = snmp.table(array(
'name' => '1.3.6.1.4.1.2021.13.15.1.1.2',
'reads' => '1.3.6.1.4.1.2021.13.15.1.1.5',
'writes' => '1.3.6.1.4.1.2021.13.15.1.1.6',
'read' => '1.3.6.1.4.1.2021.13.15.1.1.12',
'written' => '1.3.6.1.4.1.2021.13.15.1.1.13',
'busy' => '1.3.6.1.4.1.2021.13.15.1.1.14',
));
if (list.count($disks) == 0) {
fail('misconfigured', 'The agent does not serve the disk table (diskIOTable, UCD-DISKIO-MIB)');
}
$names = array();
foreach ($disks as $row) {
if (list.has($row, 'name')) {
$names[$row['name']] = true;
}
}
// A name served twice is counted once: a counter is read only once per run.
$done = array();
foreach ($disks as $row) {
if (!list.has($row, 'name') || !list.has($row, 'reads') || !list.has($row, 'writes')
|| !list.has($row, 'read') || !list.has($row, 'written')) {
continue;
}
$name = $row['name'];
if (list.has($done, $name)) {
continue;
}
$done[$name] = true;
// The shortest prefix followed by digits, or by "p" and digits: sda for sda1, nvme0n1 for nvme0n1p1.
// A partition is a name whose prefix is itself a disk of the table.
$parent = text.match($name, '^(.+?)p?[0-9]+$');
if (list.count($parent) > 0 && list.has($names, $parent[1])) {
continue;
}
// Every counter is read on every run, so that the next run has its rate.
$reads = counter.rate('reads', $row['reads'], $name);
$writes = counter.rate('writes', $row['writes'], $name);
$read = counter.rate('read', $row['read'], $name);
$written = counter.rate('written', $row['written'], $name);
if (list.has($row, 'busy')) {
// Microseconds busy per second: one percent is 10,000 of them.
$busy = counter.rate('busy', $row['busy'], $name);
if ($busy != '') {
value('busy', number.round($busy / 10000, 1), $name);
}
}
if ($reads == '' || $writes == '' || $read == '' || $written == '') {
continue;
}
value('read-iops', number.round($reads, 1), $name);
value('write-iops', number.round($writes, 1), $name);
value('iops', number.round($reads + $writes, 1), $name);
value('read-rate', number.round($read / 1048576, 2), $name);
value('write-rate', number.round($written / 1048576, 2), $name);
}