#!/bin/bash
# 20210628 - Renamed xymon-chronyd.bash
# based on ntpd xymon monitor
# IWT 2010 stanza below for etc/clientlaunch.cfg
# [ntpd]
# ENVFILE $HOBBITCLIENTHOME/etc/hobbitclient.cfg
# CMD $HOBBITCLIENTHOME/ext/xymon-chronyd.cfg
# LOGFILE $HOBBITCLIENTHOME/logs/xymon-chronyd.log
# INTERVAL 5m
# General setup
PROG="xymon-chronyd.bash"
VERSION="0.3"
TEST="ntpd" # THE NAME OF OUR TEST
script=$(basename $0)
FOOTER="
Test: ${TEST}${NL}
Script: ${script}
Version: ${VERSION}${NL}
"
PURPLEDELAY="60" # Time to live = one day
ERRORLOG=$HOBBITCLIENTHOME/logs/$PROG.log
CHRONYC='/usr/bin/chronyc'
# Colors and limits - units are in milliseconds (1/1000s of a second) (other than stratum which goes from 0-16)
((STRATUM_YELLOW = 2)) # if stratum is larger than 2 -- go yellow
((STRATUM_RED = 3)) # if stratum is larger than 3 -- go red
((SLOW_YELLOW = 1)) # if more than 1 ms, go yellow (system time)
((SLOW_RED = 10)) # if more than 10 ms, go red (system time)
((RMS_OFFSET_YELLOW = 1)) # if more than 1 ms, go yellow (RMS Offset)
((RMS_OFFSET_RED = 10)) # if more than 10 ms, go red (RMS Offset)
((DISPERSION_YELLOW = 1)) # if more than 1 ms, go yellow (Root Dispersion)
((DISPERSION_RED = 10)) # if more than 10 ms, go red (Root Dispersion)
# output from: chronyc tracking
# Reference ID : 35.73.197.144 (time1.google.com)
# Stratum : 2
# Ref time (UTC) : Mon Jun 28 16:12:59 2021
# System time : 0.000489485 seconds slow of NTP time
# Last offset : -0.000389254 seconds
# RMS offset : 0.001954304 seconds
# Frequency : 2.726 ppm slow
# Residual freq : -0.015 ppm
# Skew : 0.345 ppm
# Root delay : 0.016909 seconds
# Root dispersion : 0.001069 seconds
# Update interval : 521.7 seconds
# Leap status : Normal
#################################################################
green='GREEN'
yellow='YELLOW'
red='RED'
COLOR="${green}"
ERR=''
NL='
'
DIV='
'
if [[ "X$HOBBITCLIENTHOME" == "X" ]]
then
echo "ERROR: HOBBITCLIENTHOME variable not set"
exit 1
fi
#################################################################
# actually start getting data and running tests
#################################################################
tracking=$(${CHRONYC} tracking)
sources=$(${CHRONYC} sourcestats)
stratum=$(echo "${tracking}" | grep Stratum | awk '{print $3}')
# sed out minus sign so we can look at absolute distance
slow=$(echo "${tracking}" | grep "System time" | awk '{print $4}' | sed 's/-//' | sed 's/+//')
rmsOffset=$(echo "${tracking}" | grep "RMS offset" | awk '{print $4}' | sed 's/-//' | sed 's/+//')
dispersion=$(echo "${tracking}" | grep "Root dispersion" | awk '{print $4}' | sed 's/-//' | sed 's/+//')
sync=$(echo "${tracking}" | grep 'Leap status' | awk '{print $4}' | tr '[:upper:]' '[:lower:]')
# first test is absolute
if (( stratum > STRATUM_RED ))
then
COLOR="${red}"
ERR="STRATUM: ${startum} > Red Threshold (${STRATUM_RED})${NL}"
else
if (( stratum > STRATUM_YELLOW ))
then
COLOR="${yellow}"
ERR="STRATUM: ${startum} > Yellow Threshold (${STRATUM_YELLOW})${NL}"
fi
fi
# rest of tests must assume a tes may have already failed
# system time off
tmp=$(echo "${slow} * 1000" | bc) # multiply by 1000 to get milliseconds
tn=$(echo "0${tmp}" | awk -F'.' '{print $1}') # add leading zero (in case less than 0) and then truncate at decimal point
if ((tn > SLOW_RED))
then
COLOR="${red}"
ERR="${ERR}System time is off: ${slow}*1000 > Red Threshold (${SLOW_RED})${NL}"
else
if ((tn > SLOW_YELLOW))
then
if [[ "${COLOR}" == "${green}" ]]
then
COLOR="${yellow}"
fi
ERR="${ERR}System time is off: ${slow} > Yellow Threshold (${SLOW_YELLOW})${NL}"
fi
fi
#RMS Offset
tmp=$(echo "${rmsOffset} * 1000" | bc) # multiply by 1000 to get milliseconds
tn=$(echo "0${tmp}" | awk -F'.' '{print $1}') # add leading zero (in case less than 0) and then truncate at decimal point
if ((tn > RMS_OFFSET_RED))
then
COLOR="${red}"
ERR="${ERR}RMS Offset is bad: ${rmsOffset} > Red Threshold (${RMS_OFFSET_RED})${NL}"
else
if ((slow > RMS_OFFSET_YELLOW))
then
if [[ "${COLOR}" == "${green}" ]]
then
COLOR="${yellow}"
fi
ERR="${ERR}RMS Offset is bad: ${rmsOffset}*1000 > Yellow Threshold (${RMS_OFFSET_YELLOW})${NL}"
fi
fi
# dispersion
tmp=$(echo "${dispersion} * 1000" | bc) # multiply by 1000 to get milliseconds
tn=$(echo "0${tmp}" | awk -F'.' '{print $1}') # add leading zero (in case less than 0) and then truncate at decimal point
if ((slow > SLOW_RED))
then
COLOR="${red}"
ERR="${ERR}Dispersion is bad: ${dispersion}*1000 > Red Threshold (${DISPERSION_RED})${NL}"
else
if ((slow > SLOW_RED))
then
if [[ "${COLOR}" == "${green}" ]]
then
COLOR="${yellow}"
fi
ERR="${ERR}Dispersion is bad: ${dispersion}*1000 > Yellow Threshold (${DISPERSION_YELLOW})${NL}"
fi
fi
# leap second can be: Normal, Insert second, Delete second or Not synchronized
# grab first word after colon, make loercase and compare to not
if [[ 'not' == "${sync}" ]]
then
COLOR="${red}"
ERR="${ERR}Leap status is Not synchronized${NL}"
fi
if [[ 'X' != "${ERR}X" ]] # we had errors
then
$ERR="${ERR}${NL}${NL}${DIV}${NL}"
fi
MSG="Chronyc tracking:${NL}${tracking}${NL}${NL}${DIV}${NL}chronyc sourcestats: ${sources}${nl}${NL}${DIV}${NL}"
# FORMAT IT PROPERLY FOR BB...
time=`$DATE +"%d/%m/%Y %H:%M:%S"`
LINE="status+${PURPLEDELAY} ${MACHINE}.${TEST} ${COLOR} ${time}
${ERR}
${MSG}
${FOOTER}
"
# Send a status update to the Big Brother display
# echo "$LINE" # SEND IT TO BBDISPLAY
$BB $BBDISP "$LINE" # SEND IT TO BBDISPLAY
# END