Python3 实现简易ping监控并发动报警邮件
1、实现原理通过ping命令结果获取丢包率和延时情况,当丢包率和延时达到预设值时,将结果作为邮件内容,并发送邮件
2、邮件是用smtplib和email实现发送的
3、目前脚本有个小问题就是:我打开文件,循环读,当读第一行时,我执行ping,获取结果,把结果写到一个文件里,同时判断是否达到预设值,如果达到,就把结果加到邮件内容,就这样一直循环,当把文件读完,然后关闭这两个文件,再发送邮件。总觉得有点问题,应该将结果存到一个列表,一次性写入。算了就先这样玩吧。
代码如下:
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# -*- coding:utf-8 -*- __author__ = 'babyshen'
__version__ = '0.0.3'
__datetime__ = '2016-12-30 03:30:00'
import os
import subprocess
import smtplib
import sys
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import COMMASPACE,formatdate
from email import encoders
# server['name'], server['user'], server['passwd'] def send_mail(server, fro, to, subject = " ", text=" ", files = []):
assert type (server) = = dict
assert type (to) = = list
assert type (files) = = list
msg = MIMEMultipart()
msg[ 'From' ] = fro # 邮件的发件人
msg[ 'Subject' ] = subject # 邮件的主题
msg[ 'To' ] = COMMASPACE.join(to) # COMMASPACE==', ' 收件人可以是多个,to是一个列表
msg[ 'Date' ] = formatdate(localtime = True ) # 发送时间
msg.attach(MIMEText(text, 'plain' , 'utf-8' ))
for file in files: # 添加附件可以是多个,files是一个列表,可以为空
part = MIMEBase( 'application' , 'octet-stream' ) #'octet-stream': binary data
with open ( file , 'rb' ) as f:
part.set_payload(f.read())
encoders.encode_base64(part)
part.add_header( 'Content-Disposition' , 'attachment; filename="%s"' % os.path.basename( file ))
msg.attach(part)
smtp = smtplib.SMTP()
smtp.connect(server[ 'name' ]) # connect有两个参数,第一个为邮件服务器,第二个为端口,默认是25
smtp.login(server[ 'user' ], server[ 'passwd' ]) # 用户名,密码
smtp.sendmail(fro, to, msg.as_string()) # 发件人,收件人,发送信息
smtp.close() # 关闭连接
def ping_test(src,dest):
ping = subprocess.Popen( '/bin/ping -i 0.2 -c 4 -q -I ' + src + ' ' + dest,
shell = True ,
stderr = subprocess.PIPE,
stdout = subprocess.PIPE) # 执行命令
res,err = ping.communicate()
if err: sys.exit(err.decode().strip( '\n' ))
pres = list (res.decode().split( '\n' ))
loss = pres[ 3 ].split()[ 5 ] # 获取丢包率
try :
rtt = pres[ 4 ].split( '/' )[ 4 ] # 获取rtt avg值
except IndexError:
rtt = ""
return loss,rtt
def ping_res( file ,revfile):
with open ( file , 'r' , encoding = 'utf-8' ) as f:
with open (revfile, 'w' , encoding = 'utf-8' ) as f1:
textmail = text = '%-15s %-15s %-15s %-5s %-5s \n' % ( 'host' , 'src' , 'dest' , 'loss' , 'rtt' )
f1.write(text)
for line in f:
host = line.split()[ 0 ]
src = line.split()[ 1 ]
dest = line.split()[ 2 ]
threshold = line.split()[ 3 ] if len (line.split()) = = 4 else 100
loss, rtt = ping_test(src, dest)
text = '%-15s %-15s %-15s %-5s %-5s \n' % (host, src, dest, loss, rtt)
f1.write(text)
# 判断丢包率和延时是不是达到预设值
if float (loss.strip( '%' )) > 10 or float (rtt) > float (threshold):
textmail + = text
return textmail
if __name__ = = '__main__' :
try :
file = '/root/ping_test/ping_test.cfg' # 配置文件,格式(空格隔开):主机名,源地址,目标地址,延时阀值(默认是100)
revfile = '/root/ping_test/ping_test.rev' # 结果文件
textmail = ping_res( file ,revfile) # 邮件内容
# print(textmail)
server = { 'name' : 'mail.baidu.com' ,
'user' : 'xxxx' ,
'passwd' :xxoo''}
fro = 'xxxxx'
to = [ 'ooooo' ]
subject = 'ping_test'
if len (textmail.split( '\n' )) = = 2 : sys.exit() # 当只有一行时退出程序不发送邮件
send_mail(server,fro,to,subject,textmail)
except smtplib.SMTPAuthenticationError:
sys.exit( "Mail Authentication Failed" )
except KeyboardInterrupt:
sys.exit( 249 )
except Exception as e:
sys.exit(e)
|
github地址:https://github.com/babyshen/Python/blob/master/monitor.py
升级版本已实现命令行参数和守护进程模式
github地址:https://github.com/babyshen/Python/blob/master/monitor_2.py
本文转自 baby神 51CTO博客,原文链接:http://blog.51cto.com/babyshen/1887791,如需转载请自行联系原作者