在《利用Pycurl库监控WEB访问质量(三)》(链接:http://www.jianshu.com/p/96f18e83c8e9)中已经能够检测状态码是否为200,响应时间是否在5秒内,如果上述任何一个条件都不满足,则发报警邮件,同时报警邮件也变得更漂亮了。但是上述的监控方式还是显示比较死板,有点硬编码的感觉,一点都不灵活,比如有些网站,我们是做了正常跳转的(HTTP CODE 302),由于302不是200,所以我们的脚本会发警报邮件,同时响应时间我需要根据不同的网站设置不同的响应时间,而不是一成不变的5秒。
动起手来
监控指标我们需要通过配置文件来加载,而不是定死要代码里,设计如下:
#配置文件
{'url':'http://www.baidu.com','title':'百度','code':[200], 'time':5}
{'url':'http://www.google.com','title':'google','code':[200,302], 'time':10}
可以看到,配置文件中每个网站都有一系列的监控指标,比如code可以是200,也可以是200或302,响应时间是5秒,或者10秒。下面让脚本加载这些监控指标:
#片断代码
with open("sites.txt") as f:
list_of_sites = f.readlines()
for element in list_of_sites:
dict_of_sites = eval(element) # 将str 转换成 dict
# 处理代码......
上述代码极其简单,不再过多解释了。
直接上最终代码:
# coding: utf-8
import pycurl
try:
from io import BytesIO
except ImportError:
from StringIO import StringIO as BytesIO
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
import jinja2
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
templateLoader = jinja2.FileSystemLoader(searchpath=".")
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = 'mail.html'
template = templateEnv.get_template(TEMPLATE_FILE)
templateVars = {'title': 'XX监控邮件',
'subtitle': 'XX网站监控信息记录',
'location': 'XX数据中心',
'jftel': '1381XXX',
'username': 'XXX',
'telephone': '13XXX/186XXX9',
'email': 'XXX@XXX.NET',
'status': [],
'num_sites': 0}
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr(( \
Header(name, 'utf-8').encode(), \
addr.encode("utf-8") if isinstance(addr, unicode) else addr))
from_addr = "XXX@XXX.com"
to_addr = "XXX@XXX.net" # 发送给多个用户,使用逗号分隔
password = "XXX"
smtp_server = "smtp.XXXX.com"
def format_msg(s):
# type: (object) -> object
msg = MIMEText(s, _subtype='html', _charset='utf-8')
msg['From'] = _format_addr(from_addr)
msg['To'] = _format_addr(to_addr)
msg['Subject'] = Header(u'来自XXX的监控小黑屋', 'utf-8').encode()
return msg.as_string()
def send_email(s):
server = smtplib.SMTP(smtp_server, 25)
server.set_debuglevel(0)
server.login(from_addr, password)
server.sendmail(from_addr, ["XXX@XXX.net"], s)
server.quit()
flag = False # 决定是否发报警邮件的标志
list_of_sites = []
outputText = ''
with open("sites.txt") as f:
list_of_sites = f.readlines()
num_sites = len(list_of_sites) # 计算所有站点的数量
templateVars['num_sites'] = num_sites
buffer = BytesIO()
c = pycurl.Curl()
c.setopt(c.FRESH_CONNECT, 1)
for element in list_of_sites:
dict_of_sites = eval(element) # 将str 转换成 dict
c.setopt(c.URL, dict_of_sites['url'].replace('\n', ''))
c.setopt(c.WRITEFUNCTION, buffer.write)
try:
c.perform()
http_code = c.getinfo(c.HTTP_CODE)
total_time = c.getinfo(c.TOTAL_TIME)
if http_code in dict_of_sites['code']:
if total_time <= dict_of_sites['time']:
templateVars['status'].append([dict_of_sites['url'], http_code, total_time])
# outputText = template.render(templateVars)
else:
templateVars['status'].append([dict_of_sites['url'], http_code, total_time])
# outputText = template.render(templateVars)
flag = True
else:
templateVars['status'].append([dict_of_sites['url'], http_code, total_time])
# outputText = template.render(templateVars)
flag = True
except pycurl.error, error:
errno, errstr = error
# print errno, errstr
templateVars['status'].append([dict_of_sites['url'], errno, errstr])
# outputText = template.render(templateVars)
flag = True
c.close()
# print templateVars
outputText = template.render(templateVars)
msg = format_msg(outputText)
if flag:
send_email(msg)