#!/bin/sh

#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

PROGNAME=`basename $0`
VERSION="Version 1.4,"
AUTHOR="2011, Mike Adolphs (http://www.matejunkie.com/) - Updated Cyrille Josselin"

print_version() {
    echo "$VERSION $AUTHOR"
}

print_help() {
    print_version $PROGNAME $VERSION
    echo ""
    echo "Description:"
    echo "$PROGNAME is a Nagios plugin to check the Apache's server status."
    echo "It monitors requests per second, bytes per second/request, "
    echo "amount of busy/idle workers and its CPU load."
    echo ""
    echo "Example call:"
    echo "./$PROGNAME -H localhost -P 80 -t 30 -s status_page [-S] \\"
    echo "[-wr] 100 [-cr] 250 [-wb] 120|75% [-cb] 130|80% [-wc] 80 [-cc] 140"
    echo ""
    echo "Options:"
    echo "  -H|--hostname)"
    echo "    Sets the hostname. Default is: localhost"
    echo "  -P|--port)"
    echo "    Sets the port. Default is: 80"
    echo "  -t|--timeout)"
    echo "    Sets a timeout within the server's status page must've been"
    echo "    accessed. Otherwise the check will go into an error state."
    echo "    Default is: 30"
    echo "  -s|--status-page)"
    echo "    name of the status page requested. Default is: server-status"
    echo "  -S|--secure)"
    echo "    Enables HTTPS (no certificate check though). Default is: off"
    echo "  -wr|--warning-req)"
    echo "    Sets a warning level for requests per second. Default is: off"
    echo "  -cr|--critical-req)"
    echo "    Sets a critical level for requests per second. Default is: off"
    echo "  -wb|--warning-busy)"
    echo "    Sets a warning level for number of busy workers. Default is: off"
    echo "    can use percentage of busy workers instead of number if '%' used"
    echo "  -cb|--critical-busy)"
    echo "    Sets a critical level for number of busy workers. Default is: off"
    echo "    can use percentage of busy workers instead of number if '%' used"
    echo "  -wc|--warning-consumption)"
    echo "    Sets a warning level for bytes per second. Default is: off"
    echo "  -cc|--critical-consumption)"
    echo "    Sets a critical level for bytes per second. Default is: off"
    exit $ST_UK
}

ST=0
ST_OK=0
ST_WR=1
ST_CR=2
ST_UK=3

hostname="localhost"
port=80
status_page="server-status"
timeout=30
secure=0

wcdiff_req=0
wclvls_req=0

while test -n "$1"; do
    case "$1" in
        --help|-h)
            print_help
            exit $ST_UK
            ;;
        --version|-v)
            print_version $PROGNAME $VERSION
            exit $ST_UK
            ;;
        --hostname|-H)
            hostname=$2
            shift
            ;;
        --port|-P)
            port=$2
            shift
            ;;
        --timeout|-t)
            timeout=$2
            shift
            ;;
        --status-page|-s)
            status_page=$2
            shift
            ;;
        --secure|-S)
            secure=1
            ;;
        --warning-req|-wr)
            warn_req=$2
            shift
            ;;
        --critical-req|-cr)
            crit_req=$2
            shift
            ;;
        --warning-busy|-wb)
            warn_busy=$2
            shift
            ;;
        --critical-busy|-cb)
            crit_busy=$2
            shift
            ;;
        --warning-consumption|-wc)
            warn_consumption=$2
            shift
            ;;
        --critical-consumption|-cc)
            crit_consumption=$2
            shift
            ;;

        *)
            echo "Unknown argument: $1"
            print_help
            exit $ST_UK
            ;;
    esac
    shift
done

# get functions
get_status() {
    if [ "$secure" = 1 ]
    then
        command_status="--no-check-certificate -t 3 -T ${timeout} https://${hostname}:${port}/${status_page}?auto"
    else
        command_status="-t 3 -T ${timeout} http://${hostname}:${port}/${status_page}?auto"
    fi
    server_status=`wget -qO- ${command_status}`
    if [ $? -ne 0 ]
    then    
        echo "UNKNOWN - "`wget -O- ${command_status}  2>&1 | grep -i "failed\|error"|tr "|" ","`
        exit $ST_UK
    fi
}

