#!/bin/sh
###############################################
#
# Nagios script to check I/O statistics
#
# NOTE: Requires kernel 2.4 or higher 
# 
# See usage for command line switches
# 
# Created: 2007-06-27 (i.yates@uea.ac.uk)
# Updated: 2007-07-27 (i.yates@uea.ac.uk)
#
###############################################

. /usr/local/nagios/libexec/utils.sh


VERSION="1.0"

IOSTAT=/usr/bin/iostat
GREP=/bin/grep
AWK=/bin/awk

FLAG_VERBOSE=FALSE
FLAG_TPS=FALSE
FLAG_READS=FALSE
FLAG_WRITES=FALSE
LEVEL_WARN=""
LEVEL_CRIT=""
RESULT=""
EXIT_STATUS=$STATE_OK


###############################################
#
## FUNCTIONS 
#

## Print usage
usage() {
	echo " check_iostat $VERSION - Nagios I/O statistics check script"
	echo ""
	echo " Usage: check_iostat -w <warning value> -c <critical value> [ -i|r|w <device> ] [ -v ] [ -h ]"
	echo ""
	echo "		-w  Warning trigger level"
	echo "		-c  Critical trigger level"
	echo "		-t  I/O transactions per second (TPS/IOPS) on <device>"
	echo "		-i  Kilobytes read IN per second on <device>"
	echo "		-o  Kilobytes written OUT per second on <device>"
	echo "		-v  Verbose output (ignored for now)"
	echo "		-h  Show this page"
	echo ""
}
 
## Process command line options
doopts() {
	if ( `test 0 -lt $#` )
	then
		while getopts w:c:t:i:o:vh myarg "$@"
		do
			case $myarg in
				h|\?)
					usage
					exit;;
				w)
					LEVEL_WARN=$OPTARG;;
				c)
					LEVEL_CRIT=$OPTARG;;
				t)
					FLAG_TPS=TRUE
					DEVICE=$OPTARG;;
				i)
					FLAG_READS=TRUE
					DEVICE=$OPTARG;;
				o)
					FLAG_WRITES=TRUE
					DEVICE=$OPTARG;;
				v)
					FLAG_VERBOSE=TRUE;;
				*)	# Default
					usage
					exit;;
			esac
		done
	else
		usage
		exit
	fi
}


# Write output and return result
theend() {
	echo $RESULT
	exit $EXIT_STATUS
}


#
## END FUNCTIONS 
#

#############################################
#
## MAIN 
#


# Handle command line options
doopts $@

# Do the do
OUTPUT=`$IOSTAT -k -d $DEVICE | $GREP $DEVICE`
if test -z "$OUTPUT" ; then
	RESULT="IOSTAT UNKNOWN - query returned no output!"
	EXIT_STATUS=$STATE_UNKNOWN
else
	## General sanity check
	if test -n "$LEVEL_WARN" -a -n "$LEVEL_CRIT" -a "$LEVEL_WARN" -lt "$LEVEL_CRIT" ; then
		## Handle Transactions per second
		if test $FLAG_TPS = "TRUE" ; then
			TPS=`echo $OUTPUT | $AWK '{print $2}'`
			TPS_ABS=`echo $TPS | $AWK '{printf "%d",$1}'`
			if test "$TPS_ABS" -lt "$LEVEL_WARN" ; then
				RESULT="IOSTAT OK - $TPS Transactions per second on $DEVICE"
				EXIT_STATUS=$STATE_OK
			else
				if test "$TPS_ABS" -gt "$LEVEL_CRIT" ; then 
					RESULT="IOSTAT CRITICAL - $TPS Transactions per second on $DEVICE"
					EXIT_STATUS=$STATE_CRITICAL
				else
					if test "$TPS_ABS" -gt "$LEVEL_WARN" ; then 
						RESULT="IOSTAT WARNING - $TPS Transactions per second on $DEVICE"
						EXIT_STATUS=$STATE_WARNING
					fi
				fi
			fi
		fi

		## Handle Reads per second
		if test $FLAG_READS = "TRUE" ; then
			READSS=`echo $OUTPUT | $AWK '{print $3}'`
			READSS_ABS=`echo $READSS | $AWK '{printf "%d",$1}'`
			if test "$READSS_ABS" -lt "$LEVEL_WARN" ; then
				RESULT="IOSTAT OK - $READSS Kilobytes/s reading on $DEVICE"
				EXIT_STATUS=$STATE_OK
			else
				if test "$READSS_ABS" -gt "$LEVEL_CRIT" ; then 
					RESULT="IOSTAT CRITICAL - $READSS Kilobytes/s reading on $DEVICE"
					EXIT_STATUS=$STATE_CRITICAL
				else
					if test "$READSS_ABS" -gt "$LEVEL_WARN" ; then 
						RESULT="IOSTAT WARNING - $READSS Kilobytes/s reading on $DEVICE"
						EXIT_STATUS=$STATE_WARNING
					fi
				fi
			fi
		fi

		## Handle Writes per second
		if test $FLAG_WRITES = "TRUE" ; then
			WRITESS=`echo $OUTPUT | $AWK '{print $4}'`
			WRITESS_ABS=`echo $WRITESS | $AWK '{printf "%d",$1}'`
			if test "$WRITESS_ABS" -lt "$LEVEL_WARN" ; then
				RESULT="IOSTAT OK - $WRITESS Kilobytes/s writing on $DEVICE"
				EXIT_STATUS=$STATE_OK
			else
				if test "$WRITESS_ABS" -gt "$LEVEL_CRIT" ; then 
					RESULT="IOSTAT CRITICAL - $WRITESS Kilobytes/s writing on $DEVICE"
					EXIT_STATUS=$STATE_CRITICAL
				else
					if test "$WRITESS_ABS" -gt "$LEVEL_WARN" ; then 
						RESULT="IOSTAT WARNING - $WRITESS Kilobytes/s writing on $DEVICE"
						EXIT_STATUS=$STATE_WARNING
					fi
				fi
			fi
		fi
	else
		echo "ERROR: Invalid warning/critical values"
		usage
		exit
	fi
fi

# Quit and return information and exit status
theend
