Table of Contents

Nagios Plugin for scanning HTTP Log

#!/bin/bash
#
# Apache access log line count & response times
# Written by Senthil Nathan
# Last Modified: June 1st 2017
#
# Usage: ./http_stat -f access_log_file -g search_pattern -w Count Warn -c Count Critical (there are more options!!!)
#
# Description: Count the number of lines in apache access log for the previous minute
#
# This plugin is to check the lines generated by the log in the previosu minute
# Assumes apache log time stamp of format "%d/%b/%Y:%H:%M"
# E.g. 08/Dec/2015:10:55:15
#
# Output:
#
#  Count is OK/Warning/Critical|'$themetric'=xxxxxx;nnnnnn;mmmmmm;0
#
# Examples:
#
#   Warn if total access count / minute > 10000
#   Critical if total access count > 20000
#   Below eg may not work
#   http_stat -f /opt/apache2/HTTPServer/logs/app_access_log -w 10000 -c 20000
#
#   This will work!
#   http_stat -f /opt/apache2/HTTPServer/logs/app_access_log -g pos -G pdf -wa 12000 -ca 14000 -wr 250000 -cr 400000 -wh2 12000 -ch2 14000 -wh3 700 -ch3 1000 -wh4 50 -ch4 75 -wh5 10 -ch5 15
#
#
 
PROGNAME=`/bin/basename $0`
PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'`
REVISION="1.0"
#
. $PROGPATH/utils.sh
#
finalstat=$STATE_UNKNOWN
 
check_root()
{
    # make sure script is running as root
    if [ `whoami` != root ]; then
        echo "UNKNOWN: please make sure script is running as root"
        exit $STATE_UNKNOWN
    fi
}
 
print_usage() {
    echo "Usage: $PROGNAME -f <access log file path> 
                           -wa <warning access count> -ca <critical access count> -ma <min access count>
                           -wr <warning response time> -cr <critical response time>
                           -wh2 <warning access count> -ch2 <critical access count>
                           -wh3 <warning access count> -ch3 <critical access count>
                           -wh4 <warning access count> -ch4 <critical access count>
                           -wh5 <warning access count> -ch5 <critical access count>"
    echo "Usage: $PROGNAME --help"
    echo "Usage: $PROGNAME --version"
}
 
print_revision() {
    echo "Program: $PROGNAME"
    echo "Version: $REVISION"
}
 
print_help() {
    print_revision
    echo ""
    print_usage
    echo ""
    echo "Check total access log count 2 minutes for Nagios"
    echo ""
}
 
# Check user is root (not required)
#check_root
 
# Make sure the correct number of command line
# arguments have been supplied
 
if [ $# -lt 1 ]; then
    print_usage
    exit $STATE_UNKNOWN
fi
 
# Grab the command line arguments
 
thegrep=""
declare -i theminia=10
exitstatus=$STATE_WARNING #default
while test -n "$1"; do
    case "$1" in
        --help)
            print_help
            exit $STATE_OK
            ;;
        -h)
            print_help
            exit $STATE_OK
            ;;
        --version)
            print_revision
            exit $STATE_OK
            ;;
        -V)
            print_revision
            exit $STATE_OK
            ;;
        -ca) # Critical Access Counts
            thecrita=$2
            shift
            ;;
        -wa)
            thewarna=$2
            shift
            ;;
        -ma)
            theminia=$2
            shift
            ;;
        -cr) # Critical Response Time
            thecritr=$2
            shift
            ;;
        -wr)
            thewarnr=$2
            shift
            ;;
        -ch2) # Critical HTTP Status Code 2xx
            thecrit2=$2
            shift
            ;;
        -wh2)
            thewarn2=$2
            shift
            ;;
        -ch3) # Critical HTTP Status Code 3xx
            thecrit3=$2
            shift
            ;;
        -wh3)
            thewarn3=$2
            shift
            ;;
        -ch4) # Critical HTTP Status Code 4xx
            thecrit4=$2
            shift
            ;;
        -wh4)
            thewarn4=$2
            shift
            ;;
        -ch5) # Critical HTTP Status Code 5xx
            thecrit5=$2
            shift
            ;;
        -wh5)
            thewarn5=$2
            shift
            ;;
        -f)
            thefile=$2
            shift
            ;;
        --filename)
            thefile=$2
            shift
            ;;
        -G)
            thegrep="$thegrep | grep -v $2 "
            shift
            ;;
        --Grep)
            thegrep="$thegrep | grep -v $2 "
            shift
            ;;
        -g)
            thegrep="$thegrep | grep $2 "
            shift
            ;;
        --grep)
            thegrep="$thegrep | grep $2 "
            shift
            ;;
        *)
            echo "Unknown argument: $1"
            print_usage
            exit $STATE_UNKNOWN
            ;;
    esac
    shift
