获取zabbix API 监控数据shell脚本,自动日常巡检服务器信息、并发送指定群组

一,前言

有zabbix监控,也并不是时刻盯着数据,所以想着,每天固定某个时刻,自动发送服务器数据到指定群组,给其他人更直观的数据。

数据就可以从zabbix API获取。参考官方API文档:https://www.zabbix.com/documentation/current/zh/manual/api

二,功能实现

主要功能概览

  1. 获取cpu和内存的数据(可根据实际情况添加其他监控项数据)。
  2. 只需要24小时内,最大,最小,平均数据。
  3. 只获取群组为prod的主机服务器,意味着生产环境。
    需要获取主机,在zabbix分到同一个组,方便获取所有主机信息。

代码步骤概览

  1. 获取 Zabbix 认证 Token(登录有权限的账户)。
    user.login方法,获取Token。需要注意的是,由于安装版本不同,API链接可能不同,如有些是https://example.com/zabbix/api_jsonrpc.php,有些是https://example.com/api_jsonrpc.php
  2. 获取指定群组中的所有主机,获取群组ID。
    hostgroup.get方法,获取群组ID
  3. 获取群组内所有主机,host.get方法。
  4. 遍历每个主机,获取CPU和RAM的监控项,获取需要监控项的itemID,item.get方法。
  5. 通过 监控项的itemID,获取历史数据记录,history.get方法。
  6. 计算将结果通过媒体发送到指定群组(这里为TG群组)。

三,代码实现

这里使用shell脚本

powershell 复制代码
#!/bin/bash

# 信息验证
ZABBIX_URL="https://zabbix.example.com/api_jsonrpc.php"
ZABBIX_GROUP="prod"  # 指定的服务器群组名称
ZABBIX_USER="Admin"
ZABBIX_PASS="passoword"

# TG 群组token和ID
TELEGRAM_BOT_TOKEN="5487418237:AAGibU......."
TELEGRAM_CHAT_ID="-452112...."

# 登录并获取zabbix token
AUTH_TOKEN=$(curl -s -X POST -H 'Content-Type: application/json' -d '{
    "jsonrpc": "2.0",
    "method": "user.login",
    "params": {
        "user": "'$ZABBIX_USER'",
        "password": "'$ZABBIX_PASS'"
    },
    "id": 1
}' $ZABBIX_URL | jq -r '.result')
#echo $AUTH_TOKEN

# Step 1: 获取群组ID
GROUP_ID=$(curl -s -X POST -H 'Content-Type: application/json' -d '{
    "jsonrpc": "2.0",
    "method": "hostgroup.get",
    "params": {
        "output": "extend",
        "filter": {
            "name": ["'$ZABBIX_GROUP'"]
        }
    },
    "auth": "'$AUTH_TOKEN'",
    "id": 1
}' $ZABBIX_URL | jq -r '.result[0].groupid')
#echo $GROUP_ID

# Step 2: 获取群组内所有主机
HOSTS=$(curl -s -X POST -H 'Content-Type: application/json' -d '{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
        "output": ["hostid", "host"],
        "groupids": "'$GROUP_ID'"
    },
    "auth": "'$AUTH_TOKEN'",
    "id": 1
}' $ZABBIX_URL)
#echo $HOSTS

# 时间范围,这里只获取24小时的数据
END_TIME=$(date +%s)
#echo $END_TIME
START_TIME=$((END_TIME - 86400))  # 24小时之前的时间戳
#echo $START_TIME

