Zabbix 5.0.2调用企业微信API实现报警消息微信通知

目录 编程, 运维

Zabbix原生就支持了非常多的消息通知类型,但大部分因为地区的原因根本无法使用,就算是可用的Email,手机短信这类消息通知方式也因为通知不够明显或会产生额外的费用导致不太实用。

不过非常幸运的是,除了自带的这些消息通知,它也可以通过脚本去自定义监控媒介。可以利用企业微信中消息推送API去实现报警消息直接推送到个人或多人微信的这样的功能。

直入主题

首先我们需要注册一个企业微信,这个注册个人也能通过,并不会产生什么成本。

注册完成并登录后,前往应用管理项,创建一个应用,名称和Logo随意即可。

创建完应用后,点击进入应用,我们需要获取应用的AgentId和Secret,AgentId直接就可以在页面上获取,但Secret不行,直接点击Secret的查看按钮,这时提示需要安装手机版企业微信,按提示下载登录后点击发送即可。

注意:企业微信后续可以关联微信,整个流程走完后就可以删除企业微信。

切换到通讯录项展开菜单,记住部门ID的编号。比如我这里编号为1

注意:你可以创建多个部门,将不同系统的运维人员拉入不同的部门来实现消息的指定推送

然后前往“我的企业”获取企业ID。现在我们手里有AgentId,Secret,企业ID和部门编号这4个参数,后续都会用上。

编写调用企业微信API接口代码

首先进入Zabbix终端,在终端中安装nodejs环境。

调用Api任何开发语言都可以做到,甚至直接用shell使用curl来实现发送功能,但是shell处理编码会非常棘手,遇到空格时消息也会被分割开,转译又非常的麻烦,所以使用nodejs来实现

apt-get install node npm -y && npm i axios

演示使用Debian10系统,CentOS7请使用yum install nodejs -y,CentOS8使用dnf install nodejs -y

安装完成后。创建脚本,赋予执行权限,并使用vim打开。

cd /lib/zabbix/alertscripts && \
touch WeChat.js && \
chmod +x WeChat.js && \
vim WeChat.js

开始编写API调用代码。

编写调用企业微信API接口代码

更改代码中的重要参数为你的AgentId,Secret,企业ID和部门编号

#!/usr/bin/env node
const axios = require("axios");
​
/**
 * logPath    -> 日志路径
 * id         -> 企业id
 * Secret     -> Secret
 */
const logPath = "/home/zabbix/wechat.log";
const id = "..............";
const secretId = "..............";
​
/**获取调用时传递的参数,在Zabbix中调用时直接WeChat.js <要发送的信息> process.argv[2]取的就是这个要发送的信息*/
var content = process.argv[2];
if(!content){return false};
​
axios.get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + id + "&corpsecret=" + secretId)
.then((res) =>{
  
  /**获取返回的token,需要携带这个token去调用下一个api*/
  let token =res.data.access_token;
  if (!token) {return false};
  
  axios.post("https://qyapi.weixin.gq.com/cgi-bin/message/send?access_token=" + token,{
    touser: "@all",
    toparty: "1",               //部门id
    msgtype: "text",            //发送的消息类型
    agentid: "1000002",         //应用id
    text: {
      content: content          //发送的内容
    },
    safe: 0
  });
});

完成后保存退出。

将企业微信的消息推送到个人微信

虽然微信用户有12亿,但是企业微信不是人人都装的,所以为了便利性,我们需要将企业微信的消息直接推送到个人微信上

现在回到企业微信网页端,转到我的企业,选择微信插件。

将页面移动下去,有一个邀请关注,用微信扫描这个二维码。后续的通知都会从微信上显示,如果需要让其他人也收到推送信息,直接分享二维码即可。

测试消息通知

完成上面这些步骤后,我们就可以进行消息推送的测试

./WeChat.js test

执行如上命令,WeChat.js后跟随的test就是需要推送的消息。

