Annotation of badi/public_scripts/canardien/canardien, revision 1.5

1.1       adi         1: #!/bin/bash
                      2: 
1.4       adi         3: # canardien 0.0.4
                      4: # (c) 2005-2019 under GPL by Adrian Zaugg
1.1       adi         5: 
                      6: 
1.4       adi         7: # canardien [<host> [<host> ...]]
                      8: 
                      9: # canardiens pings a machine, originally ente.limmat.ch thus its name, 
                     10: # to determine wether she is gone diving.
                     11: 
1.1       adi        12: 
                     13: ## Settings
                     14: #
                     15: 
1.4       adi        16: # Hosts to ping. use a space separated list for multiple targets. All
                     17: # hosts of the list are checked and their results reported individually.
                     18: # Hosts given on the command line overwrite this setting.
                     19: HOSTS=""
1.1       adi        20: 
                     21: # eMail Alerts
                     22: # Send alert email messages to the following address(es). Leave empty
                     23: # for no alert. For multiple destinations use a comma separated list.
1.3       adi        24: ALERT_TO="root"
1.1       adi        25: 
                     26: # Subject of alert email
1.4       adi        27: ALERT_SUBJECT='"Attention: no answer from $HOST anymore!"'
1.1       adi        28: 
1.4       adi        29: # Text of Message (Put variables in 'single quotes' to protect them. They
                     30: # should get expanded at the time the message is sent!)
1.3       adi        31: ALERT_TEXT='"\n[$TIME_STAMP]\n\nALERT!!\n\n\t$HOST is down!\n\nYou should probably do something, please.\n\nKind regards, $PINGHOST."'
1.1       adi        32: 
1.4       adi        33: # Path to fping
                     34: PING=""
1.1       adi        35: 
1.4       adi        36: # Answer of fping to reachable hosts
1.1       adi        37: ALIVE_ANSWER="is alive"
                     38: 
1.4       adi        39: # Max number of pakets to send before giving up. Time increases exponentially,
                     40: # use a number < 7.
                     41: RETRIES=4
                     42: 
1.1       adi        43: # Temporary file path
                     44: TMPDIR="/tmp"
                     45: 
                     46: # This hosts name
1.4       adi        47: PINGHOST="$(uname -n)"
1.1       adi        48: 
1.4       adi        49: # Set to an empty string to avoid debug output,
1.1       adi        50: # to "low" for a few, output and to anything else
                     51: # for verbose output
1.4       adi        52: DEBUG=verbose
1.1       adi        53: 
1.4       adi        54: # For silent (non-error) operation set to anything,
1.1       adi        55: # comment out to enable text output
1.4       adi        56: #SILENT=shshsh
1.1       adi        57: 
                     58: 
                     59: # -----------functions-----------
                     60: 