# Step 3: 遍历每个主机,获取CPU和RAM的监控项数据
for HOST in $(echo "$HOSTS" | jq -r '.result[] | @base64'); do
    _jq() {
        echo ${HOST} | base64 --decode | jq -r ${1}
    }

    HOST_ID=$(_jq '.hostid')
    #echo $HOST_ID
    HOST_NAME=$(_jq '.host')
    #echo $HOST_NAME

    # Step 4: 获取CPU和内存的itemid
    ITEMID_CPU=$(curl -s -X POST -H 'Content-Type: application/json' -d '{
        "jsonrpc": "2.0",
        "method": "item.get",
        "params": {
            "output": "extend",
            "hostids": "'$HOST_ID'",
            "search": {
	        "name": "CPU utilization",
                "key_": "system.cpu.util"
            }
        },
        "auth": "'$AUTH_TOKEN'",
        "id": 1
    }' $ZABBIX_URL | jq -r '.result[0].itemid')
    #echo $ITEMID_CPU

    ITEMID_MEM=$(curl -s -X POST -H 'Content-Type: application/json' -d '{
        "jsonrpc": "2.0",
        "method": "item.get",
        "params": {
            "output": "extend",
            "hostids": "'$HOST_ID'",
            "search": {
                "key_": "vm.memory.utilization"
            }
        },
        "auth": "'$AUTH_TOKEN'",
        "id": 1
    }' $ZABBIX_URL | jq -r '.result[0].itemid')
    #echo $ITEMID_MEM

    # 获取CPU和内存的历史数据
    CPU_DATA=$(curl -s -X POST -H 'Content-Type: application/json' -d '{
        "jsonrpc": "2.0",
        "method": "history.get",
        "params": {
            "output": "extend",
            "history": 0,
	    "itemids": "'$ITEMID_CPU'",
            "time_from": "'$START_TIME'",
            "time_till": "'$END_TIME'",
	    "sortfield": "clock",
            "sortorder": "DESC"
    },
        "auth": "'$AUTH_TOKEN'",
        "id": 1
    }' $ZABBIX_URL | jq -r '.result[] | .value')

    MEM_DATA=$(curl -s -X POST -H 'Content-Type: application/json' -d '{
        "jsonrpc": "2.0",
        "method": "history.get",
        "params": {
            "output": "extend",
            "history": 0,
            "itemids": "'$ITEMID_MEM'",
            "time_from": "'$START_TIME'",
            "time_till": "'$END_TIME'",
            "sortfield": "clock",
            "sortorder": "DESC"
        },
        "auth": "'$AUTH_TOKEN'",
        "id": 1
    }' $ZABBIX_URL | jq -r '.result[] | .value')

    #获取最新的CPU和内存数值
    LATEST_CPU=$(echo "$CPU_DATA" | head -n 1)
    LATEST_MEM=$(echo "$MEM_DATA" | head -n 1)

    #计算CPU和内存的最大值、最小值和平均值
    CPU_MAX=$(echo "$CPU_DATA" | sort -nr | head -n 1)
    CPU_MIN=$(echo "$CPU_DATA" | sort -n | head -n 1)
    CPU_AVG=$(echo "$CPU_DATA" | awk '{s+=$1} END {printf "%.2f", s/NR}')
    #echo $CPU_MAX
    #echo $CPU_MIN
    #echo $CPU_AVG


    MEM_MAX=$(echo "$MEM_DATA" | sort -nr | head -n 1)
    MEM_MIN=$(echo "$MEM_DATA" | sort -n | head -n 1)
    MEM_AVG=$(echo "$MEM_DATA" | awk '{s+=$1} END {printf "%.2f", s/NR}')
    #echo "$MEM_AVG"

    #格式化为两位小数
    CPU_MAX=$(printf "%.2f" "$CPU_MAX")
    CPU_MIN=$(printf "%.2f" "$CPU_MIN")
    LATEST_CPU=$(printf "%.2f" "$LATEST_CPU")

    MEM_MAX=$(printf "%.2f" "$MEM_MAX")
    MEM_MIN=$(printf "%.2f" "$MEM_MIN")
    LATEST_MEM=$(printf "%.2f" "$LATEST_MEM")

    #发送监控数据到 TG 群组
    MESSAGE="*Server Name(服务器):* $HOST_NAME%0A*CPU utilization 24h(利用率):*%0A- Max(最大): $CPU_MAX%25%0A- Min(最小): $CPU_MIN%25%0A- AVG(平均): $CPU_AVG%25%0A- Current(当前): $LATEST_CPU%25%0A*Memory utilization 24h(内存利用率):*%0A- Max(最大): $MEM_MAX%25%0A- Min(最小): $MEM_MIN%25%0A- AVG(平均): $MEM_AVG%25%0A- Current(当前): $LATEST_MEM%25%"
    #echo $Message

    curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
    -d "chat_id=$TELEGRAM_CHAT_ID" \
    -d "text=$MESSAGE" \
    -d "parse_mode=Markdown"

