#!/bin/sh
# 
# Plugin to check system memory
# by hugme (nagios@hugme.org)
# Nagios script to check memory usage on linux server
# version 1.1.1
# 
##########################################################

MEMINFO="/proc/meminfo"

##########################################################
# We call them functions because they're fun
##########################################################

print_help() {
cat << EOF
Linux Memory Plugin for Nagios
Copyright (c) hugme (nagios@hugme.org)
Version: 1.1.1
Last Modified: 10-18-2010
License: This software can be used for free unless I meet you, then you owe me lunch.

Usage: check_linux_memory -w [warning %] -c [critical %]

Options:
 -w [0-99]		= Your warning %. 20 means 20% of your memory can remain before a warning alarm. Do not use the % sign.
 -c [0-99]		= Your critical %. 10 means 10% of your memory can remain before a critical alarm. Do not use the % sign.
 -d [K,M,G,T]	= divider K=kilobytes, M=megabytes, G=gigabytes, T=terabytes
 -f		= Include cached memory as free memory when calculating your percentage free

EOF
	}

invalid_type() {
	echo "\nInvalid $1\n"
	print_help
	exit 3
	}

##############################################
## Suck in the user input
##############################################


while test -n "$1"; do
	case $1 in
		--help) print_help ; exit 0 ;;
		-h) print_help ; exit 0 ;;
		-w) WARN=$2; shift ;;
		-c) CRIT=$2; shift ;;
		-d) DIV=$2; shift ;;
		-f) FC=1 ;;
	esac
	shift
done

##############################################
## Set the defaults if needed
##############################################

[ -z "$WARN" ] && WARN=20
[ -z "$CRIT" ] && CRIT=10
[ -z "$DIV" ] && DIV=M
[ -z "$FC" ] && FC=0

##############################################
## Check user input
##############################################

echo $WARN | grep -v [0-9.] > /dev/null && invalid_type warning
echo $CRIT | grep -v [0-9.] > /dev/null && invalid_type critical
[ "${WARN%.*}" -ge 100 ] && invalid_type warning
[ "${CRIT%.*}" -ge 100 ] && invalid_type critical
[ "${CRIT%.*}" -gt "${WARN%.*}" ] && invalid_type critical

case $DIV in
	k|K) DIVNUM=1;;
	m|M) DIVNUM=1024;;
	g|G) DIVNUM=1048576;;
	t|T) DIVNUM=1073741824;;
	*) invalid_type;; 
esac

[ ! -f "$MEMINFO" ] && {
	echo "Your Memory info file seems to be missing"
	exit 1
	}

##############################################
## Do the work
## Pull the memory file into awk
## grab the lines we need
## Print the information
##############################################

RESULT=$(awk -v warn=$WARN -v crit=$CRIT -v div=$DIV -v divnum=$DIVNUM -v fc=$FC '/^MemTotal:/ { total=$2 }
/^MemTotal:/ { tot=$2 }
/^MemFree:/ { free=$2 }
/^Buffers:/ { buff=$2 }
/^Cached:/ { cache=$2 }
/^Active:/ { active=$2 }
/^Inactive:/ { inactive=$2 }
END { if ( fc == 1 ) { free=free+cache }
	{ freeperct=free/tot*100 }
	if ( freeperct > warn ) { result="OK" ; xit="0"}
	if ( freeperct <= warn ) {
		if ( freeperct > crit ) { result="WARNING" ; xit="1" }
		else if ( freeperct <= crit ) { result="CRITICAL" ; xit="2" }
		}
	{print xit" MEMORY "result" - "freeperct"% Free - Total:"tot/divnum div" Active:"active/divnum div" Inactive:"inactive/divnum div" Buffers:"buff/divnum div" Cached:"cache/divnum div" |Free="freeperct";"warn";"crit";0 Active="active";0;0;0 Inactive="inactive";0;0;0 Buffers="buff";0;0;0 Cached="cache";0;0;0" }
	}' /proc/meminfo)

echo ${RESULT#* }
exit ${RESULT%% *}