done
 
# Validate arguments
if [ -z $thecritr ] || [ -z $thewarnr ] || [ -z $thecrita ] || [ -z $thewarna ] || \
   [ -z $thecrit2 ] || [ -z $thewarn2 ] || [ -z $thecrit3 ] || [ -z $thewarn3 ] || \
   [ -z $thecrit4 ] || [ -z $thewarn4 ] || [ -z $thecrit5 ] || [ -z $thewarn5 ] ; then
  print_usage
  exit $STATE_UNKNOWN
fi
if [ -z $thefile ]; then
  print_usage
  exit $STATE_UNKNOWN
fi
 
# Check begins here
 
#
PMIN=`date --date '-2 min' +"%d/%b/%Y:%H:%M"`
declare -i accesscount=0
declare -i responsetime
declare -i http2cnt=0 http3cnt=0 http4cnt=0 http5cnt=0
#
#THE_CMD="grep $PMIN $thefile $thegrep | wc -l"
#accesscount=`eval $THE_CMD`
THE_CMD="grep $PMIN $thefile $thegrep|awk '{ sum += \$11; n++ } END { if (n > 0) printf(\"%d\", sum / n); }'"
responsetime=`eval $THE_CMD`
THE_CMD="grep $PMIN $thefile $thegrep|awk '{print int(\$9/100)}'|sort|uniq -c"
IFS=$'\n'
for output in `eval $THE_CMD`; do
  http_count=`echo $output|awk '{print $1}'`
  accesscount=$((accesscount + http_count))
  http_stats=`echo $output|awk '{print $2}'`
  if [ $http_stats -eq 2 ]; then
    http2cnt=$http_count
  elif [ $http_stats -eq 3 ]; then
    http3cnt=$http_count
  elif [ $http_stats -eq 4 ]; then
    http4cnt=$http_count
  elif [ $http_stats -eq 5 ]; then
    http5cnt=$http_count
  fi
done
 
infostr=""
if [ $accesscount -lt $thewarna ]; then
  infostr="$infostr Access Count is OK."
  outa=$STATE_OK
else
  if [ $accesscount -ge $thecrita ]; then
    infostr="$infostr Access Count is Critical."
    outa=$STATE_CRITICAL
  elif [ $accesscount -ge $thewarna ]; then
    infostr="$infostr Access Count is Warning."
    outa=$STATE_WARNING
  fi
fi
#
if [ $responsetime -lt $thewarnr ]; then
  infostr="$infostr Response Time is OK."
  outr=$STATE_OK
else
  if [ $responsetime -ge $thecritr ]; then
    infostr="$infostr Response Time is Critical."
    outr=$STATE_CRITICAL
  elif [ $responsetime -ge $thewarnr ]; then
    infostr="$infostr Response Time is Warning."
    outr=$STATE_WARNING
  fi
fi
#
if [ $http2cnt -lt $thewarn2 ]; then
  infostr="$infostr HTTP 2xx Count is OK."
  out2=$STATE_OK
else
  if [ $http2cnt -ge $thecrit2 ]; then
    infostr="$infostr HTTP 2xx Count is Critical."
    out2=$STATE_CRITICAL
  elif [ $http2cnt -ge $thewarn2 ]; then
    infostr="$infostr HTTP 2xx Count is Warning."
    out2=$STATE_WARNING
  fi
