zabbix之Web检测(四)
https://blog.51niux.com/?id=150 主要是一些web页面上如items、触发器啊等的一些配置,这里继续记录后面的内容。
一、Web监控
Web scenarios(Web 场景)是用来监控Web程序的,可以监控到Web程序的下载速度、返回码及响应时间,还支持把一组连续的Web动作作为一个整体进行监控。
1.1 Web监控的原理
Web监控即对HTTP服务的监控,模拟用户去访问网站,对特定的结果进行比较,如状态码、返回字符串等特定的数据进行比较和监控,从而判断网站Web服务的可用性。在很多时候,我们可以用脚本、程序来进行自定义监控,如Linux下的命令curl、http库等多种现有的程序和库都可以来实现这一需求。
1.2 Web监控指标
HTTP状态码 : 重点监控40X、50X
HTTP响应速度:对特定的指标进行抽样监控,及时发现服务的可用性和性能指标
HTTP下载速度:对特定的文件抽样下载
1.3 Web监控的配置
Web检测是一个很好的功能,我们也经常会用到,比如检测网站是否正常,网站访问速率是否正常,网站登录是否正常等等,很多东西不是单纯的从进程和端口上面能看出来的。
这个Web检测的过程是zabbix服务器的一个主动去检测的过程,安装的时候加上--with-libcurl参数,虽然是服务器主动去检测,但是web页面配置的时候还是需要在一台主机上配置,所以我们得找一个专门的主机上面来添加web检测,可以直接再127.0.0.1上面添加web检测,或者是专门定义一个模板,里面都是web检测的内容,然后让一个主机来加载此模板。
示例1(静态网页检测):
Web检测的添加:
这里首页的浏览就又几个大网站来举例(我这里就越过模板直接再主机上面添加了):
#进入web检测页面后点击右上角的创建web场景。
#这个页面填完之后,点击步骤再去操作,那个认证一般涉及到登录或者CA证书认证这种TLS访问的时候会用到。
#我们添加了三个,当然添加一个也可以。
博文来自:www.51niux.com
网页触发器的添加:
#就点击本主机的触发器,给我们上面设置的web监测做触发器,监控起来。
#这里主要是添加那里选择哪个监控项做下说明,选择带有code表示的,因为我们检测的是状态码,如果你想选择相应时间就选time,如果选择访问响应速率上面还有个download,然后上面创建web检测的时候设置了两次时间,你看截图红框右边就能了解了,是为了区分知道哪个是哪个。
#做了个简单的触发器,三个都不等于200状态码的时候也就是三个网站都挂了的时候报警,当然一般我们可能就检测一个网页返回非200的状态码就报警了。
查看下网页检测的数据图:
#下面是进入之后的效果图:
示例2(动态网页的检测):
这里我们实验一下登录状态的检测(我把页面换回英文的,正好上面一张中文图,下面一张英文图)。
博文来自:www.51niux.com
添加Steps步骤:
Name: Web监控的名字,具有唯一性,zabbix 2.2开始支持在名称中使用宏 Application: 选择Web监控属于的组。Web scenario items配置属于组后,可以再Monitoring->Latest data分组中看到数据 New application: 输入名称即为场景(scenario)创建新的组 Update interval(in sec):Scenario间隔的时间,单位是秒 Retries: 重试机制,默认是1,最多支持10次重试,从zabbix 2.2开始支持此参数 Agent: 浏览器类型,支持自定义。从zabbix 2.2开始支持宏 HTTP proxy: HTTP代理格式 Variables : Scenario级的变量(macros)可以再scenario steps(URL,Post variables)中配置,格式如:{username}=admin {password}=zabbix {hostid}=regex:hostid is ([0-9]+) #这个一个变量一行 Enabled: Scenario开启关闭
Name: 本步骤的名称 URL:监控的Web页面(注:必须是全路径带页面名) Post: 传递给页面的参数,多个参数之间用&连接,此处可饮用前面定义的变量。 Variables: 设置变量。 Headers:头信息 Follow redirects:跟随跳转 Retrieve only headers:仅获取头信息 Timeout:超时时间 Required string: 页面中能匹配到字符,若不匹配,则认为出错 Status codes:页面返回状态码
#这个Post参数怎么着呢,可以借用浏览器,比如火狐的firebug功能,按F12刷新页面,点击编辑请求头的编辑和重发,看看POST应该是啥。
#触发器的添加也就跟上面一样了。这里我们故意吧密码设置错,看看什么效果。
添加完Steps后的效果:
#这个Steps之所以叫步骤,是有它的道理的,执行的时候是从上到下执行的,如果下面的Steps依赖上面的执行,上面的执行如果有问题,直接就影响到后面了。
先看一下正常的情况:
#从上图可以看出一切OK,看不出问题。
博文来自:www.51niux.com
故意更改成错误密码再查看情况:
{user}=admin {password}=zabbi #我们将密码改成错误的密码
针对登录验证添加一个触发器
#这种添加触发器的方式是错误的,因为如果登录失败,登出的时候连状态码都没有,如果你进行test测试的话你会发现直接就报错了,因为一个数字跟一个空值去对比没法对比。当然有很多种方法检测,这里就举例一种:
#用nodata表达式如果1分钟之内获取不到数据,就认为是waring。下面是设置后的报警信息:
#下面我们把zabbix的登录密码改回正确的,看报警状态是否能改变。
#从截图上看15:05的Warning警告在15:07变成了恢复状态。
#当然也可以判断web.test.fail是不是为0,如果为0就是就是没有失败就没事,如果<>0就报警,也是可以的,比如用这个检测https网页之类的,很多种触发器的设置方式就不一一列举了。
#Web主动检测一般大部分都是检测一个固定的url来判断访问访问是否正常,这种登录验证的验证还是比较少的,当然主要复杂点要去了解页面特点来设置。
示例3(跟zabbix毫无关系,就是涉及到web检测了就提下):
#这个例子跟zabbix的主动检测可以说毫无关系,要说放到这里就是说zabbix的web检测的方式一般主要还是靠http状态码为主,但是如果判断条件再复杂点,比如并非是一个web页面而是一个json页面,要根据json页面大小、获取某个键的数组里面的元素数量、然后json的某个字段是显示OK还是ERR而且还有多个url等等,环境比较复杂,可能要用到自己写了.......下面是一个python小例子,写的low一点大家也好理解:
#!/usr/bin/python # -*- coding: UTF-8 -*- import json import time import urllib2 import os import string import smtplib from email.mime.text import MIMEText from email.header import Header ###mail############ #这个邮件的发送函数主要是摘自网上 mailto_list=['123456789@qq.com','csp@51niux.com'] #收件人(列表) mail_host="smtp.51niux.com" #使用的邮箱的smtp服务器地址 mail_user="test" #用户名 mail_pass="123456" #密码 mail_postfix="51niux.com" #邮箱的后缀,网易就是163.com def send_mail(to_list,sub,content): me="slowurl"+"<"+mail_user+"@"+mail_postfix+">" msg = MIMEText(content,_subtype='plain') msg['Subject'] = sub msg['From'] = me msg['To'] = ";".join(to_list) #将收件人列表以‘;’分隔 try: server = smtplib.SMTP() server.connect(mail_host) #连接服务器 server.login(mail_user,mail_pass) #登录操作 server.sendmail(me, to_list, msg.as_string()) server.close() return True except Exception, e: print str(e) return False ############### url = [ #这里就简单一点将要测试的url做成一个列表 'http://192.168.14.51:8080/infos.htm', 'http://192.168.14.52:8080/infos.htm', 'http://192.168.14.53:8080/infos.htm', 'http://192.168.14.54:8080/infos.htm', 'https://info.51niux.com/infos.htm', ] errlist = [] oklist = [] for x in url: try: #抓取错误放到for循环里面不会因为某一个页面打不开而导致后面的url都被连累 html = urllib2.urlopen(x,timeout = 3) #访问url,加上超时时间防止万一url有问题卡太长时间 hjson = json.loads(html.read().decode('utf-8')) #将json页面导出为json数据 PageSize = int(html.headers['Content-Length']) #获取页面header信息的Content-Length的值也是此页面的大小 ErrMsg = hjson['errMsg'].encode('utf-8') #将获取的unicode转换成str类型 ArrayCount = len(hjson['Infos']) #获取Infos键的数量 if PageSize > 500: if ErrMsg == "OK": if ArrayCount > 30: oklist.append(x) #如果上面三个条件都匹配就将url添加到oklist列表中 except BaseException: ##如果抓取到了错误信息,就做下面的事情,要抓取下错误,不然万一url访问不成功的话程序会报错的 print ("url is err:%s" %x) for item in url: #这里就是让oklist列表跟url列表进行匹配,也就是求个差集,那么没匹配上的肯定就是有问题的url了 if item not in oklist: errlist.append(item) #errlist = list(set(url).difference(set(oklist))) #当然显然用差集比较的方式更好一点 LenErrlist=len(errlist) ####mail_send############ errurl = ','.join(errlist) #将errlist的列表格式转换成str if LenErrlist > 0: if send_mail(mailto_list,"info访问警告","Err Url: %s" %errurl): #第一个字段是收件人、第二个字段邮件主题、第三个字段邮件内容 #这是最好写点中文,如果随便写,可能会被网易当做垃圾邮件退信 print "done!" #这里最好是写入到个文件啥的,这样也能监控起来,不然光print一放后台谁知道出没出问题 else: print "failed!"
#大概意思就是根据json页面提取需要的信息然后调用smtp客户端发送给多个收件人,这个python脚本相对而言比较简单。
#比如在出现错误的时候记录在本地,如何做到发送一次错误之后不再重复发送那就得写计数器了但是这种又不是后台进程可能要借助记录到一个临时文件的方式,不如写成一个插件的形式借助其他的报警工具来进行报警。如下面:
#!/usr/bin/python # -*- coding: UTF-8 -*- import json import time import urllib2 import os import sys import string import time ############### url = [ 'http://192.168.14.51:8080/infos.htm', 'http://192.168.14.52:8080/infos.htm', 'http://192.168.14.53:8080/infos.htm', 'http://192.168.14.54:8080/infos.htm', 'https://info.51niux.com/infos.htm', ] errlist = [] oklist = [] for x in url: try: html = urllib2.urlopen(x,timeout = 3) hjson = json.loads(html.read().decode('utf-8')) PageSize = int(html.headers['Content-Length']) ErrMsg = hjson['errMsg'].encode('utf-8') ArrayCount = len(hjson['Infos']) if PageSize > 500: if ErrMsg == "OK": if ArrayCount > 30: oklist.append(x) except BaseException: Time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) errtext = open("/tmp/urlerr.txt","a") errtext.write(Time +" ") errtext.write("Alert:The show url is have err!"+"\n") errtext.close() errlist = list(set(url).difference(set(oklist))) LenErrlist=len(errlist) ####statuc_check############ errurl = ','.join(errlist) def status(errurl): if errurl.strip()=='': print "The show url is OK!" sys.exit(0) else: print ("The url have err:%s" %errurl) sys.exit(2) status(errurl)
#主要是最下面这个,就是借鉴check_ganglia.py,通过nrpe调用,只是返回检测状态和打印信息,然后剩下的邮件设置啊报警次数什么的都交给如nagios来解决就行了