393 lines
12 KiB
Bash
393 lines
12 KiB
Bash
#! /bin/bash
|
|
#
|
|
# Script to check Internet connection speed using speedtest-cli
|
|
#
|
|
# Jon Witts - 20150228
|
|
#
|
|
#########################################################################################################################################################
|
|
#
|
|
# Nagios Exit Codes
|
|
#
|
|
# 0 = OK = The plugin was able to check the service and it appeared to be functioning properly
|
|
# 1 = Warning = The plugin was able to check the service, but it appeared to be above some warning
|
|
# threshold or did not appear to be working properly
|
|
# 2 = Critical = The plugin detected that either the service was not running or it was above some critical threshold
|
|
# 3 = Unknown = Invalid command line arguments were supplied to the plugin or low-level failures internal
|
|
# to the plugin (such as unable to fork, or open a tcp socket) that prevent it from performing the specified operation.
|
|
# Higher-level errors (such as name resolution errors, socket timeouts, etc) are outside of the control of plugins
|
|
# and should generally NOT be reported as UNKNOWN states.
|
|
#
|
|
########################################################################################################################################################
|
|
|
|
plugin_name="Nagios speedtest-cli plugin"
|
|
version="1.2 2015022818.19"
|
|
|
|
#####################################################################
|
|
#
|
|
# CHANGELOG
|
|
#
|
|
# Version 1.0 - Initial Release
|
|
#
|
|
# Version 1.1 - Added requirement to use server id in test and need to define
|
|
# full path to speedtest binary - thanks to Sigurdur Bjarnason
|
|
# for changes and improvements
|
|
#
|
|
# Version 1.2 - Added ability to check speed from an internal Speedtest Mini
|
|
# server. Idea sugested by Erik Brouwer
|
|
#
|
|
#
|
|
#
|
|
|
|
#####################################################################
|
|
# function to output script usage
|
|
usage()
|
|
{
|
|
cat << EOF
|
|
******************************************************************************************
|
|
|
|
$plugin_name - Version: $version
|
|
|
|
OPTIONS:
|
|
-h Show this message
|
|
-w Download Warning Level - *Required* - integer or floating point
|
|
-c Download Critical Level - *Required* - integer or floating point
|
|
-W Upload Warning Level - *Required* - integer or floating point
|
|
-C Upload Critical Level - *Required* - integer or floating point
|
|
-l Location of speedtest server - *Required * - takes either "i" or "e". If you pass "i" for
|
|
Internal then you will need to pass the URL of the Mini Server to the "s" option. If you pass
|
|
"e" for External then you must pass the server integer to the "s" option.
|
|
-s Server integer or URL for the speedtest server to test against - *Required* - Run
|
|
"speedtest --list | less" to find your nearest server and note the number of the server
|
|
or use the URL of an internal Speedtest Mini Server
|
|
-p Output Performance Data
|
|
-v Output plugin version
|
|
-V Output debug info for testing
|
|
|
|
This script will output the Internet Connection Speed using speedtest-cli to Nagios.
|
|
|
|
You need to have installed speedtest-cli on your system first and ensured that it is
|
|
working by calling "speedtest --simple".
|
|
|
|
See here: https://github.com/sivel/speedtest-cli for info about speedtest-cli
|
|
|
|
First you MUST define the location of your speedtest install in the script or this will
|
|
not work.
|
|
|
|
The speedtest-cli can take some time to return its result. I recommend that you set the
|
|
service_check_timeout value in your main nagios.cfg to 120 to allow time for
|
|
this script to run; but test yourself and adjust accordingly.
|
|
|
|
You also need to have access to bc on your system for this script to work and that it
|
|
exists in your path.
|
|
|
|
Your warning levels must be higher than your critical levels for both upload and download.
|
|
|
|
Performance Data will output upload and download speed against matching warning and
|
|
critical levels.
|
|
|
|
Jon Witts
|
|
|
|
******************************************************************************************
|
|
EOF
|
|
}
|
|
|
|
#####################################################################
|
|
# function to output error if speedtest binary location not set
|
|
locundef()
|
|
{
|
|
cat << EOF
|
|
******************************************************************************************
|
|
|
|
$plugin_name - Version: $version
|
|
|
|
You have not defined the location of the speedtest binary in the script! You MUST do
|
|
this before running the script. See line 170 of the script!
|
|
|
|
******************************************************************************************
|
|
EOF
|
|
}
|
|
|
|
#####################################################################
|
|
# function to check if a variable is numeric
|
|
# expects variable to check as first argument
|
|
# and human description of variable as second
|
|
isnumeric()
|
|
{
|
|
re='^[0-9]+([.][0-9]+)?$'
|
|
if ! [[ $1 =~ $re ]]; then
|
|
echo $2" with a value of: "$1" is not a number!"
|
|
usage
|
|
exit 3
|
|
fi
|
|
}
|
|
|
|
#####################################################################
|
|
# functions for floating point operations - require bc!
|
|
|
|
#####################################################################
|
|
# Default scale used by float functions.
|
|
|
|
float_scale=3
|
|
|
|
#####################################################################
|
|
# Evaluate a floating point number expression.
|
|
|
|
function float_eval()
|
|
{
|
|
local stat=0
|
|
local result=0.0
|
|
if [[ $# -gt 0 ]]; then
|
|
result=$(echo "scale=$float_scale; $*" | bc -q 2>/dev/null)
|
|
stat=$?
|
|
if [[ $stat -eq 0 && -z "$result" ]]; then stat=1; fi
|
|
fi
|
|
echo $result
|
|
return $stat
|
|
}
|
|
|
|
#####################################################################
|
|
# Evaluate a floating point number conditional expression.
|
|
|
|
function float_cond()
|
|
{
|
|
local cond=0
|
|
if [[ $# -gt 0 ]]; then
|
|
cond=$(echo "$*" | bc -q 2>/dev/null)
|
|
if [[ -z "$cond" ]]; then cond=0; fi
|
|
if [[ "$cond" != 0 && "$cond" != 1 ]]; then cond=0; fi
|
|
fi
|
|
local stat=$((cond == 0))
|
|
return $stat
|
|
}
|
|
|
|
########### End of functions ########################################
|
|
|
|
# Set up the variable for the location of the speedtest binary.
|
|
# Edit the line below so that the variable is defined as the location
|
|
# to speedtest on your system. On mine it is /usr/local/bin
|
|
# Ensure to leave the last slash off!
|
|
# You MUST define this or the script will not run!
|
|
STb=/usr/bin
|
|
|
|
# Set up the variables to take the arguments
|
|
DLw=150.00
|
|
DLc=100.00
|
|
ULw=150.00
|
|
ULc=100.00
|
|
Loc=e
|
|
# Server ID, if 0 using nearest server
|
|
SEs=0
|
|
#PerfData=TRUE
|
|
PerfData=
|
|
debug=
|
|
|
|
# Retrieve the arguments using getopts
|
|
while getopts "hw:c:W:C:l:s:pvV" OPTION
|
|
do
|
|
case $OPTION in
|
|
h)
|
|
usage
|
|
exit 3
|
|
;;
|
|
w)
|
|
DLw=$OPTARG
|
|
;;
|
|
c)
|
|
DLc=$OPTARG
|
|
;;
|
|
W)
|
|
ULw=$OPTARG
|
|
;;
|
|
C)
|
|
ULc=$OPTARG
|
|
;;
|
|
l)
|
|
Loc=$OPTARG
|
|
;;
|
|
s)
|
|
SEs=$OPTARG
|
|
;;
|
|
p)
|
|
PerfData="TRUE"
|
|
;;
|
|
v)
|
|
echo "$plugin_name. Version number: $version"
|
|
exit 3
|
|
;;
|
|
V)
|
|
debug="TRUE"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
|
|
# Check if the Speedtest binary variable $STb has been defined and exit with warning if not
|
|
if [[ -z $STb ]]
|
|
then
|
|
locundef
|
|
exit 3
|
|
fi
|
|
|
|
# Check for empty arguments and exit to usage if found
|
|
if [[ -z $DLw ]] || [[ -z $DLc ]] || [[ -z $ULw ]] || [[ -z $ULc ]] || [[ -z $Loc ]] || [[ -z $SEs ]]
|
|
then
|
|
usage
|
|
exit 3
|
|
fi
|
|
|
|
# Check for invalid argument passed to $Loc and exit to usage if found
|
|
if [[ "$Loc" != "e" ]] && [[ "$Loc" != "i" ]]
|
|
then
|
|
usage
|
|
exit 3
|
|
fi
|
|
|
|
# Check for non-numeric arguments
|
|
isnumeric $DLw "Download Warning Level"
|
|
isnumeric $DLc "Download Critical Level"
|
|
isnumeric $ULw "Upload Warning Level"
|
|
isnumeric $ULc "Upload Critical Level"
|
|
#isnumeric $Serv "Server Number ID"
|
|
|
|
# Check that warning levels are not less than critical levels
|
|
if float_cond "$DLw < $DLc"; then
|
|
echo "\$DLw is less than \$DLc!"
|
|
usage
|
|
exit 3
|
|
elif float_cond "$ULw < $ULc"; then
|
|
echo "\$ULw is less than \$ULc!"
|
|
usage
|
|
exit 3
|
|
fi
|
|
|
|
# Output arguments for debug
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "Download Warning Level = "$DLw
|
|
echo "Download Critical Level = "$DLc
|
|
echo "Upload Warning Level = "$ULw
|
|
echo "Upload Critical Level = "$ULc
|
|
echo "Server Location = "$Loc
|
|
echo "Server URL or Integer = "$SEs
|
|
fi
|
|
|
|
#Set command up depending upon internal or external
|
|
if [ "$Loc" == "e" ]; then
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "External Server defined"
|
|
fi
|
|
if [ "$SEs" == "0" ]; then
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "no SEs specified"
|
|
fi
|
|
command=$($STb/speedtest --simple)
|
|
else
|
|
command=$($STb/speedtest --server=$SEs --simple)
|
|
fi
|
|
elif [ "$Loc" == "i" ]; then
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "Internal Server defined"
|
|
fi
|
|
command=$($STb/speedtest --mini=$SEs --simple)
|
|
else
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "We should never get here as we checked the contents of Location variable earlier!"
|
|
fi
|
|
usage
|
|
exit 3
|
|
fi
|
|
|
|
# Get the output of the speedtest into an array
|
|
# so we can begin to process it
|
|
i=1
|
|
typeset -a array
|
|
|
|
array=($command)
|
|
|
|
# Check if array empty or not having at least 9 indicies
|
|
element_count=${#array[@]}
|
|
expected_count="9"
|
|
|
|
# Output array indicies count for debug
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "count = $element_count"
|
|
fi
|
|
|
|
if [ "$element_count" -ne "$expected_count" ]; then
|
|
echo "You do not have the expected number of indices in your output from SpeedTest. Is it correctly installed?"
|
|
usage
|
|
exit 3
|
|
fi
|
|
|
|
# echo contents of speedtest for debug
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "$command"
|
|
fi
|
|
|
|
# split array into our variables for processing
|
|
ping=${array[1]}
|
|
pingUOM=${array[2]}
|
|
download=${array[4]}
|
|
downloadUOM=${array[5]}
|
|
upload=${array[7]}
|
|
uploadUOM=${array[8]}
|
|
|
|
# echo each array for debug
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "Ping = "$ping
|
|
echo "Download = "$download
|
|
echo "Upload = "$upload
|
|
fi
|
|
|
|
#set up our nagios status and exit code variables
|
|
status=
|
|
nagcode=
|
|
|
|
# now we check to see if returned values are within defined ranges
|
|
# we will make use of bc for our math!
|
|
if float_cond "$download < $DLc"; then
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "Download less than critical limit. \$download = $download and \$DLc = $DLc "
|
|
fi
|
|
status="CRITICAL"
|
|
nagcode=2
|
|
elif float_cond "$upload < $ULc"; then
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "Upload less than critical limit. \$upload = $upload and \$ULc = $ULc"
|
|
fi
|
|
status="CRITICAL"
|
|
nagcode=2
|
|
elif float_cond "$download < $DLw"; then
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "Download less than warning limit. \$download = $download and \$DLw = $DLw"
|
|
fi
|
|
status="WARNING"
|
|
nagcode=1
|
|
elif float_cond "$upload < $ULw"; then
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "Upload less than warning limit. \$upload = $upload and \$ULw = $ULw"
|
|
fi
|
|
status="WARNING"
|
|
nagcode=1
|
|
else
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "Everything within bounds!"
|
|
fi
|
|
status="OK"
|
|
nagcode=0
|
|
fi
|
|
|
|
#nagout="$status - Ping = $ping $pingUOM Download = $download $downloadUOM Upload = $upload $uploadUOM"
|
|
#perfout="|'download'=$download;$DLw;$DLc 'upload'=$upload;$ULw;$ULc"
|
|
nagout="$nagcode speedtest-cli download=$download;$DLw;$DLc|upload=$upload;$ULw;$ULc|ping=$ping;250;500 Ping = $ping $pingUOM Download = $download $downloadUOM Upload = $upload $uploadUOM"
|
|
|
|
# append perfout if argument was passed to script
|
|
if [ "$PerfData" == "TRUE" ]; then
|
|
if [ "$debug" == "TRUE" ]; then
|
|
echo "PerfData requested!"
|
|
fi
|
|
nagout=$nagout$perfout
|
|
fi
|
|
|
|
echo $nagout
|
|
exit $nagcode
|