fi
#
if [ $http3cnt -lt $thewarn3 ]; then
  infostr="$infostr HTTP 3xx Count is OK."
  out3=$STATE_OK
else
  if [ $http3cnt -ge $thecrit3 ]; then
    infostr="$infostr HTTP 3xx Count is Critical."
    out3=$STATE_CRITICAL
  elif [ $http3cnt -ge $thewarn3 ]; then
    infostr="$infostr HTTP 3xx Count is Warning."
    out3=$STATE_WARNING
  fi
fi
#
if [ $http4cnt -lt $thewarn4 ]; then
  infostr="$infostr HTTP 4xx Count is OK."
  out4=$STATE_OK
else
  if [ $http4cnt -ge $thecrit4 ]; then
    infostr="$infostr HTTP 4xx Count is Critical."
    out4=$STATE_CRITICAL
  elif [ $http4cnt -ge $thewarn4 ]; then
    infostr="$infostr HTTP 4xx Count is Warning."
    out4=$STATE_WARNING
  fi
fi
#
if [ $http5cnt -lt $thewarn5 ]; then
  infostr="$infostr HTTP 5xx Count is OK."
  out5=$STATE_OK
else
  if [ $http5cnt -ge $thecrit5 ]; then
    infostr="$infostr HTTP 5xx Count is Critical."
    out5=$STATE_CRITICAL
  elif [ $http5cnt -ge $thewarn5 ]; then
    infostr="$infostr HTTP 5xx Count is Warning."
    out5=$STATE_WARNING
  fi
fi
 
if [ $outa -eq $STATE_CRITICAL ] || [ $outr -eq $STATE_CRITICAL ] || [ $out5 -eq $STATE_CRITICAL ] || \
   [ $out2 -eq $STATE_CRITICAL ] || [ $out3 -eq $STATE_CRITICAL ] || [ $out4 -eq $STATE_CRITICAL ]; then
     finalstat=$STATE_CRITICAL
elif [ $outa -eq $STATE_WARNING ] || [ $outr -eq $STATE_WARNING ] || [ $out5 -eq $STATE_WARNING ] || \
     [ $out2 -eq $STATE_WARNING ] || [ $out3 -eq $STATE_WARNING ] || [ $out4 -eq $STATE_WARNING ]; then
     finalstat=$STATE_WARNING
else
     finalstat=$STATE_OK
fi
 
# If the Minimum Access Count is not reached then force OK!
if [ $accesscount -lt $theminia ]; then
     infostr="Access count is below min required ${theminia}. Forcing OK. $infostr"
     finalstat=$STATE_OK
fi
 
outstrh_a="Access Count=${accesscount}"
outstrh_r="Response Time=${responsetime}us"
outstrh_2="HTTP 2xx Count=${http2cnt}"
outstrh_3="HTTP 3xx Count=${http3cnt}"
outstrh_4="HTTP 4xx Count=${http4cnt}"
outstrh_5="HTTP 5xx Count=${http5cnt}"
 
outstrp_a="'Access Count'=${accesscount};${thewarna};${thecrita};0"
outstrp_r="'Response Time'=${responsetime}us;${thewarnr};${thecritr};0"
outstrp_2="'HTTP 2xx Count'=${http2cnt};${thewarn2};${thecrit2};0"
outstrp_3="'HTTP 3xx Count'=${http3cnt};${thewarn3};${thecrit3};0"
outstrp_4="'HTTP 4xx Count'=${http4cnt};${thewarn4};${thecrit4};0"
outstrp_5="'HTTP 5xx Count'=${http5cnt};${thewarn5};${thecrit5};0"
 
infostr=`echo $infostr|sed 's/^ //'`
echo "$infostr $outstrh_a $outstrh_r $outstrh_2 $outstrh_3 $outstrh_4 $outstrh_5|$outstrp_a $outstrp_r $outstrp_2 $outstrp_3 $outstrp_4 $outstrp_5"
 
#echo "$themetric Check Unknown"
 
exit $finalstat