zabbix3.0实现微信报警

Posted by Yancy on 2016-06-22

前言:

因为我已经在测试环境和·生产环境·都实现了微信和邮件告警。今天有空就写了篇文档后期可以在复习下,现实生产环境中,我们通常使用邮件和短信接受zabbix报警信息,但是邮件经常被工作人员搁置在角落中甚至被设置为垃圾邮件被过滤掉。公司的短信接口又太贵,复杂环境中使用短息报警会使运维成本增加很多。微信提供了很好的第三方接口,我们可以利用微信报警以求降低运维成本。

这里我现在公司也用第三方的电话短信猫做告警,严重的故障会用短信来发送到指定的运维人员。这样即使微信和邮件都没有打开收到,短信和电话会第一时间通知。

微信告警的好处:

第一:可以及时通知时间通知运维人员。及时的解决故障。

第二:下班周末课余时间可以准时接收到。

安装与配置:

微信的第三方接口要求我们先申请一个企业号——传送门:微信企业公众号平台

第一步:申请微信公众号









这里跟微信绑定后期登陆只需要扫描下二维码就可以了。

如何申请也可参考这篇文档:申请微信公众号

如何操作企业号?

1.通讯录添加企业成员

我们要提前把成员信息添加进组织部门,必填项+手机号或者微信号,这样别人扫描二维码的时候才能成功关注企业号。
注意:这里有两个我们要用到信息,一个组织部门的ID,一个部门成员的账号(账号是自己手动指定的,不同于微信号,最好是字母加数字)


2.应用中心创建应用

我们要在这里创建应用,因为要通过应用发送消息给部门成员
注意:这里要记住一个值,应用ID



3.给部门设置管理员

设置--->功能设置---->权限管理---->新建管理组
管理员必须事先已经关注了企业号,并且已经设置好邮箱地址  


确定管理员可以读取通讯录,可以使用应用发消息。
注意:我们需要管理员的CorpID和Secret

我们要准备这些东西:

一个微信企业号
企业号已经被部门成员关注
企业号里有一个可以发消息的应用
一个授权管理员,可以使用该应用给成员发消息

我们要取到这些信息:

成员账号
组织部门ID
应用ID
CropID
Secret

如何调用微信接口?

调用微信接口需要一个调用接口的凭证:access_token

通过 :CropID 、Secret  才能获取到access_token,但是获取到的token有效期为两分钟

微信企业号接口调试工具传送门:http://qydev.weixin.qq.com/debug


测试是否可通:

使用:

curl -s -G  url    获取 AccessToke

使用:

curl --data  url  传送凭证调用企业号接口

这里出现一个问题:

curl -s -G url 获取 AccessToke时候为什么我在用企业号发送消息的时候总是返回{"errcode":41004,"errmsg":"corpsecret missing”}呢?

主要原因:

1
2
3
“41004”说明:缺少secret参数,请排查相关问题。
用“”把url括起来就OK,即curl -s -G "url",估计你已经解决了,帮助后来者吧。

这个问题很棘手,一开始弄搞了一个半个小时后面看到一篇过来人的文章帮助了我:
这里我也贴出来了。参考文档

python脚本原理

 使用:

 self.__corpid =  corpid

 使用:

self.__secret = secret     传送凭证调用企业号接口

脚本已贴出来了,可以下载 weixin.py

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
**#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urllib,urllib2,json
import sys
import logging
reload(sys)
sys.setdefaultencoding( "utf-8" )
class WeChat(object):
__token_id = ''
# init attribute
def __init__(self,url):
self.__url = url.rstrip('/')
self.__corpid = 'xxx'
self.__secret = 'xxx'
# Get TokenID
def authID(self):
params = {'corpid':self.__corpid, 'corpsecret':self.__secret}
data = urllib.urlencode(params)
content = self.getToken(data)
try:
self.__token_id = content['access_token']
# print content['access_token']
except KeyError:
raise KeyError
# Establish a connection
def getToken(self,data,url_prefix='/'):
url = self.__url + url_prefix + 'gettoken?'
try:
response = urllib2.Request(url + data)
except KeyError:
raise KeyError
result = urllib2.urlopen(response)
content = json.loads(result.read())
return content
# Get sendmessage url
def postData(self,data,url_prefix='/'):
url = self.__url + url_prefix + 'message/send?access_token=%s' % self.__token_id
request = urllib2.Request(url,data)
try:
result = urllib2.urlopen(request)
except urllib2.HTTPError as e:
if hasattr(e,'reason'):
print 'reason',e.reason
elif hasattr(e,'code'):
print 'code',e.code
return 0
else:
content = json.loads(result.read())
result.close()
return content
# send message
def sendMessage(self,touser,message):
self.authID()
data = json.dumps({
'touser':touser,
'toparty':"3",
'msgtype':"text",
'agentid':"3",
'text':{
'content':message
},
'safe':"0"
},ensure_ascii=False)
response = self.postData(data)
log_file = "/home/zabbix/weixin.log"
logging.basicConfig(filename=log_file,filemode='a',level=logging.DEBUG)
logging.info(data)
logging.debug(response)
print response
if __name__ == '__main__':
if len(sys.argv) != 4:
print 'error segments, now exit'
sys.exit()
a = WeChat('https://qyapi.weixin.qq.com/cgi-bin')
a.sendMessage(sys.argv[1],sys.argv[3])
log_file = "/home/zabbix/weixin.log" 微信日志
'toparty':"3",

 'agentid':"3", 这里3 是我这边应用ID 3
touser否成员ID列表(消息接收者,多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为@all,则向关注该企业应用的全部成员发送
toparty否部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
totag否标签ID列表,多个接收者用‘|’分隔。当touser为@all时忽略本参数
msgtype是消息类型,此时固定为:text
agentid是企业应用的id,整型。可在应用的设置页面查看
content是消息内容
safe否表示是否是保密消息,0表示否,1表示是,默认0


"touser":"touser",   #企业号中的用户帐号,在zabbix用户Media中配置,如果配置不正常,将按部门发送。
文中使用的用户, toparty 部门iD为3,agentid 应用ID为3.

为什么要这样写脚本?

因为微信企业号开放的端口有固定的格式限制
企业号支持的格式:http://qydev.weixin.qq.com/wiki/index.php?title=消息类型及数据格式

将脚本放入zabbix默认执行路径下

mv weixin.sh /usr/local/zabbix/share/zabbix/alertscripts
chown zabbix.zabbix /usr/local/zabbix/share/zabbix/alertscripts/weixin.py
chmod +x /usr/local/zabbix/share/zabbix/alertscripts/weixin.py

到这里上面基本的已经配置完毕了。

测试脚本是否可以发送成功消息

1
2
[root@salt alertscripts]# python weixin.py test world!
{u'errcode': 60011, u'errmsg': u'no privilege to access/modify contact/party/agent '}

出现我是企业号体验账户 我发送消息:微信错误 errcode=60011. 可参考:微信错误 errcode=60011

我这里的原因是应用ID一开始写1,后来改成3测试就通了。

1
2
[root@salt alertscripts]# python weixin.py test hello world!
{u'invaliduser': u'all user invalid', u'errcode': 0, u'errmsg': u'ok'}

这里用户关注了以后:

1
2
[root@salt alertscripts]# python weixin.py jinyu hello world!
{u'errcode': 0, u'errmsg': u'ok'}

web服务端配置:

至此工具安装完成,在zabbix界面里添加脚本告警

设置脚本,脚本名称为工具名称,设置好点添加按钮

添加新的报警媒介到用户,我以Admin用户为例


添加

选择刚才的媒介,收件人为我提供的UserID,多个用户用|隔开

添加后一点要点更新

我们在这里独立设置一个Action,当然你也可以在默认的Action里添加

名称为weixin

告警消息的格式,大家可以根据自己需求具体设置,下面是我的设置

默认接收人:故障{TRIGGER.STATUS},服务器:{HOSTNAME1}发生: {TRIGGER.NAME}故障!

默认信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
告警主机:{HOSTNAME1}
告警时间:{EVENT.DATE} {EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目:{TRIGGER.KEY1}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
前状态:{TRIGGER.STATUS}:{ITEM.VALUE1}
事件ID:{EVENT.ID}
恢复主旨:恢复{TRIGGER.STATUS}, 服务器:{HOSTNAME1}: {TRIGGER.NAME}已恢复!
恢复信息:
告警主机:{HOSTNAME1}
告警时间:{EVENT.DATE} {EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息: {TRIGGER.NAME}
告警项目:{TRIGGER.KEY1}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
当前状态:{TRIGGER.STATUS}:{ITEM.VALUE1}
事件ID:{EVENT.ID}

切换到操作标签,添加操作
选择发送到Admin用户,只使用weixin,选择好之后点添加,这里我已经添加过了,所以提示更新。

设置好之后如下,点添加

经过以上步骤,就完成了配置,就可以使用zabbix来告警啦,用dd命令测试下磁盘i/o告警,一会就会看到微信上发过来的告警信息

dd if=/dev/zero of=/tmp/test2.img bs=1024M count=1000 oflag=dsync

课外普及:

普及:

如何正确使用dd工具测试磁盘的I/O速度

一般情况下,我们都是使用dd命令创建一个大文件来测试磁盘的读写速度。但是,很多人都存在一个误区,以为dd命令显示的速度就是磁盘的写入速度,其实这是不然的。我们分析一下dd命令是如何工作的。

  1. dd if=/dev/zero of=/xiaohan/test.iso bs=1024M count=1

这种情况下测试显示的速度是dd命令将数据写入到内存缓冲区中的速度,只有当数据写入内存缓冲区完成后,才开始将数据刷入硬盘,所以这时候的数据是无法正确衡量磁盘写入速度的。

  1. dd if=/dev/zero of=/xiaohan/test.iso bs=1024M count=1;sync

这种情况下测试显示的跟上一种情况是一样的,两个命令是先后执行的,当sync开始执行的时候,dd命令已经将速度信息打印到了屏幕上,仍然无法显示从内存写硬盘时的真正速度。

  1. dd if=/dev/zero of=/xiaohan/test.iso bs=1024M count=1 conv=fdatasync

这种情况加入这个参数后,dd命令执行到最后会真正执行一次“同步(sync)”操作,所以这时候你得到的是读取这128M数据到内存并写入到磁盘上所需的时间,这样算出来的时间才是比较符合实际的。

  1. dd if=/dev/zero of=/xiaohan/test.iso bs=1024M count=1 oflag=dsync

这种情况下,dd在执行时每次都会进行同步写入操作。也就是说,这条命令每次读取1M后就要先把这1M写入磁盘,然后再读取下面这1M,一共重复128次。这可能是最慢的一种方式,基本上没有用到写缓存(write cache)。

总结:

建议使用测试写速度的方式为:

dd if=/dev/zero of=/xiaohan/test.iso bs=1024M count=1 conv=fdatasync

建议使用测试读速度的方式为:

dd if=/xiaohan/test.iso of=/dev/zero bs=1024M count=1 iflag=direct

*注:要正确测试磁盘读写能力,建议测试文件的大小要远远大于内存的容量!!!

PS:后续计划

1.后续可能会增加发送次数计数,方便管理用户

2.添加查询操作到微信,针对用户定制开发。可通过微信查询zabbix服务器里监控主机的状态,通过微信简单操作zabbix。

预览

注意事项及报错处理

 #Zabbix-web页面新增用户权限处理,发送对象选择(用户的名称)

#应用当中可见范围选择注意(选这要发送的对象(部门,及部门成员))

zabbix-server2.4服务端编译安装 zabbix-server服务端编译安装

zabbix2.4监控80端口状态 : zabbix监控80端口状态

zabbix+Grafana安装使用监控结合 :zabbix+Grafana安装使用监控结合

zabbix监控MySQL-添加自定义监控项 : zabbix监控MySQL-添加自定义监控项

zabbix的ICMP_Ping模版实现对客户端网络状态的监控 : zabbix的ICMP_Ping模版实现对客户端网络状态的监控

zabbix性能监控故障总结 zabbix性能监控故障总结