Python3 实现简易ping监控并发送报警邮件

本博客介绍了一个使用 Python 实现的简易 Ping 监控脚本,该脚本能够周期性地检测网络连通性和延迟,并在丢包率或延迟超过预设阈值时发送报警邮件。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值