Deepseek 对接 Zabbix

in 默认分类 with 0 comment

2025-03-04T06:55:16.png

前提条件

Windows 11 安装Ollama,部署deepseek-r1:14b模型;
centos 7中安装zabbix 7.0;

实验目的及效果

本文旨在使用Deepseek-r1:14b模型与Zabbix对接,最终实现效果为Zabbix 接收告警提示,Deepseek模型对出现告警进行分析并提出解决措施。实现方式为:Zabbix内部查看及钉钉webhook机器人发送告警及分析发送。由于参考连接中所缺省步骤较多,所以对两篇文档中缺少部分进行补充。

Zabbix内部查看参考:Zabbix告警分析新纪元:本地DeepSeek大模型实现智能化告警分析
钉钉webhook机器人发送告警及分析发送参考:Zabbix 运维监控系统对接ollama deepseek

Zabbix内部查看

整个部署过程如下图所示:
2025-03-04T07:04:14.png

由于本人是用Windows 11 部署 ollama,实现方式与参考文档不同,如需查看部署方式可参考本站Deepseek+Dify+Chatbox应用及Dify配置,此处将略过部署。

在上述的两种实现方式中最为重要的是将Zabbix所在机器的SELinux和防火墙关闭(或防火墙可以只开只需要的端口),否则将出现脚本或Scripts没有问题但执行时出现各种报错。(特别是SELinux)

配置Webhook

在Zabbix控制台中创建新的Webhook脚本,具体步骤如下:

登录Zabbix控制台,点击“Alerts”->“Scripts”点击"Create script"按钮,填写以下内容
2025-03-04T07:14:52.png

Name: 解决方案
Scope: Manual event action
Menu path: AI助手
Type: Webhook
Parameters: name:detail value: {TRIGGER.NAME},name: host value: {HOST.HOST}
2025-03-04T07:15:13.png

在Script body中粘贴如下内容:

// 配置信息
var OLLAMA_API_URL = 'http://192.168.X.X:11434/api/chat' /*此为部署Ollama 的服务器的IP地址:11434,此api在web页面中直接访问将出现404,但不影响使用。此api所耗本人时间最长,如未关闭SELinux,则会出现各种报错。*/
var MODEL_NAME = 'deepseek-r1:14b'    /*此为在部署Ollama后所下载并能正常运行的deepseek-r1模型名称,如有多个模型则需要确定使用哪个。*/

/**
 * 生成告警消息
 * @param {Object} params - Zabbix 告警参数
 */
function generateAlertMessage(params) {
   
    return [
        '当前服务器告警,主机: ' + params.host,
        '详情: ' + params.detail,
        '请执行:1. 根本原因分析(概率排序)2. 提供修复命令3. 关联知识文档',
    ].join('\n')
}

/**
 * 发送消息到 Ollama Chat API
 * @param {string} message - 要发送的消息
 */
function sendToOllama(message) {
   
    try {
   
        // 准备请求数据
        var payload = JSON.stringify({
   
            model: MODEL_NAME,
            messages: [
                {
   
                    role: 'user',
                    content: message,
                },
            ],
            stream: false,
        })

        // 记录请求日志
        Zabbix.Log(4, '[Ollama Webhook] 发送请求: ' + payload)

        // 发送请求
        var response = new HttpRequest()
        //response.addHeader('Content-Type: application/json')
        var responseData = response.post(OLLAMA_API_URL, payload)

        // 检查响应
        if (response.getStatus() != 200) {
   
            throw new Error('API 请求失败,状态码: ' + response.getStatus())
        }
        // 记录成功日志
        Zabbix.Log(4, '[Ollama Webhook] 发送成功: ' + responseData)

        try {
   
            var result = JSON.parse(responseData)
            // chat API 返回的是 message 对象
            return result.message.content || '成功发送到 Ollama'
        } catch (e) {
   
            return '成功发送到 Ollama(响应解析失败): ' + e.message
        }
    } catch (error) {
   
        // 记录错误日志
        Zabbix.Log(3, '[Ollama Webhook] 错误: ' + error.message)
        throw error
    }
}

