msgs.sh
Author | Andy Smith |
---|---|
Compatibility | Xymon 4.2,4.3 |
Requirements | unix |
Download | None |
Last Update | 2014-08-29 |
Description
This is a server-side extension that scans hosts.cfg for custom tags defining log files to be treated separately. Collection and analysis of the log files is carried out as per the msgs column described in the documentation, this extension merely reproduces the status log for the named log files under a different test name. This is useful if you need to configure different actions for alerts in different log files in the critical view.
Installation
Client side
N/A
Server side
Copy script to server/ext/ directory, create entry in tasks.cfg or new file in tasks.d/ directory.
Add tag with the following format to the hosts.cfg entry for desired logs on the relevant hosts:-
MSGS:/path/to/log/file:column_name
You must have previously configured the log /path/to/log/fileto be collected in client-local.cfg and it is expected that there will be a corresponding 'LOG' test configured in analysis.cfg
For troubleshooting, run with '-n' and/or '-x9'.
Source
msgs.sh
Copy this to the “server/ext” directory on your Xymon server.
Show Code ⇲
Hide Code ⇱
#!/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 [<options>] [<Value1....>] \t-n\t\tDont send results to Xymon \t-D <Server Name>\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(m<n?m:n)}; func max(m,n){return(m>n?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 '/<H2>/,$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 <pre> and </pre> 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 '/<pre>/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
tasks.d/msgs
Copy this to the “tasks.d” directory on your Xymon server.
Show Code ⇲
Hide Code ⇱
[msgs] #DISABLED ENVFILE /apps/xymon/server/etc/xymonserver.cfg CMD $XYMONHOME/ext/msgs.sh LOGFILE $XYMONSERVERLOGS/msgs.log INTERVAL 1m
Known Bugs and Issues
To Do
Credits
Changelog
- 2014-01-26
- Initial release
- 2014-08-29
- 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.
- discard the full log and cater for any markup conflicts.