#!/bin/sh
#ident "@(#)msgs.sh 0.2.0"
#******************************************************************************
# $Id: msgs.sh 225 2014-08-29 14:28:47Z asmith69 $
# $Revision: 225 $
# $Author: asmith69 $
# $Date: 2014-08-29 15:28:47 +0100 (Fri, 29 Aug 2014) $
# $HeadURL: svn://galahad/xymon_addons/trunk/Extensions/msgs.sh $
#******************************************************************************
###############################################################################
# This code scans hosts.cfg for hosts marked with a 'msgs' test and for each
# of these, it will retrieve the relevant part of the current [msgs] log and
# create an alternate column for the given log file.
###############################################################################
# 0.0.0 a while ago abs First version
# 0.1.0 2014-01-26 abs cleaned up and made portable
# 0.2.0 2014-08-29 abs send message via stdin to avoid command line
# length issues.
# add a blank line between all paragraphs to ensure
# only the correct parts of the original page are
# presented, also, discard the full log and cater
# for any markup conflicts.
###############################################################################
# embedded debug command ....
$DBG_SH
#Command=`basename $0 .sh`
Command=`basename $0`
Version=`sed '/^\#ident.*@(#).*$/!d; s/^\(#ident.*@(#)\)\([^ ]*\)\([ ]*\)\([^ ]*\)\([ ]*\)\([^ ]*\)\([ ]*\)\([^ ]*\)"$/\4/;q' $0`
whichunix(){
OSTYPE="unix"
case `uname -m` in
sun4*)
case `uname -r | cut -d. -f1` in
4) OSTYPE="sunos";;
5) OSTYPE="solaris";;
esac ;;
i86pc) OSTYPE="solaris" ;;
i?86|x86_64)
case `uname -r` in
3.2) OSTYPE="sysv"
esac
case `uname -s` in
Linux) OSTYPE="linux"
esac ;;
*)
case `uname -s` in
HP-UX) OSTYPE="hpux" ;;
AIX) OSTYPE="aix" ;;
esac ;;
esac
echo $OSTYPE
}
SED=/bin/sed
GREP=/bin/grep
EGREP=/bin/egrep
case `whichunix` in
linux)
ECHO="echo -e"
AWK=/usr/bin/gawk
PING=/bin/ping
PINGOPTS=-nqc1
;;
*)
ECHO="echo"
AWK=/usr/bin/nawk
PING=/usr/sbin/ping
PINGOPTS=-nc1
;;
esac
PING=portqry
PINGOPTS=
MyBadge="
$Command version $Version column"
# Correct command-line invocation usage ....
Usage="Usage:\t$Command [] []
\t-n\t\tDont send results to Xymon
\t-D \tReport specified Server Name(s)
\t-h\t\tThis Help"
###############################################################################
# de-bugging functions ....
show_only() { echo "$*"; return $?; }
show_and_do() { echo "$*"; eval "$*"; return $?; }
do_only() { eval "$*"; return $?; }
usage_exit() { $ECHO $1 >&2; $ECHO "$Usage" >&2; exit 1; }
err_exit() { $ECHO "$Command: $1" >&2; exit 1; }
###############################################################################
alarm() {
perl -e 'alarm shift;
exec @ARGV' "$@";
}
###############################################################################
portqry() {
/opt/soe/local/bin/perl -e 'use Net::Ping;
($host, $port, $timeout) = @ARGV;
$port = 22 if !$port;
$timeout = 2 if !$timeout;
$r = 1;
$p = Net::Ping->new("tcp", $timeout);
$p->port_number($port);
$r = 0 if $p->ping($host);
$p->close();
exit($r);' "$@"
}
###############################################################################
nexpr() {
$AWK '
func min(m,n){return(mn?m:n)};
BEGIN { print '"$*"' ; exit }'
}
###############################################################################
epoch_ticks_to_human_readable() {
perl -e "print scalar(gmtime($1/1000))"
}
###############################################################################
epoch_ticks() {
perl -e "print time"
}
###############################################################################
send_status_to_xymon() {
# Create the status page
case $CurrentStatus in
$GREEN) COLOR=green;;
$YELLOW) COLOR=yellow;;
$RED) COLOR=red;;
esac
End=`epoch_ticks`
Duration=`expr $End - $Begin`
# Send text status to xymon for display on the page, set the
# colour as appropriate.
echo "status ${MACHINE}.$COLUMN $COLOR `date`
$MSG
${MyBadge} $COLUMN tested in $Duration Seconds" | $XYMON $XYMSRV "@"
}
###############################################################################
send_data_to_xymon() {
if [ -n "${DATA}" ]
then
# Send the CSV to xymon for capture by the rrd module
$XYMON $XYMSRV "data ${MACHINE}.$COLUMN
${DATA}
"
fi
}
###############################################################################
send_clear_status_to_xymon() {
# grab what was there before
ThePage=`$XYMONSTATUS $XYMSRV "xymondlog ${MACHINE}.$COLUMN" | \
$SED -n '//,$p' | \
$SED -e 's/\&green/\&clear/;s/\&white/\&clear/;s/\&red/\&clear/;s/\&yellow/\&clear/'`
# Send text status to xymon for display on the page, set the
# colour as appropriate.
echo "status ${MACHINE}.$COLUMN clear `date`
${TheError}
${ThePage}" | $XYMON $XYMSRV "@"
}
###############################################################################
Server_Summary() {
# grab the full message log that Xymon already analysed
# for all the defined msgs tests
# make sure there is a blank line between all paragraphs
MSGLOG=`$XYMONCOMMS $XYMSRV \
"xymondlog ${MACHINE}.msgs" \
| sed -n '2,$p' \
| sed '/Full log\|\(Critical entries\|Warnings\|No entries\) in/{x;p;x;}' \
`
if [ $? -eq 0 ]
then
Status=`$ECHO "$MSGLOG" | egrep '(No entries|Warnings|Critical entries) in .*'"$LogPath"`
case "$Status" in
"")
MyColour='&yellow';CurrentStatus=$WHITE
Status="No analysis specified for $LogPath"
;;
?yellow?Warnings*) MyColour='&yellow';CurrentStatus=$YELLOW ;;
?red?Critical*) MyColour='&red';CurrentStatus=$RED ;;
*) MyColour='&green';CurrentStatus=$GREEN ;;
esac
$Comment Status=$Status
# cut out the paragraphs in the full message log that refer to the
# analysis of this logfile only
PLogPath=`$ECHO "$LogPath" | sed 's;\([[$/.]\);\\\\\1;g'`
$Comment PLogPath=$PLogPath
# the first sed will leave a leading blank line which needs to be trimmed
# using the second sed. Also, the warning case in analysis will insert
# gratuitous and
tags which need to be trimmed as well.
Loglines=`$ECHO "$MSGLOG" | sed \
-e '/./{H;$!d;}' \
-e 'x;/\(Critical entries\|Warnings\|No entries\) in .*'$PLogPath'/!d;' \
| sed \
-e '/^$/d' \
-e '//d' \
-e '/<\/pre>/d' \
| sed \
-e '/\(Critical entries\|Warnings\|No entries\) in .*'$PLogPath'/G' \
-e '2,$s/\</g' \
-e '2,$s/>/\>/g' \
-e '2,$s/^\./\[/' \
-e '2,$s/^\(&\(yellow\|red\)\) \./\1 \[/' \
`
# in the last sed, add a blank line after the heading anchor
# and replace potential markup conflicts
MSG="
$Loglines
"
# just in case we forgot to analyse this logfile, it will get sent
# back as a clear, so make the page useful
TheError="$Status
$Loglines
"
else
MyColour='&red';CurrentStatus=$WHITE
TheError="$XYMONCOMMS $XYMSRV 'xymondlog ${MACHINE}.msgs' sulked"
MSG="`date`
$TheError
"
fi
return $CurrentStatus
}
###############################################################################
###############################################################################
XYMONHTAG=msgs # What we put in hosts.cfg to trigger this test
COLUMN=$XYMONHTAG # Column name, often same as tag in hosts.cfg
XYMONVSN=4.3.12
###############################################################################
# inherit this from the environment or startup profile if its there
case $XYMONVSN in
4.2*)
XYMONCLIENTHOME="/usr/lib/xymon/client"
XYMONSERVERHOME="/usr/lib/xymon/server"
XYMONCOMMS=bb
HOSTGREP=bbhostgrep
;;
*)
XYMONCLIENTHOME="/apps/xymon/client"
XYMONSERVERHOME="/apps/xymon/server"
XYMONCOMMS=xymon
HOSTGREP=xymongrep
;;
esac
if [ -d $XYMONSERVERHOME ]
then
if [ -z "$XYMONHOME" ]
then
XYMONHOME="$XYMONSERVERHOME" # Directory for the Xymon server files
fi
else
if [ -z "$XYMONHOME" ]
then
XYMONHOME="$XYMONCLIENTHOME" # Directory for the Xymon client files
fi
fi
if [ -z "$XYMON" ]
then
XYMON="$XYMONHOME/bin/${XYMONCOMMS}" # The Xymon client "xymon" utility
fi
if [ -z "$XYMONTMP" ]
then
XYMONTMP="$XYMONHOME/tmp" # Where we may store temporary files.
fi
if [ -z "$XYMONVAR" ]
then
XYMONVAR="$XYMONHOME/data" # The directory holds all monitoring data
fi
if [ -z "$MACHINEDOTS" ]
then
MACHINEDOTS="`uname -n`"
fi
XYMONGREP=$XYMONHOME/bin/${HOSTGREP}
XYMONSTATUS=$XYMONHOME/bin/${XYMONCOMMS} # so we can query when debugging
[ -w $XYMONTMP ] || XYMONTMP="/tmp"
#
if [ -z "$XYMSRV" ]
then
if [ -n "$BBDISP" ]
then
XYMSRV=$BBDISP
else
XYMSRV=127.0.0.1
fi
fi
export XYMONHOME XYMON XYMONCOMMS XYMONTMP XYMONVAR XYMONDISP XYMSRV
# make somewhere for us to scribble
ScratchDir=${XYMONTMP}/${XYMONHTAG}_$$
TheOutput=$ScratchDir/status
mkdir -p $ScratchDir
trap "rm -rf $ScratchDir" 0 1 3 5
# check for command line switches ....
DeBug=
Comment=:
Action=do_only
while getopts X:D:I:nhx: flag
do
case $flag in
X) XYMSRV="$OPTARG" ;;
D) TheServers="$OPTARG" ;;
n) XYMON=echo ;;
x) DeBug="-x $OPTARG"
case ${OPTARG} in
0) Action=do_only ;;
1) Action=show_and_do ;;
2) Action=show_and_do ;;
3) Action=show_only; XYMON=echo ;;
*) Action=show_only; XYMON=echo; Comment=echo ;;
esac
;;
h|\?) usage_exit "" ;;
esac
done
shift `expr $OPTIND - 1`
# adjust path to be able to use xymon utils
PATH=$PATH:$XYMONHOME/bin; export PATH
[ $# -gt 0 ] && RuntimeValues="${@}"
# if not in the c/l, select each host in hosts.cfg with this test defined
if [ -z "$TheServers" ]
then
TheServers=`$XYMONGREP "${XYMONHTAG}*" | $AWK '{print $2}'`
fi
# Lets go ....
RED=3;YELLOW=2;GREEN=1;WHITE=142
Start=`epoch_ticks`
for Server in $TheServers
do
$Comment "analysing Server $Server"
Begin=`epoch_ticks`
MACHINE=`echo $Server | $SED -e's/\./,/g'`
TheTags=`$XYMONCOMMS $XYMSRV "hostinfo host=$Server" | \
tr '|' '\\n' | grep -i ${XYMONHTAG}:`
$Comment "analysing hostinfo $TheTags"
for Tag in $TheTags
do
$Comment " analysing HOST TAG $Tag"
# Re-initialise everything for this loop
MSG=""; DATA=""; TheError=""; COLUMN=""
# MSGS:/usr/lib64/xymon/client/tmp/error.log:msgs_error
LogPath=`echo $Tag | awk -F: '{print $2}'`
COLUMN=`echo $Tag | awk -F: '{print $3}'`
[ -z "$COLUMN" ] && COLUMN=msgs_`basename $LogPath .log`
$Comment " LogPath=$LogPath"
$Comment " COLUMN=$COLUMN"
CurrentStatus=$GREEN
# Check that Server is accessible and create a summary page
Server_Summary
# send the update to Xymon
[ $? -ne $WHITE ] && send_status_to_xymon || send_clear_status_to_xymon
done # TheTags
done # TheServers
exit 0
[msgs]
#DISABLED
ENVFILE /apps/xymon/server/etc/xymonserver.cfg
CMD $XYMONHOME/ext/msgs.sh
LOGFILE $XYMONSERVERLOGS/msgs.log
INTERVAL 1m