version 1.5, 2019/04/16 07:28:47
|
version 1.6, 2023/08/06 20:06:51
|
Line 1
|
Line 1
|
#!/bin/bash |
#!/bin/bash |
|
|
# canardien 0.0.4 |
# canardien 0.0.6 |
# (c) 2005-2019 under GPL by Adrian Zaugg |
# (c) 2005-2021 under GPL by Adrian Zaugg |
|
|
|
|
# canardien [<host> [<host> ...]] |
# canardien [<host> [<host> ...]] |
|
|
# canardiens pings a machine, originally ente.limmat.ch thus its name, |
# canardiens pings a machine, originally ente.limmat.ch thus its name, |
# to determine wether she is gone diving. |
# to determine wether she is gone diving. |
|
|
|
|
Line 38 ALIVE_ANSWER="is alive"
|
Line 38 ALIVE_ANSWER="is alive"
|
|
|
# Max number of pakets to send before giving up. Time increases exponentially, |
# Max number of pakets to send before giving up. Time increases exponentially, |
# use a number < 7. |
# use a number < 7. |
RETRIES=4 |
RETRIES=5 |
|
|
# Temporary file path |
# Temporary file path |
TMPDIR="/tmp" |
TMPDIR="/tmp" |
Line 78 function init() {
|
Line 78 function init() {
|
if [ -n "$*" ]; then |
if [ -n "$*" ]; then |
HOSTS="$*" |
HOSTS="$*" |
fi |
fi |
|
|
|
# remove multiple spaces and trim |
|
HOSTS="$(echo "$HOSTS" | sed -e "s/ \{1,\}/ /g" -e "s/^ //" -e "s/ $//")" |
|
|
if [ -z "$HOSTS" ]; then |
if [ -z "$HOSTS" ]; then |
echo "Error: No host to ping." >&2 |
echo "Error: No host to ping." >&2 |
exit 0 |
exit 1 |
fi |
fi |
} |
} |
|
|
|
|
# If a host responds to pings, it is considered up. |
# If a host responds to pings, it is considered up. |
function checkconnection() { |
function checkconnection() { |
|
|
while read -r HOST; do |
|
unset UP |
|
|
|
# ping host |
unset UP |
PING_ANSWER="$($PING -R -B 2 -r $RETRIES -p 50 "$HOST" 2>&1)" |
|
PING_ERRNUM=$? |
|
if [ $PING_ERRNUM -gt 2 ]; then |
|
echo "Error: Got error $PING_ERRNUM from fping $(head -1 "$PING_ANSWER"). Disregarding $HOST." >&2 |
|
continue; |
|
fi |
|
|
|
# parse answer |
# ping host |
if [ $(echo "$PING_ANSWER" | grep -c "$ALIVE_ANSWER") -gt 0 ]; then |
PING_ANSWER="$($PING -R -B 2 -r $RETRIES -p 50 "$HOST" 2>&1)" |
UP=true |
PING_ERRNUM=$? |
|
if [ $PING_ERRNUM -gt 2 ]; then |
|
echo "Error: Got error $PING_ERRNUM from fping $(head -1 "$PING_ANSWER"). Disregarding $HOST." >&2 |
|
continue; |
|
fi |
|
|
|
# parse answer |
|
if [ $(echo "$PING_ANSWER" | grep -c "$ALIVE_ANSWER") -gt 0 ]; then |
|
UP=true |
|
fi |
|
TIME_STAMP="$(date +"%a %e.%m.%y %H:%M:%S")" |
|
if [ -n "$UP" ]; then |
|
if [ ! "$DEBUG" = "low" ] && [ -n "$DEBUG" ]; then |
|
shout "The connection to $HOST is up." |
fi |
fi |
TIME_STAMP="$(date +"%a %e.%m.%y %H:%M:%S")" |
else |
if [ -n "$UP" ]; then |
if [ -n "$DEBUG" ]; then |
if [ ! "$DEBUG" = "low" ] && [ -n "$DEBUG" ]; then |
shout "The connection to $HOST is down." |
shout "The connection to $HOST is up." |
|
fi |
|
else |
|
if [ -n "$DEBUG" ]; then |
|
shout "The connection to $HOST is down." |
|
fi |
|
fi |
fi |
|
fi |
# remember a hosts state |
|
rememberstate |
# remember a hosts state |
|
rememberstate |
done <<< "$(echo "$HOSTS" | tr ' ' '\n')" |
|
} |
} |
|
|
|
|
Line 125 function checkconnection() {
|
Line 126 function checkconnection() {
|
function rememberstate() { |
function rememberstate() { |
# Put a simple time stamp in a tmp file, when host is detected as down for the first time |
# Put a simple time stamp in a tmp file, when host is detected as down for the first time |
if [ -z "$UP" ]; then |
if [ -z "$UP" ]; then |
if [ ! -e "$TMPDIR/.canardien-$PINGHOST-$HOST" ]; then |
if [ ! -e "$TMPDIR/.canardien-$PINGHOST-$HOST" ]; then |
# set time stamp |
# set time stamp |
echo -ne "$TIME_STAMP" > "$TMPDIR/.canardien-$PINGHOST-$HOST" |
echo -ne "$TIME_STAMP" > "$TMPDIR/.canardien-$PINGHOST-$HOST" |
# send alert |
# send alert |
Line 133 function rememberstate() {
|
Line 134 function rememberstate() {
|
elif [ -n "$DEBUG" ]; then |
elif [ -n "$DEBUG" ]; then |
shout "Down since `cat $TMPDIR/.canardien-$PINGHOST-$HOST`." |
shout "Down since `cat $TMPDIR/.canardien-$PINGHOST-$HOST`." |
fi |
fi |
else |
else |
# Host is up |
# Host is up |
if [ -e "$TMPDIR/.canardien-$PINGHOST-$HOST" ]; then |
if [ -e "$TMPDIR/.canardien-$PINGHOST-$HOST" ]; then |
if [ -n "$DEBUG" ]; then |
if [ -n "$DEBUG" ]; then |
shout "$HOST is up again." |
shout "$HOST is up again." |
fi |
fi |
# send alert |
# send alert |
ALERT_SUBJECT='"The host $HOST answers again!"' |
ALERT_SUBJECT='"The host $HOST answers again!"' |
ALERT_TEXT='"[$(date +"%a %e.%m.%y %H:%M:%S")]\n\n\n$HOST is up again.\n--------------------------------------\n(downtime began $(cat "$TMPDIR/.canardien-$PINGHOST-$HOST"))\n\n\n Kind regards, $PINGHOST."' |
ALERT_TEXT='"[$(date +"%a %e.%m.%y %H:%M:%S")]\n\n\n$HOST is up again.\n--------------------------------------\n(downtime began $(cat "$TMPDIR/.canardien-$PINGHOST-$HOST"))\n\n\n Kind regards, $PINGHOST."' |
sendalert |
sendalert |
# delete tmp file |
# delete tmp file |
rm "$TMPDIR/.canardien-$PINGHOST-$HOST" |
rm "$TMPDIR/.canardien-$PINGHOST-$HOST" |
else |
else |
# still running |
# still running |
if [ ! "$DEBUG" = "low" ] && [ -n "$DEBUG" ]; then |
if [ ! "$DEBUG" = "low" ] && [ -n "$DEBUG" ]; then |
shout "$HOST is up." |
shout "$HOST is up." |
Line 181 function shout() {
|
Line 182 function shout() {
|
# -----------main----------- |
# -----------main----------- |
|
|
init "$*" |
init "$*" |
checkconnection |
|
|
# call an instance for each host, when multiple hosts are given |
|
if [[ "$HOSTS" =~ " " ]]; then |
|
while read -r HOST; do |
|
"$0" "$HOST" & |
|
done <<< "$(echo "$HOSTS" | tr ' ' '\n')" |
|
exit 0 |
|
else |
|
# process a single host |
|
HOST="$HOSTS" |
|
checkconnection |
|
fi |
|
|
exit 0 |
exit 0 |
|
|
|
# todo: Switches ( -q, --debug, ...) |
|
# grace period: do not send a mail if down time shorter than X minutes |
|
# repeat down info after x hours |
|
# test port instead of ping or in addition |
|
|