获取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
相关推荐
Liang_GaRy几秒前
心路历程-Linux的特殊权限
linux·运维·服务器
monster_风铃2 分钟前
BFD原理与配置
服务器·网络·tcp/ip·信息安全管理与评估
0wioiw06 分钟前
Docker(⑤Kali Linux-HexStrike AI安装)
linux·服务器
wifi chicken8 分钟前
Linux Netfilter 之 如何完成一个自制的防火墙实例
linux·kernel·tcpip·netfiler
非凡ghost11 分钟前
AOMEI Partition Assistant磁盘分区工具:磁盘管理的得力助手
linux·运维·前端·数据库·学习·生活·软件需求
山君爱摸鱼11 分钟前
Linux网络配置
linux·运维
寒士obj14 分钟前
Docker的使用及核心命令
运维·docker·容器
喜欢你,还有大家19 分钟前
Nginx服务——安装与搭建
java·服务器·nginx
Galeoto25 分钟前
how to setup k3s on an offline ubuntu
linux·运维·ubuntu
二进制coder42 分钟前
深入解析 AST2600 H2B 接口:架构、原理与完整开发指南
linux·架构