-
Hahn Axel (hahn) authoredHahn Axel (hahn) authored
check_haproxy_status 6.27 KiB
#!/bin/bash
# ======================================================================
#
# NAGIOS CLIENT CHECK :: haproxy status
# show current requests to frontend and backend
#
# ----------------------------------------------------------------------
# settings values are parsed by a given section.
# if it fails it scans other sections .. finally default and global
# see getCfgvar
# ----------------------------------------------------------------------
# 2020-04-27 v1.0 <axel.hahn@iml.unibe.ch>
# 2020-04-28 v1.1 <axel.hahn@iml.unibe.ch> added status and max connections for frontend and backend
# 2020-04-29 v1.2 <axel.hahn@iml.unibe.ch> parse ini section by given section
# 2020-06-03 v1.3 <axel.hahn@iml.unibe.ch> added ping to each backend server
# 2020-12-03 v1.4 <axel.hahn@iml.unibe.ch> added support of multiple front- and backends
# 2021-12-14 v1.5 <axel.hahn@iml.unibe.ch> use updated haproxy paser in sourced file
# 2022-04-01 v1.6 <axel.hahn@iml.unibe.ch> use wget default params; shell fixes
# 2022-10-21 v1.7 <axel.hahn@unibe.ch> remove grep: warning: stray \ before white space
# ======================================================================
. $(dirname $0)/inc_pluginfunctions
. $(dirname $0)/inc_haproxy_cfg.sh
cfgfile=/etc/haproxy/haproxy.cfg
tmpfile=/tmp/check_haproxy_status_$$
tmpfile2=/tmp/check_haproxy_status2_$$
tmpfileping=/tmp/check_haproxy_status3_$$
# ----------------------------------------------------------------------
# pre checks
# ----------------------------------------------------------------------
ph.require wget
if [ ! -f $cfgfile ]; then
ph.abort "UNKNOWN: config file does not exist: $cfgfile"
fi
cat $cfgfile >/dev/null
if [ $? -ne 0 ]; then
ph.abort "UNKNOWN: unable to read ha proxy config $cfgfile ... `ls -l $cfgfile`"
fi
cat $cfgfile | grep " mode .*http" >/dev/null
if [ $? -ne 0 ]; then
ph.abort "UNKNOWN: haproxy is not in http mode"
fi
# ----------------------------------------------------------------------
# functions
# ----------------------------------------------------------------------
# find a column number of a given field name in haproxy csv
function getColnumber(){
cat $tmpfile | head -1 | sed 's#,#\n#g' | grep -n "^$1$" | cut -f 1 -d ':'
}
# get stats data from column [name]
function getColumn(){
typeset -i local _iNumber=$1
local _filter=$2
test -z $_filter && _filter='.*'
grep "$_filter" $tmpfile | grep -v "stats_frontend" | cut -f 2,$_iNumber -d ','
}
# get sum of all stats data from column [name]
function getColSum(){
getColumn $1 $2 | rev | cut -f 1 -d "," | rev | while read myvalue
do
echo +$myvalue
done
}
function checkStatus(){
local _value=$1
local _must=$2
echo $_value | grep "$_must" >/dev/null
if [ $? -eq 0 ]; then
echo $_value | grep -v "$_must" | grep "." >/dev/null && echo ERROR
else
echo ERROR
fi
}
# ----------------------------------------------------------------------
# build url
# ----------------------------------------------------------------------
url=$( getStatusUri )
if [ -z "$url" ]; then
ph.abort "UNKNOWN: Unable to detect url for status page."
fi
url="${url};csv;norefresh"
# remove password for showing url in output
urlmasked=$( echo $url | sed "s#\(://\)\(.*@\)#\1#g" )
# ----------------------------------------------------------------------
# check output
# ----------------------------------------------------------------------
# --- get status page
wget -T 5 -t 1 --no-check-certificate -O $tmpfile $url 2>/dev/null
if [ $? -ne 0 ]; then
rm -f $tmpfile
ph.abort "UNKNOWN: url $urlmasked did not respond. $(wget -T 5 -t 1 --no-check-certificate -O - -S $url)"
fi
colLimit=$(getColnumber "slim")
colCurrentConnections=$(getColnumber "scur")
colStatus=$(getColnumber "status")
statusFront=$(getColumn $colStatus ",FRONTEND," | cut -f 2 -d "," | tr "\n" " ")
statusBack=$( getColumn $colStatus ",BACKEND," | cut -f 2 -d "," | tr "\n" " ")
typeset -i iMaxConnFront=$(getColSum $colLimit ",FRONTEND,")
typeset -i iMaxConnBack=$( getColSum $colLimit ",BACKEND,")
typeset -i iFrontend=$(getColSum $colCurrentConnections ",FRONTEND,")
typeset -i iFrontendFree=$iMaxConnFront-$iFrontend
typeset -i iBackend=$( getColSum $colCurrentConnections ",BACKEND," )
typeset -i iBackendFree=$iMaxConnBack-$iBackend
statusExt=
if [ "$( checkStatus ""$statusFront"" 'OPEN' )" = "ERROR" ]; then
ph.setStatus "critical"
statusExt="${statusExt}ERROR: a frontend status is not OPEN\n"
fi
if [ "$( checkStatus ""$statusBack"" 'UP' )" = "ERROR" ]; then
ph.setStatus "critical"
statusExt="${statusExt}ERROR: a backend status is not UP\n"
fi
ph.status "FRONT: $statusFront - ${iFrontend} (max: ${iMaxConnFront}) .. BACK: $statusBack - $iBackend (max: ${iMaxConnBack})"
test -z "$statusExt" || echo "${statusExt}"
# echo; echo DEBUG: ; cat $tmpfile
ph.perfadd "frontend" "${iFrontend}"
ph.perfadd "frontend-max" "${iMaxConnFront}"
ph.perfadd "frontend-free" "${iFrontendFree}"
ph.perfadd "backend" "${iBackend}"
ph.perfadd "backend-max" "${iMaxConnBack}"
ph.perfadd "backend-free" "${iBackendFree}"
# ----------------------------------------------------------------------
# show server connections and summary (FRONTEND/ BACKEND)
# ----------------------------------------------------------------------
getColumn $colCurrentConnections | sed -n "2,$ p" >$tmpfile2
while read line
do
srv=$(echo $line | cut -f 1 -d ",")
val=$(echo $line | cut -f 2 -d ",")
label=$(echo $srv | tr [:upper:] [:lower:])
# echo "${srv} - ${val}"
echo -n "${srv} - ${val} "
# v1.3: if it is a servername then ping to it
# echo ${srv} | grep "^[a-z0-9\-\.]" >/dev/null
# if [ $? -eq 0 ]; then
# ping -c 1 ${srv} >$tmpfileping
# grep "\ 0%\ packet\ loss" $tmpfileping >/dev/null
# if [ $? -eq 0 ]; then
# echo "- Ping OK"
# else
# echo "- Ping FAILED"
# cat $tmpfileping
# test "`ph.status`" = "OK" && ph.setStatus "warning"
# fi
# rm -f $tmpfileping
# else
# echo
# fi
# performance data: send summary only
# echo ${srv} | egrep "(FRONTEND|BACKEND)" >/dev/null && ph.perfadd "${label}" "${val}"
done < $tmpfile2
rm -f $tmpfile $tmpfile2 2>/dev/null
ph.exit
# ----------------------------------------------------------------------