使用脚本监控服务状态

通过shell脚本和定时任务实现服务的状态监控,并在服务状态异常时通报运维人员,当然这只是一个十分简单的脚本实现,可在此脚本基础上增加系统资源预警的功能。

编写思路

  1. 既然是对是否启动的检测,也就是对进程是否存在的检测,即判断服务进程是否存在。
  2. 可通过service命令实现,该命令用来获取或管理Linux系统的服务信息,可通过服务名称找到服务的相关信息包括服务状态(或者查找服务进程,通过ps 命令)。
  3. 配合awk命令进行信息筛选过滤,判断服务状态。
  4. 邮件发送可使用linux自带的mail命令,但由于国内各大邮件服务均不再支持普通链接的方式发送,发送邮件需要SSL链接,在/etc/mail.rc中可配置发送方的邮件账号和密码,但至于怎样开启SSL方式,则无人问津,故放弃使用该命令发送邮件。
  5. 可以使用比较流行的Python脚本实现邮件发送。

实现

shell脚本编写(以apache和mysql服务为例):

watcher.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/sh
datetime=`date +'%Y-%m-%d %H:%M:%S'`
proc_http=`/sbin/service httpd status | awk '$1=="httpd"{if($5=="running..."){print "ok"}else{print ;}}'`
proc_mysql=`/sbin/service mysqld status | awk '$1=="mysqld"{if($5=="running..."){print "ok"}else{print ;}}'`
log="/root/watcher/service.txt"
if [ "$proc_http" != "ok" -o "$proc_mysql" != "ok" ] ; then
msg="$datetime - the service is abnormal, mysqld is [ $proc_mysql ] and httpd is [ $proc_http ]"
if [ "$proc_http" = "ok" -a "$proc_mysql" != "ok" ] ; then
echo " - keep httpd service stopping now..."
some=`/sbin/service httpd stop | awk '{print $4}'`
msg="$msg and keep the httpd service stopped [ $some ]"
fi
echo "$msg"
if [ -f "$log" ] ; then
echo " - the last error file exist, skip this time."
else
echo "$msg" > "$log"
python /root/watcher/mail.py >> /root/watcher/mail.log 2>&1
fi
else
if [ -f "$log" ] ; then
echo "$datetime - found error file, clean up ...[ $log ]"
rm -f "$log"
fi
fi

编写Python脚本用以发送邮件

mail.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/python
import email
import mimetypes
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
import smtplib
def sendEmail(authInfo, fromAdd, toAdd, subject, plainText):
strFrom = fromAdd
strTo = toAdd
server = authInfo.get('server')
user = authInfo.get('user')
passwd = authInfo.get('password')
sslPort = '465'
if not (server and user and passwd) :
print 'incomplete login info, exit now'
return
msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = subject
msgRoot['From'] = strFrom
msgRoot['To'] = strTo
msgRoot.preamble = 'This is a multi-part message in MIME format.'
msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)
msgText = MIMEText(plainText, 'plain', 'utf-8')
msgAlternative.attach(msgText)
#smtp = smtplib.SMTP()
#smtp = smtplib.SMTP(server)
smtp = smtplib.SMTP_SSL(server,sslPort)
smtp.ehlo()
smtp.set_debuglevel(1)
try:
smtp.ehlo()
smtp.login(user, passwd)
smtp.sendmail(strFrom, toAdd, msgRoot.as_string())
except Exception as e:
print e
smtp.close()
return
if __name__ == '__main__' :
authInfo = {}
authInfo['server'] = 'smtp.qq.com'
authInfo['user'] = 'xxxxxxxx@qq.com'
authInfo['password'] = 'xxxxxxxxx'
fromAdd = 'xxxxxxx@qq.com'
toAdd = 'yyyyyyyy@yy.yy.com'
subject = 'apache server error'
file_object = open('httpdlog.txt')
try:
all_the_text = file_object.read()
finally:
file_object.close()
htmlText = all_the_text
sendEmail(authInfo, fromAdd, toAdd, subject, htmlText)

运行与说明

如上代码,监控脚本在确认apache服务和mysql服务任意一个出现异常则输出信息到文件中,再通过python命令执行python脚本来发送通知邮件。而当mysql服务异常时则停止运行中的apache服务,对数据予以保护。且为了避免一旦有服务异常则频繁发送通知邮件的情况,在每次发送邮件前确认上次发送的异常状况是否被处理。

Python脚本通过读取服务监控脚本生成的文件内容为发送内容进行邮件发送,设置好发送方的SMTP服务地址(例如:smtp.qq.com)和用户名(xxxxxxxx@qq.com)及密码(xxxxxxxxxx),同时设置投递目标邮箱地址(yyyyyyyy@yy.yy.com)执行发送。脚本中一行smtp.set_debuglevel(1)用于启用debug模式,该模式下会输出大量运行日志以便对脚本执行进行分析,在实际使用中应该删除这行。

添加定期任务

以管理员身份输入命令 crontab –e 编辑定期任务,通过-l 参数选项查看已经编辑好的定期任务。例如每10分钟检查一次(或使用*/10代替0,10,20,30,40,50来实现,差别在于是否一定是正好的时间点,如10分、20分、30分、40分、50分的时候执行):

1
0,10,20,30,40,50 * * * * /root/watcher/watcher.sh >> /root/watcher/log.log 2>/root/watcher/err.log &

使用脚本监控服务状态
https://vicasong.github.io/python/service-watcher-by-shell/
作者
Vica
发布于
2016年9月14日
许可协议