#!/bin/sh # -*- sh -*- set -eu : <<=cut =head1 NAME zpool_iostat - Plugin to monitor transfer statistics of ZFS pools =head1 APPLICABLE SYSTEMS All systems with "zpool" installed. =head1 CONFIGURATION No configuration is required. =head1 INTERPRETATION This plugin shows a graph with read (positive) and write (negative) values for the IO transfer of each pool. =head1 MAGIC MARKERS #%# family=auto #%# capabilities=autoconf =head1 AUTHOR tsaavik Peter Doherty Lars Kruse =head1 LICENSE GPLv2 =cut # shellcheck source=/usr/share/munin/plugins/plugin.sh . "$MUNIN_LIBDIR/plugins/plugin.sh" ZPOOL_BIN=/sbin/zpool ACTION="${1:-}" if [ "$ACTION" = "autoconf" ]; then if [ -x "$ZPOOL_BIN" ]; then echo yes else echo "no (missing executable '$ZPOOL_BIN')" fi exit 0 fi zlines=$("$ZPOOL_BIN" iostat -v | wc -l | sed 's/ //g') iostats=$("$ZPOOL_BIN" iostat -v 1 1 | tail "-$zlines") zlist=$(echo "$iostats" \ | awk '/alloc/ {next}; /avail/ {next}; /raid/ {next}; /mirror/ {next}; { if ( $4 >=0 ) print $1}' \ | tr ' ' '\n') # Parse the n'th column of the iostat output for a given pool or disk as a # number (interpreting K and M suffixes). get_device_iostat_column() { local device_label="$1" local stat_column="$2" # convert all numeric values into kB echo "$iostats" \ | awk '{ if ($1 == "'"$device_label"'") print $'"$stat_column"'; }' \ | awk '/M/ {print int($1)*1000}; /K/ {print int($1)}; /[0-9]$/ {print int($1)/1000}' } get_device_fieldname() { local device_id="$1" # Backwards compatibility (until 2016): keep the unprefixed pool name # for the fieldname, except for pool names starting with digits. if echo "$device_id" | grep -q "^[0-9]"; then clean_fieldname "_$device_id" else clean_fieldname "$device_id" fi } if [ "$ACTION" = "config" ]; then echo 'graph_title zpool iostat' echo 'graph_args --base 1000 -l 0' echo 'graph_vlabel write (-) / read (+) KBytes/s' echo 'graph_category disk' echo 'graph_scale no' echo 'graph_info This graph shows zpool iostat' # Assemble the "graph_order" as a sorted list of read/write pairs for # each device. printf "graph_order" echo "$zlist" | while read -r device_id; do fieldname="$(get_device_fieldname "$device_id")" printf " %s_read %s_write" "$fieldname" "$fieldname" done # finalize the 'graph_order' with a newline echo # output all fields: write as negative numbers and read as positive echo "$zlist" | while read -r device_id; do fieldname="$(get_device_fieldname "$device_id")" echo "${fieldname}_read.label $device_id" echo "${fieldname}_read.type GAUGE" echo "${fieldname}_read.graph no" echo "${fieldname}_write.label $device_id" echo "${fieldname}_write.type GAUGE" echo "${fieldname}_write.negative ${fieldname}_read" done exit 0 fi echo "$zlist" | while read -r device_id; do fieldname="$(get_device_fieldname "$device_id")" echo "${fieldname}_read.value $(get_device_iostat_column "$device_id" 6)" echo "${fieldname}_write.value $(get_device_iostat_column "$device_id" 7)" done