get_vals() {
    req_psec=`echo ${server_status} | sed -rn 's/.*ReqPerSec:\s+([0-9.]+).*/\1/p' | sed 's/^\./0./'`
    bytes_psec=`echo ${server_status} | sed -rn 's/.*BytesPerSec:\s+([0-9.]+).*/\1/p' | sed 's/^\./0./'`
    bytes_preq=`echo ${server_status} | sed -rn 's/.*BytesPerReq:\s+([0-9.]+).*/\1/p' | sed 's/^\./0./'`
    wkrs_busy=`echo ${server_status} | sed -rn 's/.*BusyWorkers:\s+([0-9.]+).*/\1/p'`
    wkrs_idle=`echo ${server_status} | sed -rn 's/.*IdleWorkers:\s+([0-9.]+).*/\1/p'`
    if [ $wkrs_busy -ge 0 -a $wkrs_idle -ge 0 ]
    then
        wkrs_busy_percent=$((100 * $wkrs_busy / ( $wkrs_busy + $wkrs_idle )))
    fi
    cpu_load=`echo ${server_status} | sed -rn 's/.*CPULoad:\s+([0-9.]+).*/\1/p' | sed 's/^\./0./'`
}

do_output() {
    output="Apache serves $req_psec Requests per second with an average CPU \
utilization of $cpu_load%. Busy workers: $wkrs_busy, idle: $wkrs_idle. Bytes used per second: $bytes_psec, per request: $bytes_preq"
}

do_perfdata() {
    perfdata="'cpu_load'=$cpu_load 'req_psec'=$req_psec \
'bytes_psec'=$bytes_psec 'bytes_preq'=$bytes_preq 'workers_busy'=$wkrs_busy \
'workers_idle'=$wkrs_idle"
}

# Let's go
    get_status
    get_vals

    do_output
    do_perfdata

# check request thresholds
    if [ ! -z "${crit_req}" ] && [ ${req_psec/.*/} -ge ${crit_req} ]
    then
        ST=$ST_CR
        output="Requests (${req_psec}>=${crit_req}) - ${output}"
    elif [ ! -z "${warn_req}" ] && [ ${req_psec/.*/} -ge ${warn_req} ]
    then
        [ $ST -ne $ST_CR ] && ST=$ST_WR
        output="Requests (${req_psec}>=${warn_req}) - ${output}"
    fi

# check workers thresholds
    if [ ! -z "${crit_busy}" ] && [ ${crit_busy/*%/%} = "%" -a ${wkrs_busy_percent} -ge ${crit_busy/"%"/} ] || ( [ ! ${crit_busy/*%/%} = "%" ] && [ ${wkrs_busy} -ge ${crit_busy} ]) 
    then
        ST=$ST_CR
        output="Busy workers (${wkrs_busy}/${wkrs_busy_percent}%>=${crit_busy}) - ${output}"
    elif [ ! -z "${warn_busy}" ] && [ ${warn_busy/*%/%} = "%" -a ${wkrs_busy_percent} -ge ${warn_busy/"%"/} ] || ( [ ! ${warn_busy/*%/%} = "%" ] && [ ${wkrs_busy} -ge ${warn_busy} ] )
    then
        [ $ST -ne $ST_CR ] && ST=$ST_WR
        output="Busy workers (${wkrs_busy}/${wkrs_busy_percent}%>=${warn_busy}) - ${output}"
    fi

# check bytes per second thresholds
    if [ ! -z "${crit_consumption}" ] && [ ${bytes_psec/.*/} -ge ${crit_consumption} ]
    then
        ST=$ST_CR
        output="Bytes per second (${bytes_psec}>=${crit_consumption}) - ${output}"
    elif [ ! -z "${warn_consumption}" ] && [ ${bytes_psec/.*/} -ge ${warn_consumption} ]
    then
        [ $ST -ne $ST_CR ] && ST=$ST_WR
        output="Bytes per second (${bytes_psec}>=${warn_consumption}) - ${output}"
    fi

    if [ $ST -eq 2 ]
    then
        echo "CRITICAL - ${output} | ${perfdata}"
        exit $ST_CR
    elif [ $ST -eq 1 ]
    then
        echo "WARNING - ${output} | ${perfdata}"
        exit $ST_WR
    else
        echo "OK - ${output} | ${perfdata}"
        exit $ST_OK
    fi