/**
 * Webhook 主函数
 */
try {
   
    // 验证必要的输入参数
    if (!value) {
   
        throw new Error('未收到告警信息')
    }

    Zabbix.Log(4, '[Ollama Webhook] 收到告警信息: ' + value)

    // 构造告警消息
    var params
    try {
   
        params = JSON.parse(value)
    } catch (e) {
   
        throw new Error('告警信息格式无效: ' + e.message)
    }

    // 生成并发送告警消息
    var alertMessage = generateAlertMessage(params)
    var response = sendToOllama(alertMessage)

    // 返回处理结果
    return '模型分析结果:\n' + response
} catch (error) {
   
    // 返回错误信息
    return '处理告警时出错: ' + error.message
}

设置Timeout为60s(此为关键,因为从zabbix到deepseek到返回分析,时间均超过默认30s,所以需设置时间60s,已免出现响应时间超过设定秒数导致回答错误)

原文中的超时优化本文未做,所以跳过。

告警分析实践
当Zabbix产生一个告警后,在问题上点击右键选择AI助手-解决方案,就会把此问题发送给Deepseek平台。
2025-03-04T07:23:45.png
2025-03-04T07:24:30.png

钉钉webhook机器人发送告警及分析发送

整个部署过程如下图所示:
2025-03-04T08:34:40.png

前提条件:
由于参考文档使用的是企业微信发送告警及恢复信息,以下内容关于python脚本部分为本人查询资料拼凑所得,可以根据实际情况选择原文档中的企业微信Python 脚本或下面钉钉Python 脚本。

在需发送群中创建钉钉机器人并获取webhook和安全设置加密密钥。
2025-03-04T07:35:51.png

如在Zabbix中运行python脚本出错,可参考以下文档:
可查看本站:配置Zabbix告警- 飞书机器人报警

在Zabbix中进行安装requests模块及Python3-pip

安装pip工具和安装requests模块
1、首先检查Linux有没有安装Python3-pip包,直接执行

[root@localhost ~]#yum install python3-pip

2、没有python3-pip包就执行命令

[root@localhost ~]#yum -y install epel-release

3、执行成功之后,再次执行

[root@localhost ~]#yum install python3-pip

可以使用python --version 和python3 --version 查看python版本号。注意:该脚本要求至少python2以上版本,且具有requests模块.否则会报错:

Traceback (most recent call last):
  File "./feishu.py", line 2, in <module>
    import requests
ImportError: No module named requests

解决办法:
进入到/usr/bin/文件夹下运行

[root@localhost ~]#cd /usr/bin/
[root@localhost bin]# pip3 install requests /*安装requests模块*/

此时运行Python 脚本的环境安装完毕。

创建脚本
脚本命名为aiwebhook.py

[root@localhost ~]#cd /usr/lib/zabbix/alertscripts/
[root@localhost alertscripts]#vi aiwebhook.py


#!/usr/bin/env python3
# -*- coding: utf-8 -*-     /*此二句为调用声明,不是注释,无此两句下面运行时将报错*/

import sys
import json
import requests
import time
import hmac
import hashlib
import base64
import urllib.parse

class DingtalkBot:
    def __init__(self, access_token, secret):
        self.access_token = access_token
        self.secret = secret

    def generate_signed_url(self):
        timestamp = str(round(time.time() * 1000))
        secret_enc = self.secret.encode('utf-8')
        string_to_sign = f"{timestamp}\n{self.secret}"
        string_to_sign_enc = string_to_sign.encode('utf-8')
        hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
        sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
        return f"https://oapi.dingtalk.com/robot/send?access_token={self.access_token}&timestamp={timestamp}&sign={sign}"

    def send_markdown(self, subject, content, ai_response):
        url = self.generate_signed_url()
        data = {
            "msgtype": "markdown",
            "markdown": {
                "title": "服务器告警通知",
                "text": (
                    "### 告警主题\n" + subject +
                    "\n\n### 详情\n```\n" + content + "\n```" +
                    "\n\n### AI分析\n" + ai_response
                )
            }
        }
 headers = {'Content-Type': 'application/json'}
        try:
            response = requests.post(url, json.dumps(data), headers=headers, timeout=10)
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            print(f"钉钉消息发送失败: {str(e)}")
            return None

