refactor: send dingtalk notify

This commit is contained in:
ning1875 2021-07-04 18:53:33 +08:00 committed by GitHub
parent 4b9cbf9aee
commit 1f16bc9a7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 120 additions and 109 deletions

View File

@ -16,19 +16,19 @@ from email.header import Header
# 脚本二开指南 # 脚本二开指南
# 1. 可以根据下面的TEST_ALERT_JSON 中的结构修改脚本发送逻辑,定制化告警格式格式如下 # 1. 可以根据下面的TEST_ALERT_JSON 中的结构修改脚本发送逻辑,定制化告警格式格式如下
""" """
告警类型prometheus [告警类型prometheus]
规则名称pull_promql [规则名称a]
是否已恢复已触发 [是否已恢复已触发]
告警级别1 [告警级别1]
触发时间2021-06-28 11:46:35 [触发时间2021-07-02 16:05:14]
可读表达式 go_gc_duration_seconds>0 [可读表达式go_goroutines>0]
当前值[vector={__name__="go_gc_duration_seconds", instance="172.20.70.205:9100", job="node-targets", quantile="1"}]: [value=0.022498] [当前值[vector={__name__="go_goroutines", instance="localhost:9090", job="prometheus"}]: [value=33.000000]]
标签组a=b c=d instance=172.20.70.205:9100 job=node-targets quantile=1 [标签组instance=localhost:9090 job=prometheus]
""" """
# 2. 每个告警会以json文件的格式存储在LOCAL_EVENT_FILE_DIR 下面,文件名为 filename = '%d_%d_%d' % (rule_id, event_id, trigger_time) # 2. 每个告警会以json文件的格式存储在LOCAL_EVENT_FILE_DIR 下面,文件名为 filename = '%d_%d_%d' % (rule_id, event_id, trigger_time)
# 3. 告警通道需要自行定义Send类中的send_xxx同名方法反射调用举例 event.notify_channels = [qq dingding] # 3. 告警通道需要自行定义Send类中的send_xxx同名方法反射调用举例 event.notify_channels = [qq dingding] 则需要Send类中 有 send_qq send_dingding方法
# 则需要Send类中 有 send_qq send_dingding方法 # 4. im发群信息比如钉钉发群信息需要群的webhook机器人 token这个信息可以在user的contacts map中各个send_方法处理即可
# 5. 用户创建一个虚拟的用户保存上述im群 的机器人token信息 user的contacts map中
import requests import requests
mail_host = "smtp.163.com" mail_host = "smtp.163.com"
@ -47,100 +47,100 @@ mail_body = """
LOCAL_EVENT_FILE_DIR = ".alerts" LOCAL_EVENT_FILE_DIR = ".alerts"
NOTIFY_CHANNELS_SPLIT_STR = " " NOTIFY_CHANNELS_SPLIT_STR = " "
# dingding 群机器人token 配置字段
DINGTALK_ROBOT_TOKEN_NAME = "dingtalk_robot_token"
DINGTALK_API = "https://oapi.dingtalk.com/robot/send"
# stdin 告警json实例 # stdin 告警json实例
TEST_ALERT_JSON = { TEST_ALERT_JSON = {
"event": { "event": {
"alert_duration": 30, "alert_duration": 10,
"hash_id": "0c6cbe29df08bb6f9c26af518638128e", "notify_channels": "dingtalk",
"res_classpaths": "",
"id": 4,
"notify_group_objs": None,
"rule_note": "",
"history_points": [ "history_points": [
{ {
"metric": "go_gc_duration_seconds", "metric": "go_goroutines",
"points": [ "points": [
{ {
"t": 1624851995, "t": 1625213114,
"v": 0.000175 "v": 33.0
} }
], ],
"tags": { "tags": {
"instance": "172.20.70.205:9100", "instance": "localhost:9090",
"job": "node-targets", "job": "prometheus"
"quantile": "0.25"
} }
} }
], ],
"id": 190,
"is_prome_pull": 1,
"is_recovery": 0,
"last_sent": True,
"notify_channels": "qq dingding ",
"notify_group_objs": None,
"notify_groups": "",
"notify_user_objs": None,
"notify_users": "1",
"priority": 1, "priority": 1,
"readable_expression": " go_gc_duration_seconds>0", "last_sent": True,
"res_classpaths": "all",
"res_ident": "",
"rule_id": 10,
"rule_name": "pull_promql",
"rule_note": "note",
"runbook_url": "qq.com",
"status": 0,
"tag_map": { "tag_map": {
"a": "b", "instance": "localhost:9090",
"c": "d", "job": "prometheus"
"instance": "172.20.70.205:9100",
"job": "node-targets",
"quantile": "0.25"
}, },
"tags": "a=b c=d instance=172.20.70.205:9100 job=node-targets quantile=0.25", "hash_id": "ecb258d2ca03454ee390a352913c461b",
"trigger_time": 1624851995, "status": 0,
"values": "[vector={__name__=\"go_gc_duration_seconds\", instance=\"172.20.70.205:9100\", job=\"node-targets\", quantile=\"0.25\"}]: [value=0.000175]" "tags": "instance=localhost:9090 job=prometheus",
"trigger_time": 1625213114,
"res_ident": "",
"rule_name": "a",
"is_prome_pull": 1,
"notify_users": "1",
"notify_groups": "",
"runbook_url": "",
"values": "[vector={__name__=\"go_goroutines\", instance=\"localhost:9090\", job=\"prometheus\"}]: [value=33.000000]",
"readable_expression": "go_goroutines>0",
"notify_user_objs": None,
"is_recovery": 0,
"rule_id": 1
}, },
"rule": { "rule": {
"alert_duration": 30, "alert_duration": 10,
"append_tags": "a=b c=d", "notify_channels": "dingtalk",
"callbacks": "localhost:8881",
"create_at": 1624851512,
"create_by": "root",
"enable_days_of_week": "1 2 3 4 5 6 7",
"enable_etime": "23:59",
"enable_stime": "00:00", "enable_stime": "00:00",
"expression": { "id": 1,
"evaluation_interval": 3, "note": "",
"promql": " go_gc_duration_seconds>0", "create_by": "root",
"resolve_timeout": 40 "append_tags": "",
},
"group_id": 1,
"id": 10,
"name": "pull_promql",
"note": "note",
"notify_channels": "qq dingding ",
"notify_groups": "",
"notify_users": "1",
"priority": 1, "priority": 1,
"recovery_notify": 0, "update_by": "root",
"runbook_url": "qq.com",
"status": 0,
"type": 1, "type": 1,
"update_at": 1624851512, "status": 0,
"update_by": "root" "recovery_notify": 0,
"enable_days_of_week": "1 2 3 4 5 6 7",
"callbacks": "localhost:10000",
"notify_users": "1",
"notify_groups": "",
"runbook_url": "",
"name": "a",
"update_at": 1625211576,
"create_at": 1625211576,
"enable_etime": "23:59",
"group_id": 1,
"expression": {
"evaluation_interval": 4,
"promql": "go_goroutines>0"
}
}, },
"users": [ "users": [
{ {
"contacts": None, "username": "root",
"create_at": 1624258550,
"create_by": "system",
"email": "",
"id": 1,
"nickname": "\u8d85\u7ba1",
"phone": "",
"portrait": "",
"role": "Admin",
"status": 0, "status": 0,
"update_at": 1624258550, "contacts": {
"update_by": "system", "dingtalk_robot_token": "xxxxxx"
"username": "root" },
"create_by": "system",
"update_at": 1625211432,
"create_at": 1624871926,
"email": "",
"phone": "",
"role": "Admin",
"update_by": "root",
"portrait": "",
"nickname": "\u8d85\u7ba1",
"id": 1
} }
] ]
} }
@ -170,7 +170,7 @@ def main():
print(msg) print(msg)
continue continue
send_func = getattr(Send, send_func_name) send_func = getattr(Send, send_func_name)
send_func(alert_content) send_func(alert_content, payload)
def content_gen(payload): def content_gen(payload):
@ -182,30 +182,30 @@ def content_gen(payload):
type_str_m = {1: "prometheus", 0: "n9e"} type_str_m = {1: "prometheus", 0: "n9e"}
rule_type = type_str_m.get(rule_type) rule_type = type_str_m.get(rule_type)
text += "告警类型:{}\n".format(rule_type) text += "[告警类型:{}]\n".format(rule_type)
rule_name = event_obj.get("rule_name") rule_name = event_obj.get("rule_name")
text += "规则名称:{}\n".format(rule_name) text += "[规则名称:{}]\n".format(rule_name)
is_recovery = event_obj.get("is_recovery") is_recovery = event_obj.get("is_recovery")
is_recovery_str_m = {1: "已恢复", 0: "已触发"} is_recovery_str_m = {1: "已恢复", 0: "已触发"}
is_recovery = is_recovery_str_m.get(is_recovery) is_recovery = is_recovery_str_m.get(is_recovery)
text += "是否已恢复:{}\n".format(is_recovery) text += "[是否已恢复:{}]\n".format(is_recovery)
priority = event_obj.get("priority") priority = event_obj.get("priority")
text += "告警级别:{}\n".format(priority) text += "[告警级别:{}]\n".format(priority)
trigger_time = event_obj.get("trigger_time") trigger_time = event_obj.get("trigger_time")
text += "触发时间:{}\n".format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(trigger_time)))) text += "[触发时间:{}]\n".format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(trigger_time))))
readable_expression = event_obj.get("readable_expression") readable_expression = event_obj.get("readable_expression")
text += "可读表达式:{}\n".format(readable_expression) text += "[可读表达式:{}]\n".format(readable_expression)
values = event_obj.get("values") values = event_obj.get("values")
text += "当前值:{}\n".format(values) text += "[当前值:{}]\n".format(values)
tags = event_obj.get("tags") tags = event_obj.get("tags")
text += "标签组:{}\n".format(tags) text += "[标签组:{}]\n".format(tags)
print(text) print(text)
return text return text
@ -248,16 +248,27 @@ class Send(object):
print("send_wecom") print("send_wecom")
@classmethod @classmethod
def send_dingtalk(cls, payload): def send_dingtalk(cls, alert_content, payload):
# TODO 钉钉发群信息需要群的webhook机器人 token这个信息可以写在告警策略中的附加字段中 # 钉钉发群信息需要群的webhook机器人 token这个信息可以在user的contacts map中
dingtalk_api_url = "https://oapi.dingtalk.com/robot/send?access_token=xxxx"
users = payload.get("event").get("users") users = payload.get("users")
atMobiles = [x.get("phone") for x in users]
for u in users:
contacts = u.get("contacts")
dingtalk_robot_token = contacts.get(DINGTALK_ROBOT_TOKEN_NAME, "")
if dingtalk_robot_token == "":
print("dingtalk_robot_token_not_found")
continue
dingtalk_api_url = "{}?access_token={}".format(DINGTALK_API, dingtalk_robot_token)
atMobiles = [u.get("phone")]
headers = {'Content-Type': 'application/json;charset=utf-8'} headers = {'Content-Type': 'application/json;charset=utf-8'}
payload = { payload = {
"msgtype": "text", "msgtype": "text",
"text": { "text": {
"content": payload "content": alert_content
}, },
"at": { "at": {
"atMobiles": atMobiles, "atMobiles": atMobiles,