1.4       adi        61: # Initialize.
                     62: function init() {
                     63: 
                     64:        # check fping existence
                     65:        if [ -z "$PING" ]; then
                     66:                PING="$(which fping)"
                     67:        fi
1.1       adi        68:        if [ ${#PING} -eq 0 ]; then
1.4       adi        69:                echo "Error: fping external program not found or not set. Exitting." >&2
                     70:                exit 1
                     71:        fi
                     72:        if [ ! -x "$PING" ]; then
                     73:                echo "Error: Can't execute the program set to use as fping. Please enter the correct path to \"fping\"." >&2
1.1       adi        74:                exit 1
                     75:        fi
1.3       adi        76: 
1.4       adi        77:        # get hostset
                     78:        if [ -n "$*" ]; then
                     79:                HOSTS="$*"
                     80:        fi
                     81:        if [ -z "$HOSTS" ]; then
                     82:                echo "Error: No host to ping." >&2
                     83:                exit 0
                     84:        fi
1.1       adi        85: }
                     86: 
1.4       adi        87: 
                     88: # If a host responds to pings, it is considered up.
                     89: function checkconnection() {
                     90:        
                     91:        while read -r HOST; do
                     92:                unset UP
                     93: 
                     94:                # ping host
                     95:                PING_ANSWER="$($PING -R -B 2 -r $RETRIES -p 50 "$HOST" 2>&1)"
                     96:                PING_ERRNUM=$?
                     97:                if [ $PING_ERRNUM -gt 2 ]; then
                     98:                        echo "Error: Got error $PING_ERRNUM from fping $(head -1 "$PING_ANSWER"). Disregarding $HOST." >&2
                     99:                        continue;
                    100:                fi
                    101: 
                    102:                # parse answer
                    103:                if [ $(echo "$PING_ANSWER" | grep -c "$ALIVE_ANSWER") -gt 0 ]; then
                    104:                        UP=true
                    105:                fi
                    106:                TIME_STAMP="$(date +"%a %e.%m.%y %H:%M:%S")"
                    107:                if [ -n "$UP" ]; then
                    108:                        if [ ! "$DEBUG" = "low" ] && [ -n "$DEBUG"  ]; then
                    109:                                shout "The connection to $HOST is up."
                    110:                        fi
                    111:                else 
                    112:                        if [ -n "$DEBUG" ]; then
                    113:                                shout "The connection to $HOST is down."
                    114:                        fi
                    115:                fi
                    116:                
                    117:                # remember a hosts state
                    118:                rememberstate
                    119:                
                    120:        done <<< "$(echo "$HOSTS" | tr ' ' '\n')"
                    121: }
                    122: 
                    123: 
                    124: # Rember recent state of host, trigger alert
                    125: function rememberstate() {
                    126:        # Put a simple time stamp in a tmp file, when host is detected as down for the first time
                    127:        if [ -z "$UP" ]; then
1.3       adi       128:                if [ ! -e "$TMPDIR/.canardien-$PINGHOST-$HOST" ]; then 
1.4       adi       129:                                # set time stamp
                    130:                                echo -ne "$TIME_STAMP" > "$TMPDIR/.canardien-$PINGHOST-$HOST"
                    131:                                # send alert
                    132:                                sendalert
                    133:                        elif [ -n "$DEBUG" ]; then
                    134:                                shout "Down since `cat $TMPDIR/.canardien-$PINGHOST-$HOST`."
                    135:                        fi
                    136:        else 
                    137:          # Host is up
                    138:                if [ -e "$TMPDIR/.canardien-$PINGHOST-$HOST" ]; then
                    139:                        if [ -n "$DEBUG" ]; then
                    140:                                shout "$HOST is up again."
                    141:                        fi
1.3       adi       142:                  # send alert
1.5     ! adi       143:                         ALERT_SUBJECT='"The host $HOST answers again!"'
1.4       adi       144:                         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."'
                    145:                         sendalert
                    146:                        # delete tmp file
                    147:                        rm "$TMPDIR/.canardien-$PINGHOST-$HOST"
                    148:                else 
                    149:                        # still running
                    150:                        if [ ! "$DEBUG" = "low" ] && [ -n "$DEBUG"  ]; then
                    151:                                shout "$HOST is up."
                    152:                        fi
                    153:                fi
                    154:        fi
1.1       adi       155: }
                    156: 
1.4       adi       157: 
1.1       adi       158: # Send an email alert
1.4       adi       159: function sendalert() {
                    160:        # send mail
1.1       adi       161:        if [ ! -z "$ALERT_TO" ]; then
1.4       adi       162:                        eval alert_subject=\$$ALERT_SUBJECT
                    163:                        eval MSG=\$$ALERT_TEXT
                    164:                        echo -e -n "$MSG" | mail -s "$alert_subject" "$ALERT_TO"
                    165:                        if [ -n "$DEBUG" ]; then
                    166:                                shout "Alert sent to $ALERT_TO."
                    167:                        fi
1.1       adi       168:        fi
                    169: }
                    170: 
1.4       adi       171: 
1.1       adi       172: # To avoid any output in case of a silent operation,
                    173: # shout instead of echo.
1.4       adi       174: function shout() {
                    175:        if [ -z "$SILENT" ]; then
                    176:                echo -e "$1"
                    177:        fi
1.1       adi       178: }
                    179: 
                    180: 
                    181: # -----------main-----------
                    182: 
1.4       adi       183: init "$*"
1.1       adi       184: checkconnection
                    185: exit 0

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>