class OllamaClient:
    def __init__(self, host='http://192.168.X.X:11434', timeout=60):  /*重中之重,设置Ollama 所在IP地址:11434,时间设置为60s,原因同上*/
        self.host = host
        self.timeout = timeout

    def get_ai_response(self, prompt):
        try:
            response = requests.post(
                f"{self.host}/api/chat",         (api后缀)
                json={
                    "model": "deepseek-r1:14b",       (所下载模型名称)
                    "messages": [{"role": "user", "content": prompt}],
                    "stream": False
                },
                timeout=self.timeout
            )
            response.raise_for_status()
            return response.json()['message']['content']
        except Exception as e:
            return f"AI分析超时或错误: {str(e)}"

if __name__ == '__main__':
    # 参数接收(示例:python script.py "Subject" "Content")
    subject = sys.argv[1]
    content = sys.argv[2]

 # 初始化服务
    dingtalk = DingtalkBot(
        access_token="X",    /* 此处替换为webhook URL中access-token,而不是整个webhook URL*/
        secret="SX"               /* 替换为加签密钥*/
    )
    ollama = OllamaClient()

    # 获取AI分析
    ai_prompt = "你是一个专业的IT工程师,简短简洁地分析以下告警原因并提供处理措施(100字内):\n" + content
    ai_response = ollama.get_ai_response(ai_prompt)

    # 发送到钉钉
    dingtalk.send_markdown(subject, content, ai_response)
    print("执行完毕")

赋予此脚本执行权限
[root@localhost alertscripts]#chmod +x aiwebhook.py

配置zabbix 服务器:
在【告警】->【媒介】->【创建媒介类型】
2025-03-04T08:04:36.png

名称 aiwebhook
类型 脚本
脚本名称 aiwebhook.py
脚本参数
{ALERT.SUBJECT}
{ALERT.MESSAGE}
描述
钉钉ai报警

2025-03-04T08:05:32.png

消息类型 问题
主题 告警通知
消息
主机:{HOST.NAME}
地址:{HOST.IP}
项目:{ITEM.NAME}
取值:{ITEM.LASTVALUE}
等级:{TRIGGER.SEVERITY}
状态:{TRIGGER.STATUS}
信息:{TRIGGER.NAME}
时间:{EVENT.DATE} {EVENT.TIME}
事件ID:{EVENT.ID}

2025-03-04T08:23:58.png

消息类型 问题恢复
主题 恢复通知
消息
主机:{HOST.NAME}
地址:{HOST.IP}
项目:{ITEM.NAME}
取值:{ITEM.LASTVALUE}
等级:{TRIGGER.SEVERITY}
状态:{TRIGGER.STATUS}
信息:{TRIGGER.NAME}
时间:{EVENT.DATE} {EVENT.TIME}
事件ID:{EVENT.ID}

2025-03-04T08:24:15.png

配置如下图所示:
2025-03-04T08:27:31.png
创建触发动作
选择【告警】->【动作】->【触发器动作】,【触发器示警度】大于等于【告警】;
2025-03-04T08:28:22.png
2025-03-04T08:28:42.png
操作选择【发送消息】,【发送给用户组】选择【zabbix administrator】,仅发送【aiwebhook】
2025-03-04T08:29:10.png
恢复操作选择【发送消息】,【发送给用户组】选择【zabbix administrator】,仅发送【aiwebhook】
2025-03-04T08:29:27.png

上述配置完成后,在【用户】中选择【用户】,选择【Admin】;
2025-03-04T08:00:52.png
点击【报警媒介】;
2025-03-04T08:01:05.png
报警媒介中类型选择【aiwebhook】,收件人选择【all】,启用时长任意设置。
2025-03-04T08:01:20.png
2025-03-04T08:01:56.png
最终效果
如出现problem 则会通过钉钉发送报警提示并给出AI分析,下图所示:
2025-03-04T08:02:58.png
恢复后则如下图所示:
2025-03-04T08:48:55.png

Responses