顺利接收。

注意:如果无法接收,请检查4样参数是否正确,该脚本不需要做额外的防火墙策略,只要能出站即可。你也可以检查程序运行的日志文件来查看调用结果。

创建消息媒介

消息推送的脚本已经创建完毕,接下来需要在Zabbix上设置自定义消息媒介

点击左侧菜单 管理-报警媒介类型 点击创建媒介类型。

将名称设置为WeChatAlert或者其它的也可以,类型选择脚本。名称选择WeChat.js,脚本参数填写{ALERT.MESSAGE}。

 

接下去点击菜单栏左侧 User settings – Profile 。切换到报警媒介卡,添加一个报警媒介,类型选择WeChatAlert,收件人随意填写因为没有做这方面接口,这个值是无效的。当启用时就默认,如果存在严重性就按图上勾即可,当然你也可以全部勾上。

消息发送实战

在Zabbix中报警消息是通过,监控项 -> 触发器 -> 动作这样的流程来进行发送的。首先定时获取监控项的值,在经过触发器判断,如果触发报警就会进行动作,在动作中做好消息发送即可。

键值选择system.run也就是运行命令,命令如下

sudo ps -ef | grep nginx | grep -v grep | wc -l

意思是用ps命令输出正在执行的进程列表,在用grep命令匹配出名字中带有nginx的进程,在反向过滤掉带有grep的进程信息,接着使用wc命令输出匹配到的行数,只要值大于等于2就说明nginx正常运行。为什么大于等于2而不是大于0?因为这和nginx的进程模型有关,nginx采用多进程模型,一个master进程去管理多个worker进程,正常情况下就应该有2个进程存在,默认配置情况下worker进程数量于cpu逻辑核心有关,所以是大于等于2。

进行监控项测试。

接下来进行触发器的创建,当前一个监控项值小于2时,触发这个触发器。

菜单栏左侧选择 配置 – 动作 – Trigger actions创建一个动作,条件选择刚刚的监控项。

创建一个操作,首先是通过自定义媒介推送告警信息给手机微信。在弹出的操作细节中,Operation选择发送消息选项,Send to users选择当前的admin用户。勾选Custom message。主题填写为

服务器:{HOSTNAME1}Zabbix Server Web Nginx进程未启动!
告警主机:{HOSTNAME1}
告警时间:{EVENT.DATE}{EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息:{TRIGGER.NAME}
告警项目:{TRIGGER.KEY1}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
当前状态:{TRIGGER.STATUS}:{ITEM.VALUE1}
事件ID:{EVENT.ID}

{}内为变量,具体含义看中文即可。我的只做参考,具体想怎样写都可。完成后点击保存即可。

在管理 -> 脚本 创建一个恢复脚本,当剩余进程大于0时,进行平滑重启,避免残余进程导致端口冲突。当进程数等于0时,直接启动。

回到添加动作的页面中,在发送消息下,在添加一个操作,执行进程恢复脚本,目标列表选择当前主机。

接下来在恢复操作块在添加一个操作细节,Operation选择发送消息,发送用户依旧admin,仅送到WeChatAlert。主题和消息填写恢复后需要发送的内容。以下是我的例子

服务器:{HOSTNAME1}Zabbix Server Web Nginx进程已启动!
告警主机:{HOSTNAME1}
告警时间:{EVENT.DATE}{EVENT.TIME}
告警等级:{TRIGGER.SEVERITY}
告警信息:{TRIGGER.NAME}
告警项目:{TRIGGER.KEY1}
问题详情:{ITEM.NAME}:{ITEM.VALUE}
当前状态:{TRIGGER.STATUS}:{ITEM.VALUE1}
事件ID:{EVENT.ID}

完成后保存,保存一直保存到底。

手动关闭Nginx服务后接收到报警信息并自动运行恢复脚本,待下一次监控数据正常后发送恢复信息。