====== msgs.sh ====== ^ Author | [[ hastymind@googlemail.com | 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. #!/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/^\./\[/' \
                                   -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.


[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.