OpenFalcon是一款由小米运维团队从互联网公司的需求出发, 根据多年的运维经验,结合市面上使用的一些运维监控系统的使用经验和反馈,开发的一套企业级、高可用、可扩展的开源监控解决方案。简单了使用一下Open-falcon运维监控,结合使用过的zabbix,cacti,nagios来说,觉得有以下几个优点:
- 支持用户主动push,可以结合一些业务需求采集数据,同时也支持用户自定义的插件。
- 支持策略模板,模板继承和覆盖,多种告警方式,支持callback调用
- 由于dashboard采用的是rrd数据,结合rrdtool的数据归档策略,可以及时返回历史数据
- 多维度的数据展示,用户可以自定义Screen。
- 有着完善的开源社区,开源社区提供了各种第三方应用的监控插件。目前的插件支持Linux、Windows、Mysql、Redis、Memache、RabbitMQ和交换机监控。
在这里就不再赘述Open-falcon运维监控系统各种组件,以及如何部署,官方文档写的十分明白,有兴趣的可以去看看官方文档。
官方文档地址:http://book.open-falcon.org/
Open-falcon的github地址:https://github.com/open-falcon/
2、遇到的问题
在使用Open-falcon的过程中遇到过这么一个问题,就是在发送微信报警的时候,发现只能绑定一个企业微信中的应用,如果监控的机器多起来,各种类型的报警成堆的在一个微信应用中出现。所以面对不同的报警类型的告警信息需要把他归类在不同的应用发送,这样面对不同的问题时便可以更加方便的解决。查看了官方提供的微信网关,研究了一下,官方使用go语言写,对于go语言没怎么接触,所以打算用python写一个微信的接口,能够自定义添加绑定不同的应用。
3、解决的方案及思路
大概思路就是,python从wechat.conf配置文件中提取配置信息,定时获取微信的access_token,并且存入到指定access_token.conf的配置文件中,绑定端口监听Open-falcon发送过来的数据,解析提取关键的信息,判断告警类型,并且从access_token.conf配置文件中获取指定应用access_token,然后发送到指定的url。
企业微信API:https://work.weixin.qq.com/api/doc
4、详细解决方法及代码分析
4.1、首先需要统一配置文件的格式:wechat.conf、access_token.conf
wechat.conf
access_token.conf
4.2、获取wechat.conf配置文件的配置项,定时获取access_token
def get_accesstoken():
url = ‘https://qyapi.weixin.qq.com/‘
ap = ConfigParser.SafeConfigParser()
cp = ConfigParser.SafeConfigParser()
ap.read(‘./config/wechat.conf‘)
config = ap.sections()
for i in config:
if i != ‘http‘ and i != ‘weixin‘:
agentid = ap.get(i, ‘AgentId‘)
corpid = ap.get(i, ‘CorpID‘)
corpsecret = ap.get(i, ‘Secret‘)
token_url = ‘%s/cgi-bin/gettoken?corpid=%s&corpsecret=%s‘ % (url, corpid, corpsecret)
access_token = json.loads(urllib.urlopen(token_url).read().decode())[‘access_token‘]
cp.add_section(i)
cp.set(i,"AgentId",agentid)
cp.set(i, "access_token", access_token)
cp.write(open(‘./config/access_token.conf‘,‘w‘))
global timer
timer = threading.Timer(3600,get_accesstoken)
timer.start()
4.3、收集Open-falcon发送到端口的数据
关键代码如下:
#继承threading.Thread类,重写方法,绑定指定端口,接收数据
def __init__(self,port):
threading.Thread.__init__(self)
self.port = port
self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
self.sock.bind((‘0.0.0.0‘,port))
self.sock.listen(0)
#对于接收到的数据进行url解码
def run(self):
while True:
data = self.client.recv(BUFSIZE)
if(data):
string = urllib.unquote(data)
self.handle_String(string)
#print string
else:
break
4.4、对于获取到的数据进行字符串截取
具体用法如下图:
字符串截取代码具体如下:
def handle_String(self,s):
a = s.split(‘&‘)
dict = {}
for i in range(len(a)):
if len(re.split(‘\[‘,a[i]))>1:
dict[‘content‘]=re.split(‘content=‘,a[i])[1]
elif len(re.split(‘tos=‘,a[i]))>1:
dict[‘tos‘]=re.split(‘tos=‘,a[i])[1]
flag = re.split(‘\[‘,dict[‘content‘])[5].split(‘*‘)[0]
touser = dict[‘tos‘]
content = dict[‘content‘]
obj = wechat.Weixin(flag, content)
obj.message(touser)
logging.debug(‘Send to %s Wechat %s %s ‘ % (touser,flag,content))
4.5、对于截取过的数据封装在对象中,并且判断获取指定的access_token和配置项,封装发送。
关键代码如下:
def message(self,touser):
url = ‘https://qyapi.weixin.qq.com/‘
cp = ConfigParser.SafeConfigParser()
ap = ConfigParser.SafeConfigParser()
cp.read(‘./config/wechat.conf‘)
ap.read(‘./config/access_token.conf‘)
config = cp.sections()
access_config = ap.sections()
agentname = ‘test4‘
agentid = cp.get(‘test4‘, ‘AgentId‘)
self.token = ap.get(‘test4‘,‘AgentId‘)
#遍历配置项是否有对应告警类型的应用
for i in config:
if i !=‘http‘ and i!= ‘weixin‘:
value = cp.get(‘weixin‘,i)
if self.flag == value:
agentname = i
agentid = cp.get(i, ‘AgentId‘)
for k in access_config:
if k == agentname:
self.token = ap.get(k,‘access_token‘)
values = {
"touser": touser,
"msgtype": ‘text‘,
"agentid": agentid,
"text": {‘content‘:self.content},
"safe": 0
}
return self.send_message(url,json.dumps(values))
4.6、发送告警信息到指定应用
关键代码如下:
def send_message(self,url,data):
send_url = "%s/cgi-bin/message/send?access_token=%s" %(url,self.token)
self.response = urllib.urlopen(urllib.Request(url=send_url,data=data)).read()
x = json.loads(self.response.decode())[‘errcode‘]
if x==0 :
logging.debug(‘Successfully %s ‘ % (data))
return ‘Successfully‘
else:
logging.debug(‘Faild %s‘ % (data))
return ‘Failed‘
**最后效果图**
总结
因为只在自己的几台虚拟机上运行,暂时还没发现出问题。如果有什么问题希望大家指正,自己学python不久,自己写这个东西学到了很多,遇到问题就不要怕解决,就怕不思考。
接口的源代码:https://github.com/libuliduobuqiuqiu/openfalcon-wechat