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,如需转载请自行联系原作者