#!/bin/sh # # Wildcard-plugin to monitor disks. To monitor a disk, # link io__ to this file. E.g. # # ln -s /usr/share/munin/plugins-auto/io_.kstat /etc/munin/node.d/io_busy_sd0 # # ...will monitor busy and wait on sd0. # # These functions are implemented: # busy bytes ops # # Any device found in /usr/bin/kstat can be monitored. # # Configuration variables # # io_*_ignore - Perl expression to select devices to ignore # # E.g. io_dad_ignore = $F[1] == 0 ignores dad0. # All fields from the kstat line are in @F. Fields are separated # by ':' or "\t". $F[0] is the module name, e.g. 'dad'. # $F[1] is the instance number. $F[2] is the device name , e.g. # 'dad0'. # # Magic markers (optional - used by munin-config and some installation # scripts): # #%# family=auto #%# capabilities=autoconf suggest FUNCTION=`basename $0 | sed -e 's/io_//' -e 's/_.*//'` MODULE=`basename $0 | sed 's/^.*_//g'` CLASS=disk PERL=${PERL:-/usr/bin/perl} if [ -z "$FUNCTION" ]; then exit elif [ "$FUNCTION" = "busy" ]; then TITLE="Busy & Wait" IN=rtime INNAME=busy OUT=wtime OUTNAME="wait" CDEF=",100,*" GARGS="--lower-limit 0 --upper-limit 100" VLABEL='%' elif [ "$FUNCTION" = "bytes" ]; then TITLE="I/O" IN=nread INNAME=$IN OUT=nwritten OUTNAME=$OUT VLABEL='Bytes per second' elif [ "$FUNCTION" = "ops" ]; then TITLE="Operations" IN=reads INNAME=$IN OUT=writes OUTNAME=$OUT VLABEL='Operations per second' fi if [ "$1" = "autoconf" ]; then if [ -x /usr/bin/kstat ]; then echo yes exit 0 else echo "no (/usr/bin/kstat not found)" exit 0 fi fi if [ "$1" = "suggest" ]; then if [ -x /usr/bin/kstat ]; then kstat -p -c '/disk|nfs|tape/' -s "/^$IN\$/" | sed -e 's/:.*//' -e 's/ssd|vdc|zvblk/sd/' -e '/^fd$/d' | sort -u exit 0 else exit 1 fi fi REGEX="$MODULE" if [ "$MODULE" = "sd" ]; then REGEX="/^(s?sd|vdc|zvblk)$/" NAME="Disk Device" elif [ "$MODULE" = "dad" ]; then NAME="IDE Disk Device" elif [ "$MODULE" = "md" ]; then NAME="Disksuite" elif [ "$MODULE" = "nfs" ]; then NAME="NFS" CLASS=nfs elif [ "$MODULE" = "st" ]; then NAME="Tape" CLASS=tape else NAME="Unknown" fi if $PERL -MSolaris::MapDev -e '' >/dev/null 2>&1; then HAS_MAPDEV=1 fi eval IGNORE="\$io_${MODULE}_ignore" if [ -n "$IGNORE" ]; then IGNORE="next if $IGNORE;" fi if [ "$1" = "config" ]; then echo "graph_title $NAME $TITLE" echo "graph_args --base 1024 $GARGS" echo 'graph_category disk' echo "graph_vlabel $VLABEL" export IN INNAME OUT OUTNAME CDEF if [ "$HAS_MAPDEV" ]; then kstat -p -c $CLASS -m $REGEX -s "/^$IN\$/" | \ $PERL -MSolaris::MapDev=inst_to_dev -n -a -F':|\t' \ -e $IGNORE' $dev = $F[2]; $name = inst_to_dev($dev); $name =~ s/:/_/g; $name = length $name ? $name : $dev; print "${dev}_$ENV{IN}.label ${name}_$ENV{INNAME}\n"; print "${dev}_$ENV{IN}.type DERIVE\n"; print "${dev}_$ENV{IN}.min 0\n"; print "${dev}_$ENV{IN}.max 1000000000\n"; print "${dev}_$ENV{IN}.cdef ${dev}_$ENV{IN}$ENV{CDEF}\n" if exists $ENV{CDEF}; print "${dev}_$ENV{OUT}.label ${name}_$ENV{OUTNAME}\n"; print "${dev}_$ENV{OUT}.type DERIVE\n"; print "${dev}_$ENV{OUT}.min 0\n"; print "${dev}_$ENV{OUT}.max 1000000000\n"; print "${dev}_$ENV{OUT}.cdef ${dev}_$ENV{OUT}$ENV{CDEF}\n" if exists $ENV{CDEF};' exit 0 else for dev in `kstat -p -c $CLASS -m $REGEX -s "/^$IN\$/" | $PERL -n -a -F':|\t' -e "$IGNORE"'print $F[2], "\n";'`; do echo "${dev}_$IN.label ${dev}_$INNAME" echo "${dev}_$IN.type DERIVE" echo "${dev}_$IN.min 0" echo "${dev}_$IN.max 1000000000" if [ -n "$CDEF" ]; then echo "${dev}_$IN.cdef ${dev}_$IN$CDEF" fi echo "${dev}_$OUT.label ${dev}_$OUTNAME" echo "${dev}_$OUT.type DERIVE" echo "${dev}_$OUT.min 0" echo "${dev}_$OUT.max 1000000000" if [ -n "$CDEF" ]; then echo "${dev}_$OUT.cdef ${dev}_$OUT$CDEF" fi done exit 0 fi fi kstat -p -c $CLASS -m $REGEX -s "/^($IN|$OUT)\$/" | $PERL -n -a -F':|\t' -e "$IGNORE"' chomp $F[4]; print $F[2]."_".$F[3].".value ", int($F[4]), "\n"; '