使用回调方式(Webhook)发送告警消息
虽然夜莺已经内置了多种通知方式,但是有些用户可能有自己的通知系统,或者有些用户希望把告警消息推送到第三方系统,这时候就需要使用回调方式(Webhook)发送告警消息。
Webhook 就是一个 HTTP API 地址,夜莺产生告警事件之后,就会通过 POST 方式调用这个 API,把告警事件详情放到 HTTP Request Body 中,如此便实现了监控系统与第三方系统之间的联动。
比如电话通道,不同的公司可能使用不同的通知方式,你们公司的电话通知接口和其他公司的电话通知接口可能是不同的,夜莺无法兼容如此多的通知方式。此时,你就可以自己搞一个 HTTP Server 提供一个 API 配置到夜莺 Webhook 中,这样夜莺产生告警事件之后就会调用你的 API,你就可以在自己的 API 中拿到告警事件详情,然后调用自己公司的电话通知接口。
OK,原理如上。此时你可能会有疑问,夜莺把告警事件的详情放到 HTTP Request Body 中推给我,那这个格式具体是什么样的呢?实际上,这个数据结构就是 alert_cur_event 这个结构体的 JSON 序列化结果。
还是弄不懂?没关系,我们来看一个实际的例子。
夜莺V7版本,菜单入口:告警通知
- 通知设置
- 回调地址
,页面上方其实已经给了一个说明,内容如下:
回调机制,用于夜莺和其他系统之间的集成。夜莺产生告警事件之后,会推送给各个回调地址,您可以自己开发一个 HTTP API 配置到这里,接收夜莺告警事件,进而做一些自动化的、定制化的逻辑。夜莺回调时使用的 HTTP 方法是 POST,会把告警事件的内容以 JSON 格式放到 HTTP Request Body 中,事件数据结构请参考这里。您可以找一台和夜莺网络互通的机器(假设其 IP 是 10.1.2.3),在上面用 nc 起一个端口,比如
nc -k -l 4321
即可用 nc 监听在 4321 端口,然后您把 http://10.1.2.3:4321 配置到回调地址里,然后去创建个告警规则,一旦触发,夜莺就会回调这个地址,您就可以在 nc 命令的输出中看到夜莺回调过来的详细数据格式了。
现在我在自己的环境里做个测试演示。首先找一台和夜莺网络互通的机器,其 IP 是:10.211.55.3,然后在上面用 nc 起一个端口,比如 nc -k -l 4321
如下:
root@ubuntu-linux-22-04-desktop:~/tmp# nc -k -l 4321
然后我把 http://10.211.55.3:4321
配置到回调地址里,回调地址有两个地方可以配置,一个是全局的,在 告警通知
- 通知设置
- 回调地址
,所有告警事件产生之后都会调用这里的回调地址。另一个是在告警规则里,是规则颗粒度的,只有这个规则产生的告警事件才会调用这个回调地址。我这里姑且配置到规则里,创建一个告警规则,回调地址配置如下:
稍等片刻,就可以在 nc 命令的输出中看到夜莺回调过来的详细数据格式了:
我这个告警规则生成了两条告警事件,所以触发了两次回调,我把其中一次回调的 JSON 拿出来,如下:
{
"id": 16,
"cate": "prometheus",
"cluster": "xxx",
"datasource_id": 1,
"group_id": 1,
"group_name": "Default Busi Group",
"hash": "0188b06deaa5eb24832548d599090f2b",
"rule_id": 4,
"rule_name": "测试回调地址",
"rule_note": "",
"rule_prod": "metric",
"rule_algo": "",
"severity": 2,
"prom_for_duration": 0,
"prom_ql": "system_load_norm_5 \u003e 0",
"rule_config": {
"queries": [
{
"keys": {
"labelKey": "",
"valueKey": ""
},
"prom_ql": "system_load_norm_5 \u003e 0",
"severity": 2
}
]
},
"prom_eval_interval": 15,
"callbacks": [
"http://10.211.55.3:4321"
],
"runbook_url": "",
"notify_recovered": 1,
"notify_channels": [
"email"
],
"notify_groups": [
"2"
],
"notify_groups_obj": [
{
"id": 2,
"name": "测试邮件告警的团队",
"note": "",
"create_at": 1708921626,
"create_by": "root",
"update_at": 1708948109,
"update_by": "root"
}
],
"target_ident": "ulric-flashcat.local",
"target_note": "",
"trigger_time": 1708999492,
"trigger_value": "0.7229",
"trigger_values": "",
"tags": [
"__name__=system_load_norm_5",
"ident=ulric-flashcat.local",
"rulename=测试回调地址"
],
"tags_map": {
"__name__": "system_load_norm_5",
"ident": "ulric-flashcat.local",
"rulename": "测试回调地址"
},
"annotations": {
},
"is_recovered": false,
"notify_users_obj": [
{
"id": 3,
"username": "n9e-wecom-robot",
"nickname": "夜莺V7群机器人",
"phone": "",
"email": "",
"portrait": "",
"roles": [
"Guest"
],
"contacts": {
"wecom_robot_token": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=x"
},
"maintainer": 0,
"create_at": 1708945529,
"create_by": "root",
"update_at": 1708945529,
"update_by": "root",
"admin": false
},
{
"id": 4,
"username": "n9e-ding-robot",
"nickname": "钉钉机器人",
"phone": "",
"email": "",
"portrait": "",
"roles": [
"Guest"
],
"contacts": {
"dingtalk_robot_token": "https://oapi.dingtalk.com/robot/send?access_token=x"
},
"maintainer": 0,
"create_at": 1708948099,
"create_by": "root",
"update_at": 1708948099,
"update_by": "root",
"admin": false
},
{
"id": 1,
"username": "root",
"nickname": "超管",
"phone": "",
"email": "",
"portrait": "",
"roles": [
"Admin"
],
"contacts": {
},
"maintainer": 0,
"create_at": 1708920315,
"create_by": "system",
"update_at": 1708920315,
"update_by": "system",
"admin": true
},
{
"id": 2,
"username": "qinxiaohui",
"nickname": "秦晓辉",
"phone": "",
"email": "qinxiaohui@flashcat.cloud",
"portrait": "",
"roles": [
"Standard"
],
"contacts": {
},
"maintainer": 0,
"create_at": 1708921503,
"create_by": "root",
"update_at": 1708921503,
"update_by": "root",
"admin": false
}
],
"last_eval_time": 1708999492,
"last_sent_time": 1708999492,
"notify_cur_number": 1,
"first_trigger_time": 1708999492,
"extra_config": null,
"status": 0,
"claimant": "",
"sub_rule_id": 0,
"extra_info": null
}
大家可以对照 alert_cur_event 这个结构体来查看,这个 JSON 就是这个结构体的 JSON 序列化结果。
之后,你就可以在自己的 API 中做一些自动化的、定制化的逻辑了。想怎么定制通知内容就怎么定制,想调用内部什么通知接口就调用什么通知接口。