将 ChatGPT 接入 Zabbix 为告警提供修复建议(对接钉钉)

1、如果接企业微信请参考下面的文章

https://www.txisfine.cn/archives/9c078bb7.html

 

感谢上述文章的作者提供的思路

  ChatGPT 是最近很火的 AI 智能机器人程序,2 个月活跃用户突破 1 亿,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,真正像人类一样来聊天交流,甚至能完成撰写邮件、视频脚本、文案、翻译、代码,写论文等任务。

   Zabbix 开源社区推文 实测|ChatGPT 对 Zabbix 用户有什么影响? 展示了将一些 Zabbix 相关的问题丢给 ChatGPT 处理来提升工作效率。既然都说到这里了,那我们能不能将 Zabbix 告警信息丢给 ChatGPT,在告警的第一时间先给出一份可以参考的建议呢?
  所以,基于 Zabbix 能力,我们将告警发给了 ChatGPT,并通过钉钉发送的方式给出告警信息和修复建议。效果如下图:
 

 

 001、准备

  • 注册 ChatGPT 账号
  • 注册 AirCode 账号
  • 准备 Zabbix 钉钉内部应用

因为需要接入 ChatGPT,必须要现有一个 OpenAI 的账号,AirCode 是一个 nodejs 运行时的 Serverless 平台,主要做 OpenAI 的 APIProxy,因为毕竟是国际服务,网络抖动会影响服务质量。

如何注册网络上很多资料,这里不在赘述。

还要准备一个 Zabbix 钉钉内部应用,用来接受告警和建议

 

 002、开始

获取 OpenAI 的 KEY

 登录到 OpenAI,访问Account API Keys - OpenAI API,点击 Create new secret key,创建一个新的 key,并保存备用。
 

 

 创建一个 AirCode 项目

登录到 AirCode,创建一个新项目。

 

 

给项目命名一下,Runtime 和 Region 默认就好,点击 Create 进入编辑区。

 1.创建一个文件,比如 main.js,将 bh1xaq/ChatGPT-zabbixAlert 中的 openai.js 拷贝进去。
 

 

 2.安装 axios 依赖,在 Dependencies 下面搜axios,找最新版本安装即可。

 

3.配置环境变量,我们需要把 OpenAI 的 KEY 配置到环境变量,同时为了您的 API 更安全,我们还需要协商一个 Zabbix 请求我们 APIProxy 的 KEY。

 

OPENAIKEY - 获取到的 OpenAI 的 KEY
ZAKEY - Zabbix 请求 APIProxy 的 KEY(需要自定义)

4.发布代码,并获得 APIProxy 地址备用。点击 Deploy,填写 Commit,发布代码。下面红框的位置就是 APIProxy 地址。

 

 

 

配置 Zabbix 通知媒介

1.登录 Zabbix 管理端,选择报警媒介类型创建媒体类型。 

 

 类型:WebHook

参数:

  • Zakey:Zabbix 请求 APIProxy 的 KEY
  • Openaiurl: OpenAI APIProxy 地址
  • Message:{ALERT.MESSAGE}
  • Subject:{ALERT.SUBJECT}
  • To:{ALERT.SENDTO}

超时时间:60s

 粘贴脚本,将 下面的代码拷贝到 脚本 中。需要修改的部分已经标红