done

以上代码,在调试,可以自行去掉 echo 前面的#。

四,群组输出格式问题

最后代码格式问题,会因所发送的媒体信息不通,代码格式也不同。如以前用/n换行,格式在shell输出没问题,在TG群就不生效。以前参考格式。

powershell 复制代码
    MESSAGE="服务器名称: $HOST_NAME\nCPU 利用率: 最大 $CPU_MAX%, 最小 $CPU_MIN%, 平均 $CPU_AVG%\n内存利用率: 最大 $MEM_MAX%, 最小 $MEM_MIN%, 平均 $MEM_AVG%"

    curl -s -X POST https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage -d chat_id=$TELEGRAM_CHAT_ID -d text="$MESSAGE"

后面改成这样的格式,虽然shell输出格式乱,但是在TG群组输入没问题。

使用Markdown 语法:

使用 * 符号来加粗文本。

使用 - 来列出项目。

确保 TG 处理换行:

将换行符 \n 替换为 %0A,这是 URL 编码的换行符。

powershell 复制代码
    MESSAGE="*Server Name(服务器):* $HOST_NAME%0A*CPU utilization 24h(利用率):*%0A- Max(最大): $CPU_MAX%25%0A- Min(最小): $CPU_MIN%25%0A- AVG(平均): $CPU_AVG%25%0A- Current(当前): $LATEST_CPU%25%0A*Memory utilization 24h(内存利用率):*%0A- Max(最大): $MEM_MAX%25%0A- Min(最小): $MEM_MIN%25%0A- AVG(平均): $MEM_AVG%25%0A- Current(当前): $LATEST_MEM%25%"
    
    curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
    -d "chat_id=$TELEGRAM_CHAT_ID" \
    -d "text=$MESSAGE" \
    -d "parse_mode=Markdown"

最后运行脚本结果

最后放服务器上,设置个定时任务,每天自动发送消息。

powershell 复制代码
crontab -e

00 12 * * * bash /shell/zabbix_monitor.sh
相关推荐
bkspiderx16 分钟前
Nginx 屏蔽服务器名称与版本信息(源码级修改)
运维·服务器·nginx
野生柚子30 分钟前
记录学习K8s 集群中OOM Killer的决策基准及执行流程
linux·运维
TLucas2 小时前
在CentOS 7上将PostgreSQL数据库从默认路径迁移到自定义目录
linux·运维·postgresql·centos
guidovans2 小时前
基于tkinter开发电脑工具集(源码在底部)
linux·windows·python·gui·tkinter
ZoeLandia3 小时前
nginx实战分析
运维·前端·nginx
菜菜子爱学习3 小时前
Nginx学习笔记(九)—— Nginx Rewrite深度解析
linux·运维·笔记·学习·nginx
迷之程序员4 小时前
服务器装两个cpu
运维·服务器
Tearstornbyrain4 小时前
在Ubuntu24.04中使用ssh连接本地git仓库到github远程仓库
linux·git·ubuntu·ssh·github
Jia ming5 小时前
【奔跑吧!Linux 内核(第二版)】第6章:简单的字符设备驱动(三)
linux
Mr_Xuhhh5 小时前
传输层协议 TCP(1)
运维·服务器·网络·c++·网络协议·tcp/ip·https