Memonitor Server dengan Shell Script

Kebetulan saat ini saya perlu memonitor server untuk mengecek status services apakah ada yang down atau semuanya baik baik saja. Nagios aja, mungkin terlintas dibenak Anda. Ide yang bagus sih. Tapi Nagios sebaiknya dengan mesin tambahan, percuma install Nagios di server yang sama; resource bertambah tinggi dan instalasi yang ribet. Mungkin dengan satu Shell script saja cukup.

Cari-cari di Google ternyata sudah ada yang buat. Bisa langsung pake; sudah ada sistem notifikasi emailnya pula. Nyontek boleh aja, kan namanya belajar. Kan kita dilahirkan untuk meniru. Tapi harus ada yang beda. Value added lah istilahnya. Saya ingin sedikit modifikasi.

Begini. Saya ingin script ini di Cron setiap 5 menit. Apabila ada yang down, langsung kirim email notifikasi, bila masih down selang 1 jam ke depan, dia akan mengirim email lagi. Selain itu dia akan mengirimkan status setiap jam 6 pagi dan sore. Nah kalau tidak ada kiriman email saat jam tersebut itu pertanda SMTP nya bermasalah. Akur?

Berikut scriptnya di bawah. Perhatikan tertera beberapa port yang akan dicek misalnya 80 untuk http, 3306 mysql, 21 ftp, dan seterusnya.

#!/bin/bash
# Shell script to monitor running services such as web/http, ssh, mail etc.
# Based on: http://bash.cyberciti.biz/monitoring/monitor-unix-linux-network-services/

#check ports
ports="80 443 3306 21 22 53 25 465 110 995 143 993"
# service names as per above ports
service="http https mysql ftp ssh dns smtp smtps pop pops imap imaps"

#Email id to send alert
ADMINEMAIL="admin@domain.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=1

#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
}

#session function
timestamp=$(date +%s)
ret=0
function chk_stamp {
tmpfile="$1"
tmp="$2"

if [ -f $tmpfile ] ; then
filestamp=$(stat -c %Y $tmpfile)
let "dif=$timestamp-$filestamp"
if [[ $dif -gt $tmp ]] ; then
ret=0
rm $tmpfile
else
ret=1
fi
else
ret=0
fi
}

function set_stamp {
tmpfile="$1"
echo "$timestamp" > $tmpfile
}

# 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 | grep -vE '^Active|Proto' | grep 'LISTEN' | awk '{ print $4}' | cut -d: -f2 | sed '/^$/d' | sort  -u)
RPORTS=$($NETSTAT -tulpn | grep 'LISTEN' | awk '{ print $4}' | cut -d: -f2,4 | cut -d: -f2 | sed '/^$/d' | sort  -u)

warn=0
# okay let us compare them
for t in $ports
do
sname=$(echo $service | cut -d' ' -f$c)
echo -en " $sname ($t) : "
echo -en " $sname ($t) : " >> $LOG
status="DOWN"
for r in $RPORTS
do
if [ "$r" == "$t" ]
then
status="OK"
break
fi
done

if [ "$status" == "DOWN" ] ; then warn=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
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

if [ $warn -eq 1 ] ; then
#warn and delay 1 hour
chk_stamp /tmp/warning.tmp 3600
if [ $ret -eq 0 ] ; then
$MAIL -s "NUSADUA: Service Warning @ $(hostname)" $ADMINEMAIL < $LOG
set_stamp /tmp/warning.tmp
echo "warning-sent"
fi
fi

#send status at 6am/pm
chk_stamp /tmp/status.tmp 4500
if [[ $ret -eq 0 && $(date +"%l") -eq 6 ]] ; then
$MAIL -s "NUSADUA: Service Status @ $(hostname)" $ADMINEMAIL < $LOG
set_stamp /tmp/status.tmp
echo "status-sent"
fi
fi
}

### main ###
init_script
chk_services

### remove a log file ###
[ -f $LOG ] && /bin/rm -f $LOG

Nah kelar.

Crontab nya? Gampang…

crontab -e
*/5 * * * * sh /mysh/chck_service.sh

 

 

Share!

    3 pemikiran pada “Memonitor Server dengan Shell Script

      1. Wah ga kepikir tuh. Tapi gampang!!! Bisa aja bikin script php untuk nyimpan data ke database. Di shellnya disisipin line tambahan untuk manggil script php tsb dengan isi parameter yang diperlukan. Semoga membantu.

    Tinggalkan Balasan

    Alamat surel Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *