Je suis un seul développeur Web avec mon propre Centos VPS hébergeant quelques petits sites Web pour mes clients. Aujourd'hui, j'ai découvert que mon service httpd s'était arrêté (sans raison apparente - mais c'est un autre fil). Je l'ai redémarré mais maintenant je dois trouver un moyen d'être averti par e-mail et/ou SMS si cela se reproduit - je n'aime pas quand mon client me téléphone pour me le dire leur site web ne fonctionne pas!
Je sais qu'il existe probablement de nombreuses possibilités différentes, y compris un logiciel de surveillance de serveur. Je pense que tout ce dont j'ai vraiment besoin, c'est d'un script que je peux exécuter en tant que tâche cron à partir de mon hôte de développement (qui s'exécute en permanence dans mon bureau) qui tente de charger une page à partir de mon serveur de production et si elle ne se charge pas dans disons 30 secondes, il m'envoie un e-mail ou un SMS. Je suis assez nul à l'écriture de scripts Shell, d'où cette question.
Toute suggestion serait grandement appréciée.
Eh bien ... Le script le plus simple, j'écris:
/usr/bin/wget "www.example.com" --timeout 30 -O - 2>/dev/null | grep "Normal operation string" || echo "The site is down" | /usr/bin/mail -v -s "Site is down" [email protected]
Ajoutez-le à cron comme:
* * * * * /usr/bin/wget "www.example.com" --timeout 30 -O - 2>/dev/null | grep "Normal operation string" || echo "The site is down" | /usr/bin/mail -v -s "Site is down" [email protected]
Mais il est trop simple de vous dire quel est le problème s'il existe.
PD: Maintenant, cette ligne unique recherche une chaîne spécifique sur la page ("Chaîne de fonctionnement normal"), qui ne devrait apparaître qu'en fonctionnement normal.
UPD2: Un moyen simple d'envoyer la page d'erreur dans l'e-mail:
/usr/bin/wget "www.example.com" --timeout 30 -O - 2>/dev/null | grep "Normal operation string" || /usr/bin/wget "www.example.com" --timeout 30 -O - 2>/dev/null | /usr/bin/mail -v -s "Site is down" [email protected]
Son inconvénient est que la page est demandée à nouveau en cas d'échec du premier test. Cette fois, la demande peut aboutir et vous ne verrez pas l'erreur. Bien sûr, il est possible de stocker la sortie et de l'envoyer en pièce jointe, mais cela rendra le script plus complexe.
Jetez un oeil à ce script:
curl
est un utilitaire de ligne de commande pour récupérer une URL. Le script vérifie le code de sortie ($? Fait référence au code de sortie de la commande la plus récente dans un script Shell) et s'il était différent de 0, signale une erreur (un code de sortie de 0 fait généralement référence à la réussite). Comme mentionné dans la réponse de HUB, vous pouvez également simplement ||
sur la ligne de commande pour exécuter une deuxième commande lorsque la première échoue.
Une fois que vous avez compris le statut, il vous suffit de vous envoyer du courrier. Voici un exemple qui utilise la commande mail
pour envoyer du courrier à partir d'un script Shell, en supposant que la boîte à partir de laquelle vous testez a une configuration SMTP:
BTW: si vous n'êtes pas bon en script Shell, ne vous limitez pas à un script Shell. Vous pouvez utiliser un script Ruby, un script php, tout type de script que votre serveur peut exécuter! Ajoutez simplement le #!/path/to/executable
ligne au début du script - par exemple:
#!/usr/bin/php
Vérifiez ce script . il vérifie une liste de sites Web et envoie un e-mail (à la liste des e-mails) chaque fois que quelque chose ne va pas (réponse http différente de 200). Le script crée un fichier .temp pour "se souvenir" du ou des sites Web qui ont échoué lors de la dernière vérification afin de ne pas recevoir plusieurs e-mails. le fichier .temp est supprimé lorsque le site Web fonctionne à nouveau.
#!/bin/bash
# list of websites. each website in new line. leave an empty line in the end.
LISTFILE=/scripts/isOnline/websites.lst
# Send mail in case of failure to. leave an empty line in the end.
EMAILLISTFILE=/scripts/isOnline/emails.lst
# `Quiet` is true when in crontab; show output when it's run manually from Shell.
# Set THIS_IS_CRON=1 in the beginning of your crontab -e.
# else you will get the output to your email every time
if [ -n "$THIS_IS_CRON" ]; then QUIET=true; else QUIET=false; fi
function test {
response=$(curl --write-out %{http_code} --silent --output /dev/null $1)
filename=$( echo $1 | cut -f1 -d"/" )
if [ "$QUIET" = false ] ; then echo -n "$p "; fi
if [ $response -eq 200 ] ; then
# website working
if [ "$QUIET" = false ] ; then
echo -n "$response "; echo -e "\e[32m[ok]\e[0m"
fi
# remove .temp file if exist.
if [ -f cache/$filename ]; then rm -f cache/$filename; fi
else
# website down
if [ "$QUIET" = false ] ; then echo -n "$response "; echo -e "\e[31m[DOWN]\e[0m"; fi
if [ ! -f cache/$filename ]; then
while read e; do
# using mailx command
echo "$p WEBSITE DOWN" | mailx -s "$1 WEBSITE DOWN" $e
# using mail command
#mail -s "$p WEBSITE DOWN" "$EMAIL"
done < $EMAILLISTFILE
echo > cache/$filename
fi
fi
}
# main loop
while read p; do
test $p
done < $LISTFILE
Ajoutez les lignes suivantes à la configuration de crontab ($ crontab -e)
THIS_IS_CRON=1
*/30 * * * * /path/to/isOnline/checker.sh
Je sais que tous les scripts ci-dessus sont exactement ce que vous avez demandé, mais je suggérerais de regarder monit car il vous enverra un e-mail si Apache est en panne mais il le redémarrera également (s'il est en panne).
Je recommanderais pingdom pour cela. Leur service gratuit vous permet de vérifier 1 site, mais c'est tout ce dont vous avez besoin pour vérifier 1 serveur. Si vous avez un iPhone, ils vous envoient un message push gratuitement, donc pas besoin d'acheter des crédits SMS d'eux, et ils ont plusieurs paramètres que vous pouvez utiliser. Le mien est configuré pour m'avertir après 2 nouvelles tentatives (10 min) et toutes les 10 minutes d'interruption par la suite. C'est génial, car il vérifie également les messages HTTP 500 indiquant qu'un site est en panne. S'il échoue, il vérifie immédiatement votre site à partir d'un serveur différent dans un emplacement différent. Si celui-ci échoue eh bien, cela déclenche votre préférence quant à la façon/quand vous souhaitez être averti.
#!/bin/bash
################Files to be created before starting exicution####################
# Sudo apt-get install alsa alsa-utils #
# mkdir -p $HOME/scripts #
# touch $HOME/scripts/URL_File #
# touch $HOME/scripts/alert_Data #
# touch /tmp/http #
# touch /tmp/http_file #
# Download alert.wav file and copy it into $HOME/scripts directory #
#################################################################################
####### checking existing process and creating temp files for URLs###############
Proc=$(ps -ef | grep http_alerts.sh | wc -l)
number=$(ps -ef | grep http_alerts.sh)
if [ $Proc -gt 3 ]
then
echo "Script Already Running. Please kill PID($number) and restart"
else
FILE="$HOME/scripts/URL_File"
myfileval=1
while read -r line_read; do
echo $line_read > /tmp/http_file
File_name=$(cat /tmp/http_file | awk -v "val=$myfileval" 'NR==val {print $2}')
File_name_val=$(ls /tmp/$File_name 2>/dev/null | wc -l)
File_name_val0=0
if [ $File_name_val -eq $File_name_val0 ]
then
touch /tmp/$File_name
fi
done < "$FILE"
####### checking existing process and finding temp files for URLs###############
echo "############ SCRIPT STARTED WORKING ################"
echo "############ SCRIPT STARTED WORKING ################" >> $HOME/scripts/alert_Data
echo " " >> $HOME/scripts/alert_Data
####### Continues Loop to check the URLs without break ###############
while true
do
####### Reading file URLs ###############
### URL formate- http or https URL;
### remarks; if domain name 0 else 1;
### domain without proto(http/https);
### Public_1; Public_2; ########
filename="$HOME/scripts/URL_File" ### file path
while read -r line; do
echo $line > /tmp/http ### inserting each line data to temparary file
### Checking Internet Connection #######
while true
do
if ping -q -c 1 -W 1 8.8.8.8 >/dev/null;
then
break
else
echo "You are not connected to internet. Please wait"
sleep 5
fi
done
### Checking Internet Connection #######
myval=1
i=$((i+1))
j=7
k=$(shuf -i 1-${j} -n 1)
l=30
i=$(($l+$k)) ##### Color code 31 to 37
echo ""
echo ""
URL=$(cat /tmp/http | awk -v "val=$myval" 'NR==val {print $1}') ### 1st paramater from file. example: http://myabcd.com
Server_State=$(cat /tmp/http | awk -v "val=$myval" 'NR==val {print $2}') ### 2nd paramater from file. example: this_is_myabcd_site
val3=$(cat /tmp/http | awk -v "val=$myfileval" 'NR==val {print $3}') ### 3rd paramater from file. 0 or 1
val4=$(cat /tmp/http | awk -v "val=$myfileval" 'NR==val {print $4}') ### 4rd paramater from file. example: myabcd.com
val5=$(cat /tmp/http | awk -v "val=$myfileval" 'NR==val {print $5}') ### 5th paramater from file. example: 123.123.123.111
val6=$(cat /tmp/http | awk -v "val=$myfileval" 'NR==val {print $5}') ### 6th paramater from file. example: 123.123.123.222
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m"
echo "\e[1;${i}m| Cheking URL : $URL \e[0m"
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| Cheking URL : $URL \e[0m" >> $HOME/scripts/alert_Data
DATA=$(date) ### time stamp
code=$(curl -s -o /dev/null -w "%{http_code}" $URL) ### getting URL response code
if [ $code -eq 200 -o $code -eq 301 -o $code -eq 302 ] ### checking with sucessful response codes
then
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m"
echo "\e[1;${i}m| UP TIME : $DATA \e[0m"
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m"
echo "\e[1;${i}m| Server State: $Server_State \e[0m"
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m"
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| UP TIME : $DATA \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| Server State: $Server_State \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
Elif [ $code -eq 404 -o $code -eq 500 ] ### checking with error response codes
then
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m"
echo "\e[1;${i}m| URL IS DOWN : $URL \e[0m"
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m"
echo "\e[1;${i}m| DOWN TIME : $DATA \e[0m"
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m"
echo "\e[1;${i}m| HTTP TIME : $code \e[0m"
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m"
echo "\e[1;${i}m| Server State: $Server_State \e[0m"
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| URL IS DOWN : $URL \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| DOWN TIME : $DATA \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| HTTP CODE : $code \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| Server State: $Server_State \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m-------------------------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
aplay $HOME/scripts/alert.wav 2> /dev/null ### On failure buzzer will sound
/usr/bin/truncate -s 0 /tmp/$Server_State ### truncate the file with server failure count data
echo " Dear Admin Team \n The $URL is DOWN for the State $Server_State. The HTTP response code is $code " | mail -s "$Server_State is down" -a "From: [email protected]" [email protected],[email protected] >> /dev/null ### On failure sending mail
Elif [ $code -eq 000 ]
then
LNUM=$(cat /tmp/$Server_State | wc -l)
LNUM0=0
oval=0
if [ $val3 -eq $oval ] ### checking Domain or Public IP
then
dname=$(nslookup $val4 | awk '/^Address: /{print $2}') ### getting domain name Public IPs
for dname_i in $dname
do
dname_url="http://$dname_i/" ### Making Public IP as http URL
dname_code=$(curl -s -o /dev/null -w "%{http_code}" $dname_url) ### getting public IP response
if [ $dname_code -eq 200 -o $dname_code -eq 301 -o $dname_code -eq 302 ] ### If success response
then
echo "\e[1;${i}m---------------------------------------------------\e[0m"
echo "\e[1;${i}m| UP TIME : $DATA \e[0m"
echo "\e[1;${i}m---------------------------------------------------\e[0m"
echo "\e[1;${i}m| Server State: $Server_State \e[0m"
echo "\e[1;${i}m---------------------------------------------------\e[0m"
echo "\e[1;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| UP TIME : $DATA \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| Server State: $Server_State \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
else #### if did not success response
if [ $LNUM -eq $LNUM0 ] ### If no failure count, then add the failure count from 1
then
echo "$Server_State 0" > /tmp/$Server_State
else
ALT=$(cat /tmp/$Server_State | awk -v "val=$myval" 'NR==val {print $2}') ### server failure count
ALT5=5
if [ $ALT -eq $ALT5 ] ### If failure count is 5 then alert with sound and send mail
then
echo "\e[0;${i}m---------------------------------------------------\e[0m"
echo "\e[0;${i}m| URL IS DOWN : $URL \e[0m"
echo "\e[0;${i}m---------------------------------------------------\e[0m"
echo "\e[0;${i}m| DOWN TIME : $DATA \e[0m"
echo "\e[0;${i}m---------------------------------------------------\e[0m"
echo "\e[0;${i}m| HTTP CODE : $code \e[0m"
echo "\e[0;${i}m---------------------------------------------------\e[0m"
echo "\e[0;${i}m| Server State: $Server_State \e[0m"
echo "\e[0;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m| URL IS DOWN : $URL \e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m| DOWN TIME : $DATA \e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m| HTTP CODE : $code \e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m| Server State: $Server_State \e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
aplay $HOME/scripts/alert.wav 2> /dev/null ### On failure buzzer will sound
/usr/bin/truncate -s 0 /tmp/$Server_State ### truncate the file with server failure count data
echo " Dear Admin Team \n The $URL is DOWN for the State $Server_State. The HTTP response code is $code " | mail -s "$Server_State is down" -a "From: [email protected]" [email protected],[email protected] >> /dev/null ### On failure sending mail
else
ALT=$((ALT+1)) ### increase server failure count
echo "$Server_State $ALT" > /tmp/$Server_State
fi
fi
fi
done
oval1=1
Elif [ $val3 -eq $oval1 ] ### No domain name backup public IPs are there
then
if [ "$val5" != "" ] ### first Public IP of diffrent ISP
then
dname_url="http://$val5/" ### making URL with public IP
dname_code=$(curl -s -o /dev/null -w "%{http_code}" $dname_url) ### getting response code
if [ $dname_code -eq 200 -o $dname_code -eq 301 -o $dname_code -eq 302 ] ### validating response code
then
echo "\e[1;${i}m---------------------------------------------------\e[0m"
echo "\e[1;${i}m| UP TIME : $DATA \e[0m"
echo "\e[1;${i}m---------------------------------------------------\e[0m"
echo "\e[1;${i}m| Server State: $Server_State \e[0m"
echo "\e[1;${i}m---------------------------------------------------\e[0m"
echo "\e[1;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| UP TIME : $DATA \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| Server State: $Server_State \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
Elif [ "$val6" != "" ] ### second Public IP of diffrent ISP
then
dname_url="http://$val6/" ### making URL with public IP
dname_code=$(curl -s -o /dev/null -w "%{http_code}" $dname_url) ### getting response code
if [ $dname_code -eq 200 -o $dname_code -eq 301 -o $dname_code -eq 302 ] ### validating response code
then
echo "\e[1;${i}m---------------------------------------------------\e[0m"
echo "\e[1;${i}m| UP TIME : $DATA \e[0m"
echo "\e[1;${i}m---------------------------------------------------\e[0m"
echo "\e[1;${i}m| Server State: $Server_State \e[0m"
echo "\e[1;${i}m---------------------------------------------------\e[0m"
echo "\e[1;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| UP TIME : $DATA \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m| Server State: $Server_State \e[0m" >> $HOME/scripts/alert_Data
echo "\e[1;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
else
if [ $LNUM -eq $LNUM0 ]
then
echo "$Server_State 0" > /tmp/$Server_State
else
ALT=$(cat /tmp/$Server_State | awk -v "val=$myval" 'NR==val {print $2}') ### server failure count
ALT5=5
if [ $ALT -eq $ALT5 ]
then
echo "\e[0;${i}m---------------------------------------------------\e[0m"
echo "\e[0;${i}m| URL IS DOWN : $URL \e[0m"
echo "\e[0;${i}m---------------------------------------------------\e[0m"
echo "\e[0;${i}m| DOWN TIME : $DATA \e[0m"
echo "\e[0;${i}m---------------------------------------------------\e[0m"
echo "\e[0;${i}m| HTTP CODE : $code \e[0m"
echo "\e[0;${i}m---------------------------------------------------\e[0m"
echo "\e[0;${i}m| Server State: $Server_State \e[0m"
echo "\e[0;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m| URL IS DOWN : $URL \e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m| DOWN TIME : $DATA \e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m| HTTP CODE : $code \e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m| Server State: $Server_State \e[0m" >> $HOME/scripts/alert_Data
echo "\e[0;${i}m---------------------------------------------------\e[0m" >> $HOME/scripts/alert_Data
aplay $HOME/scripts/alert.wav 2> /dev/null
/usr/bin/truncate -s 0 /tmp/$Server_State
echo " Dear Admin Team \n The $URL is DOWN for the State $Server_State. The HTTP response code is $code " | mail -s "$Server_State is down" -a "From: [email protected]" [email protected],[email protected] >> /dev/null ### On failure sending mail
else
ALT=$((ALT+1))
echo "$Server_State $ALT" > /tmp/$Server_State
fi
fi
fi
fi
fi
fi
fi
sleep 4
vl=1
pdate=$(ls -l $HOME/scripts/alert_Data | awk -v "val=$vl" 'NR==val {print $7}') ### getting file created day
ddate=$(date | awk -v "val=$vl" 'NR==val {print $3}') ### current day count
if [ $pdate -gt $ddate ] ### validating file created day and current
then
d=`date +%m-%d-%Y`
mv $HOME/scripts/alert_Data $HOME/scripts/alert_Data$d ### taking backup of existing file with time stamp
touch $HOME/scripts/alert_Data ### creating new file
fi
done < "$filename"
done
fi
#######################################################################################################################################################
#The content of $HOME/scripts/URL_File is as below
#Please remove "#" and Headline titles. Each parameter will be read by the difrence of spaces.
#URLoftheSite Remarks Domain(0)/IPstatus(1) Domain_name(without protocol) PublicIP_1 PublicIP_2
#http://myexamplesite.com this_is_myexamplesite 1 myexamplesite.com 123.123.123.111 123.123.123.222
Légère variation de ce qui précède.
Un script pour vérifier si un site Web est disponible toutes les 10 secondes. Consigner les tentatives ayant échoué dans un siteuptime.txt
fichier afin qu'il puisse être consulté (ou représenté graphiquement dans Excel) plus tard.
#!/bin/bash
# Check site every 10 seconds, log failed connection attempts in siteuptime.txt
while true; do
echo "Checking site...";
/usr/bin/wget "http://www.mysite" --timeout 6 -O - 2>/dev/null | grep "My String On page" || echo "The site is down" | date --iso-8601=seconds >> siteuptime.txt;
sleep 10;
done;
Comme vous avez de nombreux sites sur votre VPS, je recommanderais que vous puissiez ouvrir un compte avec un site de surveillance de site Web tel que Host-tracker.com. En plus de vous alerter si le site est en panne ou non, ils vous fournissent également une disponibilité hebdomadaire, mensuelle et annuelle de vos sites. Whish est très utile pour la gestion et la performance.
Que dis-tu de ça:
#!/bin/bash
/etc/init.d/httpd status
if [[ $? == 3 ]]; then
echo "Httpd is down `date`" | mail [email protected]
exit 1
fi
exit 0