复制代码
var weworkApp = {
    // 
    touser: null,
    // 
    message: null,
    // 
    proxy: null,
    // 
    openai_url: null,
    // Zakey
    zakey: null,
    
    msgtype: 'markdown',

    // 获取钉钉 AccessToken
    getAccessToken: function () {
        var url = 'https://oapi.dingtalk.com/gettoken?appkey=************&appsecret=*******************',
            request = new CurlHttpRequest();

        // 设置代理
        if (weworkApp.proxy) {
            request.setProxy(weworkApp.proxy);
        }
        request.AddHeader('Content-Type: application/json');
        response = request.Get(url);
        try {
            response = JSON.parse(response);
            return response.access_token;
        }
        catch (error) {
            response = null;
        }
        if (request.Status() !== 200 || response.errcode !== 0) {
            if (typeof response.errmsg === 'string') {
                throw response.errmsg;
            }
            else {
                throw 'Unknown error. Check debug log for more information.'
            }
        }
    },
    // 不用修改
    askOpenAI: function (quesion) {
        // OpenAI Proxy On AirCode
        var url = weworkApp.openai_url,
            request = new CurlHttpRequest(),
            data = {
                "zakey": weworkApp.zakey,
                "quesion": quesion
            };

        // 设置代理
        if (weworkApp.proxy) {
            request.setProxy(weworkApp.proxy);
        }
        request.AddHeader('Content-Type: application/json');
        response = request.Post(url, JSON.stringify(data));
        try {
            response = JSON.parse(response);
        }
        catch (error) {
            response = { message: "" };
        }
        return response.message;
    },

    // 发消息
    sendMessage: function (access_token) {
        var params = {
            chatid: weworkApp.touser,
            msgtype: weworkApp.msgtype,
            markdown: {
                title: "Zabbix通知",
                text: weworkApp.message
            },
            enable_duplicate_check: 1,
            duplicate_check_interval: 20
        },
            data,
            response,
            request = new CurlHttpRequest(),
            url = 'https://oapi.dingtalk.com/chat/send?access_token=' + access_token;

        // 设置代理
        if (weworkApp.proxy) {
            request.setProxy(weworkApp.proxy);
        }

        request.AddHeader('Content-Type: application/json');
        data = JSON.stringify(params);

        // 在日志中不展示 AccessToken
        Zabbix.Log(4, '[weworkApp Webhook] URL: ' + url.replace(weworkApp.access_token, '<ACCESS_TOKEN>'));
        Zabbix.Log(4, '[weworkApp Webhook] params: ' + data);
        response = request.Post(url, data);
        Zabbix.Log(4, '[weworkApp Webhook] HTTP code: ' + request.Status());

        try {
            response = JSON.parse(response);
        }
        catch (error) {
            response = null;
        }

        if (request.Status() !== 200 || response.errcode !== 0) {
            if (typeof response.errmsg === 'string') {
                throw response.errmsg;
            }
            else {
                throw 'Unknown error. Check debug log for more information.'
            }
        }
    }
}

try {
    var params = JSON.parse(value);
    if (params.HTTPProxy) {
        weworkApp.proxy = params.HTTPProxy;
    }
    weworkApp.corpid = params.Corpid;
    weworkApp.corpsecret = params.Corpsecret;
    weworkApp.touser = params.To;
    weworkApp.openai_url = params.Openaiurl;
    weworkApp.zakey = params.Zakey;
    var access_token = weworkApp.getAccessToken();
    weworkApp.message = params.Subject + '\n' + params.Message;

    //如果是故障类型的通知,就问一下 OpenAI
    if (params.Subject.indexOf("故障恢复") == -1) {
        var aiAnswer = weworkApp.askOpenAI(params.Subject);
        weworkApp.message = weworkApp.message + '\n --- \n OpenAI - 砖家建议 - 众所周知砖家建议仅供参考):\n ' + aiAnswer;
    }
    // 发钉钉通知
    weworkApp.sendMessage(access_token);
    return '200 OK';
}
catch (error) {
    Zabbix.Log(4, '[weworkApp Webhook] notification failed: ' + error);
    throw 'Sending failed: ' + error + '.';
}
复制代码

 

 

 

 

2.创建消息模板。

添加故障和故障恢复两个类型的消息。以下供参考。

复制代码
故障: {EVENT.NAME}
定位ID:{EVENT.ID}
出现时间:{EVENT.DATE} {EVENT.TIME}
所属设备:{HOST.NAME}
严重程度:{EVENT.SEVERITY}
{TRIGGER.URL}

故障恢复:{EVENT.RECOVERY.NAME}
定位ID:{EVENT.ID}
恢复时间:{EVENT.RECOVERY.DATE} {EVENT.RECOVERY.TIME} 
故障时长:{EVENT.DURATION}
影响设备:{HOST.NAME}
严重程度:{EVENT.SEVERITY}
{TRIGGER.URL}
复制代码

保存即可,我们可以进行一下测试。

 

 

 

 

3.告警信息定向推送给谁,需要一个 TOUSER 的属性,在这里添加即可。

 4.将报警媒介关联到触发器动作中。

 

zabbix 特别注意:

{ALERT.SUBJECT} 相当于 动作的主题

在zabbix里面把动作的主题配置成 故障: {EVENT.NAME}。这样访问chatapi的时候就能返回想要的信息

 

 

 

 特别说明 

AI 无法代替人类,提供的建议仅供修复参考,请运维工程师分析合理性后进行执行,以防止扩大故障。

本项目使用的 OpenAI 模型为 text-davinci-003。 

 
 
posted @   Hello_worlds  阅读(1208)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示