#!/bin/bash

nagBase="/usr/local/nagios"
nagLog="$nagBase/var/nagios.log"
archives="$nagBase/var/archives"

# [fromTime]  aSource aType: host;service;state;severity;num;text

#fromTime=`date -d "" +"%s"`
files="$nagLog"
tailMode=""
fromTime=""
toTime=""
noTime=""
host=""
service=""
state=""
severity=""
num=""
# These two need to be regexp wildcards to match everything when nothing is specified
aSource="(HOST|SERVICE)"
aType="(ALERT|NOTIFICATION|EVENT HANDLER)"

print_help() {
  echo "Usage:"
  echo "	-d (debug mode)"
  echo "	-h|--host <host>"
  echo "	-s|--service <service>"
  echo "	--state <warning type (OK, WARNING, CRITICAL, UNKNOWN)> no default"
  echo "	--ok|--warn|--warning|--crit|--critical only print things that match"
  echo "	--hard only print hard stuff"
  echo "	--soft only print soft stuff"
  echo "	--sev|--severity <type (HARD, SOFT)>, default=all"
  echo "	-Q does a quick version of HARD CRITICAL"
  echo "	-n <#> selects the alert number, no default"
  echo "	--type <alert type (ALERT, EVENT, NOTIFICATION)>, default=all"
  echo "	--event set alert type to EVENT HANDLER"
  echo "	--src|--source <alert source (HOST, SERVICE)>, default=all"
  echo "	--from <from time>, default=today at midnight"
  echo "	--to <to time>, default=now"
  echo "	--notime don't convert timestamp to human time"
  echo "	-c|--constant) the equivalent of a tail -f on the Nagios log file"
  echo "	--file <file[s]>) scan <file[s]> instead of $file; use \"...\" if wildcards"
  echo ""
  echo "All input is evaluated as a case-insensitive regexp surrounded by wildcards."
  echo "Time values can be in the following formats:"
  echo "	HH:MM[:SS]	YYYY-MM-DD	YYYY-MM-DD HH:MM[:SS]*"
  echo "This program does not directly scan log files other than the current one.  If you want"
  echo "to scan older files, use the --file option.  Note that this can be combined with the"
  echo "--from and --to options, but keep in mind that file names are named based on the date they"
  echo "were rotated, not the date of their contents."
  echo "*Due to the awk pattern matching, dates before 2020-09-09 will produce empty output."
  exit;
}

while [ -n "$1" ]; do
  case "$1" in
    --help) print_help;;
    --file) files="$2"; shift 2;;
    -h|--host) host="$2"; shift 2;;
    -s|--service) service="$2"; shift 2;;
    --state) state="$2"; shift 2;;
    --ok) state="OK"; shift 1;;
    --warn|--warning) state="WARNING"; shift 1;;
    --crit|--critical) state="CRITICAL"; shift 1;;
    --hard) severity="HARD"; shift 1;;
    --soft) severity="SOFT"; shift 1;;
    --sev|--severity) severity="$2"; shift 2;;
    -Q) severity="HARD"; state="CRITICAL"; shift 1;;
    -n|--num) num="$2"; shift 2;;
    --type) aType="$2"; shift 2;;
    --event) aType="EVENT HANDLER"; shift 1;;
    --src|--source) aSource="$2"; shift 2;;
    --from) fromTime="$2"; shift 2;;
    --to) toTime="$2"; shift 2;;
    --notime) noTime="true"; shift 1;;
    -c|--constant) tailMode="-f"; shift 1;;
    *) shift 1;;
  esac
done

# $1                              $2      $3    $4       $5  $6
# [fromTime]  aSource aType: host;service;state;severity;num;text
# $1                                                                   $2        $3    $4 $5
# [1690749418] HOST ALERT:    Security Cameras;                        DOWN;     SOFT; 1; CRITICAL - 192.168.1.88: rta nan, lost 100%
# [1690765779] SERVICE ALERT: DD-WRT;           Port: vlan1 Bandwidth; CRITICAL; SOFT; 4; CRITICAL - Current BW in: 8.22Mbps Out: 1.58Mbps
#                                                                      (NF-3)    (NF-2)(NF-1)
# (HOST|SERVICE) (DOWNTIME|FLAPPING)? (ALERT|NOTIFICATION)

timeSel=""
if [ -n "$fromTime" ]; then
  fromTimeUnix=$(date -d "$fromTime" +"%s")
  timeSel="&& substr (\$1, 2, 10) >= $fromTimeUnix"
fi
if [ -n "$toTime" ]; then
  toTimeUnix=$(date -d "$toTime" +"%s")
  timeSel="$timeSel && substr (\$1, 2, 10) <= $toTimeUnix"
fi
timeSub=""
[ -z "$noTime" ] && timeSub="&& sub (/^\[[0-9]{10}]/, strftime (\"%Y-%m-%d %H:%M:%S\", substr (\$1, 2, 10)), \$1)"

tail -n +1 $tailMode $files | gawk -F\; "\
	BEGIN {IGNORECASE=1} \
	/^\[[0-9]{10}] (GLOBAL )?$aSource (DOWNTIME |FLAPPING )?$aType: .*$host.*;$service/ \
	&& \$(NF-3)~/$state/ \
	&& \$(NF-2)~/$severity/ \
	&& \$(NF-1)~/$num/ \
	$timeSel \
	$timeSub \
	{printf \"%s: %s;%s;%s;%s;%s\n\", \$1, \$2, \$3, \$4, \$5, \$6}" |
	sed -e "s/;OK;/;\x1b[32mOK\x1b[0m;/" -e "s/;CRITICAL;/;\x1b[31mCRITICAL\x1b[0m;/" -e "s/;WARNING;/;\x1b[33mWARNING\x1b[0m;/" -e "s/;HARD;/;\x1b[35mHARD\x1b[0m;/" -e "s/;SOFT;/;\x1b[36mSOFT\x1b[0m;/"
