Grafana配置企业微信机器人实现监控告警
1.方案架构
实现功能:基于日志、zabbix或prometheus的监控数据,通过企业微信机器人实现监控告警
方案设计如下,Grafana可对接Zabbix、Prometheus和Elasticsearch等数据源,并在Grafana上配置告警触发条件,并设置私人定制的Webhook作为告警通道,将告警信息通过企业微信机器人提醒系统负责人。
2.企业微信配置
在企业微信上创建群聊,并添加该群专属机器人后会获得一个专属KEY,并记录保存。
3.Grafana配置
4.Webhook代码示例
Webhook的代码比较简单,基于Python 轻量级web框架Flask编写,整个逻辑简洁明了。具体实现代码如下:
from flask import Flask
from flask import request
import requests
import json
app = Flask(__name__)
def sendMsg(msg):
robot_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send"
payload = {}
payload["key"] = "企业微信机器人Key" #修改为你的机器人key
headers = {'Content-Type': 'application/json'}
r = requests.post(url=robot_url, headers=headers, params=payload, data=json.dumps(msg))
print(r.text)
def msgGenerator(content, mentionedList,type="text"):
msg = {
"msgtype": type,
type: ""
}
message = {}
message["content"] = content
mentioned_list = mentionedList
message["mentioned_list"] = mentioned_list
msg[type] = message
return msg
@app.route('/hello')
def hello():
return 'Hello, World!'
@app.route('/alert', methods=['POST'])
def send():
receivers = str(request.args.get("receivers")).split(",")
print(receivers)
if request.content_type.startswith('application/json'):
a = request.get_data()
dict1 = json.loads(a)
# msg = {}
# msg["title"] = dict1['title']
# msg["message"] = dict1['message']
# msg["ruleUrl"] = dict1['ruleUrl']
mstr = "【告警内容】"+"\n"+"告警应用: " + str(dict1['title']) + "\n" +"告警信息:" + str(dict1['message']) + "\n" + "详情:" + str(dict1['ruleUrl'])
message = msgGenerator(mstr, receivers)
sendMsg(message)
return "OK"
if __name__ == '__main__':
app.run(host="0.0.0.0", port=8080)
5.K8S部署Yaml文件
经编写好的代码打成镜像,并部署到K8S集群中,具体部署的yaml文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webhook
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
app: webhook
template:
metadata:
labels:
app: webhook
spec:
containers:
- args:
- python
- /opt/webhook.py
env:
- name: FLASK_APP
value: hello
- name: FLASK_ENV
value: development
image: python:3.16.0
imagePullPolicy: IfNotPresent
name: webhook
resources:
limits:
cpu: "1"
memory: 512Mi
requests:
cpu: 100m
memory: 512Mi
securityContext:
allowPrivilegeEscalation: false
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
runAsNonRoot: false
stdin: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
tty: true
volumeMounts:
- mountPath: /opt/webhook.py
name: vol2
subPath: webhook.py
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- configMap:
defaultMode: 420
items:
- key: webhook.py
path: webhook.py
name: webhook
optional: false
name: vol2
---
apiVersion: v1
kind: Service
metadata:
labels:
app: webhook
name: webhook
spec:
ports:
- name: http
nodePort: 9001
port: 80
protocol: TCP
targetPort: 8080
selector:
app: webhook
sessionAffinity: None
type: NodePort