#!/bin/bash # Shell script to monitor running services such as web/http, ssh, mail etc. # If service fails it will send an Email to ADMIN user # ------------------------------------------------------------------------- # Copyright (c) 2006 nixCraft project <http://www.cyberciti.biz/fb/> # This script is licensed under GNU GPL version 2.0 or above # ------------------------------------------------------------------------- # This script is part of nixCraft shell script collection (NSSC) # Visit http://bash.cyberciti.biz/ for more information. # ---------------------------------------------------------------------- # See URL for more info # http://www.cyberciti.biz/tips/processing-the-delimited-files-using-cut-and-awk.html # --------------------------------------------------- # Last updated: Jun - 15 - 2009. ports="22 53 80 25" # service names as per above ports service="SSH DNS WEB MAIL" #Email id to send alert ADMINEMAIL="admin@myispname.com" #Bin paths, set them according to your Linux distro NETSTAT=/bin/netstat MAIL=/usr/bin/mail LOGGER=/usr/bin/logger ID=/usr/bin/id # Red hat usr uncomment MAIL=/bin/mail LOGGER=/bin/logger #Counters, set defaults c=1 status="" sendmail=0 # set the following to 1, if you want message in /var/log/messages via a SYSLOG logtosyslog=0 # Log file used to send an email LOG="/tmp/services.log.$$" # log message to screen and a log file log(){ echo "$@" echo "$@" >> $LOG } # log message and stop script die(){ echo "$@" exit 999 } # Make sure only root can run it is_root(){ local id=$($ID -u) [ $id -ne 0 ] && die "You must be root to run $0." } # Look out for all bins and create a log file init_script(){ [ ! -x $MAIL ] && die "$MAIL command not found." [ ! -x $NETSTAT ] && die "$NETSTAT command not found." [ ! -x $LOGGER ] && die "$LOGGER command not found." [ ! -x $ID ] && die "$ID command not found." is_root >$LOG } # check for all running services and shoot an email if service is not running chk_services(){ log "-------------------------------------------------------------" log "Running services status @ $(hostname) [ $(date) ]" log "-------------------------------------------------------------" # get open ports RPORTS=$($NETSTAT -tulpn -A inet | grep -vE '^Active|Proto' | grep 'LISTEN' | awk '{ print $4}' | cut -d: -f2 | sed '/^$/d' | sort -u) # okay let us compare them for t in $ports do sname=$(echo $service | cut -d' ' -f$c) echo -en " $sname\t\t\t : " echo -en " $sname\t\t\t : " >> $LOG for r in $RPORTS do if [ "$r" == "$t" ] then status="YES" sendmail=1 break fi done echo -n "$status" echo "" echo -n "$status" >>$LOG echo "" >>$LOG # Log to a syslog /var/log/messages? # This is useful if you have a dedicated syslog server [ $logtosyslog -eq 1 ] && $LOGGER "$sname service running : $status" # Update counters for next round c=$( expr $c + 1 ) status="NO" done log "-------------------------------------------------------------" log "This is an automatically generated $(uname) service status notification by $0 script." if [ $sendmail -eq 1 ]; then $MAIL -s "Service Down @ $(hostname)" $ADMINEMAIL < $LOG fi } ### main ### init_script chk_services ### remove a log file ### [ -f $LOG ] && /bin/rm -f $LOG
4000+ howtos and counting! If you enjoyed this article, join 45000+ others and get free email updates!
- Download Script
- Email this to a friend
- Rss Feed
- Last Updated: 07/14/09


{ 31 comments… read them below or add one }
← Previous Comments
hi.. can you send to me the external script to my email hadi.utomo@gmail.com
Hi thanks for the script..
How to monitor a new port using the scrip.i want to monitor 8080,and i changed port in the ports=”22 53 80 8080″
when running the script it is showing that
SSH : YES
DNS : YES
WEB : YES
tomcat : NO
please help me
Regards
Shaiju
It’s emailing me even when all services are up:
$ sudo ./monitor.sh
————————————————————-
Running services status @ sabresboard [ Fri Apr 9 18:50:43 EDT 2010 ]
————————————————————-
SSH : YES
WEB : YES
MAIL : YES
————————————————————-
This is an automatically generated Linux service status notification by ./monitor.sh script
Still sends me an email.
Where is updated scripts
My experience is that if a port of a running service dosn’t show up in the netstat line, it’s because it’s not using the protocol inet, but inet6 istead.
try netstat -tulpn -A inet,inet6 , but the some modifications to the cut part of this line has to be done also.
cut -d: -f2 would fail because of the format of inet6 is different , try cut -d: -f2,4 | cut -d: -f2 instead.
Hi Smeven,
Thanks a lot…its worked Fine…:)
We want ot chane #get open ports section to
RPORTS=$($NETSTAT -tulapn -A inet,inet6 | grep -vE ‘^Active|Proto’ | grep ‘LISTEN’ | awk ‘{ print $4}’ | cut -d: -f2,4 | cut -d: -f2 | sed ‘/^$/d’ | sort -u) .Then only it will works on Ipv6..
Regards,
Shaiju
Hi,
You have a couple of bugs.
1. The script sends whenever at least one process is UP, you want the opposite.
2 You need to set status to ‘NO’ at the beginning of the loop rather than the end, otherwise if the first service is down it will have a status of empty string.
3. I would recommend using variables more descriptive than a single character, it will make it easier to read.
Here are the changes you need to make (note that I renamed the c variable to ‘count’):
# okay let us compare them
for t in $ports
do
status=”NO”
sname=$(echo $service | cut -d’ ‘ -f$count)
echo -en ” $sname\t\t\t : ”
echo -en ” $sname\t\t\t : ” >> $LOG
for r in $RPORTS
do
if [ "$r" == "$t" ]
then
status=”YES”
break
fi
done
if [ "$status" == "NO" ]
then
sendmail=1
fi
echo -n “$status”
echo “”
echo -n “$status” >>$LOG
echo “” >>$LOG
# Log to a syslog /var/log/messages?
# This is useful if you have a dedicated syslog server
[ $logtosyslog -eq 1 ] && $LOGGER “$sname service running : $status”
# Update counters for next round
count=$( expr $count + 1 )
done
Whoops forgot to use the code blocks
# okay let us compare them
for t in $ports
do
status="NO"
sname=$(echo $service | cut -d' ' -f$count)
echo -en " $sname\t\t\t : "
echo -en " $sname\t\t\t : " >> $LOG
for r in $RPORTS
do
if [ "$r" == "$t" ]
then
status="YES"
break
fi
done
if [ "$status" == "NO" ]
then
sendmail=1
fi
echo -n "$status"
echo ""
echo -n "$status" >>$LOG
echo "" >>$LOG
# Log to a syslog /var/log/messages?
# This is useful if you have a dedicated syslog server
[ $logtosyslog -eq 1 ] && $LOGGER "$sname service running : $status"
# Update counters for next round
count=$( expr $count + 1 )
done
RPORTS=$($NETSTAT -tulpn | grep -vE ‘^Active|Proto’ | grep ‘LISTEN’ | awk ‘{ print $4}’ | sed ‘s/[0-9a-z\.\:]*\:\([0-9]\+\)$/\1/’ | sort -u)
On .el5 this is not working . Only SMTP status printed properly.
Had problem with httpd not using a set ip and with the command in script above does not find services that don’t have them attached to an ip. So I have fixed this with the following command.
NETSTAT -tulpn | grep -vE '^Active|Proto' | grep 'LISTEN' | awk '{ print $4}' | awk -F: '{print $NF}' | sed '/^$/d' | sort -u← Previous Comments