Skip to content

Instantly share code, notes, and snippets.

@jacmkno
Last active October 3, 2022 18:22
Show Gist options
  • Select an option

  • Save jacmkno/95ce6095d622d788f5bb to your computer and use it in GitHub Desktop.

Select an option

Save jacmkno/95ce6095d622d788f5bb to your computer and use it in GitHub Desktop.
This script runs health checks in a set of hosts and updates their status on an nginx server. It also sends email notifications with the linux mail command. All other dependencies come natively with linux. It is a great alternative to the comercial nginx health_heck feature.
#!/bin/bash
# By @jacmkno - Activisual S.A.S. - http://activisual.net
# Script summary
# This script runs health cehcks in a set of hosts and updates their status on an nginx server
HOSTS=(201.208.65.152 46.56.115.234 42.79.216.211)
HOSTS_COUNT=3 # Number of hosts in the array
MAIL_SUBJECT='ACTIVISUAL - Health check status change'
MAIL_TO='webmaster@website.net'
NGINX_CONF=nginx.conf
#Expression used in grep to accept a proper response. Server response is stripped from linebreaks and the response headers are included at the begining
TEST_EXPRESSION='HTTP/1.1 200 OK.*region-footer'
SCRIPT_CRONSECS=120 # Calculate repetitions to take this ammount of time. Should equal your crontab setup.
CURL_TIMEOUT=2 # Maximum time culr will wait for an answer
EXTRA_SECS=2 # Wait this number of seconds after each prove
MAX_ERRORS=3 # Flag server as down if the last MAX_ERRORS tests are all errors
PROTOCOL='http' # All servers will be tested with HTTP protocol on port 80
let REPEAT="SCRIPT_CRONSECS/((CURL_TIMEOUT+EXTRA_SECS)*HOSTS_COUNT) - 1"
last_lines=`tail -n 100 /tmp/healthchecks`
echo $last_lines > /tmp/healthchecks
for i in `seq $REPEAT`; do
for host in "${HOSTS[@]}"
do
ans=`curl -is -m $CURL_TIMEOUT "$PROTOCOL://$host"|tr -d "\n"|grep -e "$TEST_EXPRESSION"|wc -l`
echo $host:$ans >> /tmp/healthchecks
errorsCnt=`grep "$host" /tmp/healthchecks|tail -n $MAX_ERRORS|grep ":0"|wc -l`
let serverDown=errorsCnt/MAX_ERRORS
oldStatus=`cat /tmp/health.$host`
status="$host is down? $serverDown"
if [ -n "$oldStatus" ]
then
if [ "$oldStatus" != "$status" ]
then
if [ "$serverDown" -eq 0 ] && [ "$errorsCnt" -gt 0 ]; then
status="$oldStatus"
else
if [ "$serverDown" -eq 0 ]
then
sed 's/'"$host"'\(:[0-9]\+ \| \)down /'$host'\1/' $NGINX_CONF > /tmp/health.newconf
else
sed '/down/! s/'"$host"'\(:[0-9]\+ \| \)/&down /' $NGINX_CONF > /tmp/health.newconf
fi
echo "status change: $status, errors: $errorsCnt" | mail -s "$MAIL_SUBJECT" $MAIL_TO
echo "status change: $status, errors: $errorsCnt"
mv /tmp/health.newconf $NGINX_CONF
sudo service nginx restart
fi
fi
fi
echo "$status, errors: $errorsCnt"
echo $status > /tmp/health.$host
sleep $EXTRA_SECS
done
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment