前言
Shell 脚本可以帮助你自动化任务,让你专注于更重要的工作。在本文中,我们将介绍如何编写一个 Shell 脚本,用于定期获取 Proxmox VE 系统的运行状态,结合之前介绍的搭建企业微信推送,并将这些信息推送到企业微信。
脚本功能
- 获取 CPU 使用情况
- 获取内存使用情况
- 获取 IO 使用情况
- 获取网络流量信息
- 获取存储使用情况
- 获取虚拟机信息
- 获取容器信息
脚本实现
我们将使用 Bash 脚本编写此自动化脚本。以下是脚本的实现:
#!/bin/bash
# 获取 CPU 使用情况
print_cpu_info() {
# Get CPU load
cpu_load=$(uptime | awk -F'load average:' '{ gsub(/^ +| +$/, "", $2); print $2 }')
# Print CPU section
echo "****** CPU ******"
top -bn1 | grep "Cpu(s)" | \
awk '{print "👽用户 "$2"%\n🛠️系统 "$4"%\n😴空闲 "$8"%"}'
printf "🏋️♂️负载 %s$cpu_load\n"
echo
}
# 获取内存使用情况
print_memory_info() {
# Get Memory usage
memory_info=$(free -h | grep Mem | awk '{print $3 "\t" $4 "\t" $5 "\t" $6 "\t" $7}')
# Print Memory section
echo "****** 内存 ******"
printf "🗂️已用 %s\n" "$(echo ${memory_info} | awk '{print $1 }')"
printf "🆓剩余 %s\n" "$(echo ${memory_info} | awk '{print $2 }')"
printf "♻️共享 %s\n" "$(echo ${memory_info} | awk '{print $3 }')"
printf "📦缓存 %s\n" "$(echo ${memory_info} | awk '{print $4 }')"
printf "📤可用 %s\n" "$(echo ${memory_info} | awk '{print $5 }')"
echo
}
# 获取 IO 使用情况
print_io_info() {
echo "****** IO ******"
physical_disks_list=$(lsblk -d -o NAME,TYPE | awk '$2 == "disk" {print $1}')
for disk in $physical_disks_list; do
printf "💾磁盘 $disk\n"
iostat -dx 1 1 | awk '{print $disk $4 $5 $10}' | grep $disk | \
awk '{printf "📑读取 %.2fr/s\n📝写入 %.2fw/s\n🕔响应 %.2fms\n\n", $4, $5, $10}'
done
echo
}
# 获取网络流量信息
print_traffic_info() {
# Get Traffic information
# 设置桥接口名称
# TODO
# 根据实际情况修改桥接口名称
bridges=("vmbr0" "vmbr1")
echo "****** 流量 ******"
for bridge in "${bridges[@]}"; do
printf "🌐接口 $bridge\n"
printf "⬇️接收 %.2fG\n" "$(cat /sys/class/net/$bridge/statistics/rx_bytes | awk '{sum += $1} END {print sum / (1024 * 1024)}')"
printf "⬆️发送 %.2fG\n" "$(cat /sys/class/net/$bridge/statistics/tx_bytes | awk '{sum += $1} END {print sum / (1024 * 1024)}')"
printf "\n"
done
echo
}
# 获取存储使用情况
print_storage_info() {
# Get Storage information
# Run the pvesm status command and store the output
status=$(/usr/sbin/pvesm status)
# Print the header
echo "****** 存储 ******"
# Process each line of the output
echo "$status" | awk 'NR>1 {
# Convert sizes to GB
size_gb = $4 / (1024*1024)
used_gb = $5 / (1024*1024)
avail_gb = $6 / (1024*1024)
# Print the formatted line
printf "📁逻辑卷 %s\n", $1
printf "🔎总大小 %.2fG\n🗂️已使用 %.2fG\n🆓未使用 %.2fG\n📊使用率 %.2f%%\n\n", size_gb, used_gb, avail_gb, $7
}'
}
# 获取虚拟机信息
print_vm_info() {
# Get VM information
# Print VM section
echo "****** 虚拟机 ******"
# Run the command to get the list of VMs and process the output
pvesh get /cluster/resources --output-format json | jq -r '.[] | select(.type == "qemu" and .status == "running") | [.type, .name, .vmid, .cpu, .mem, .maxmem, .disk, .maxdisk, .diskread, .diskwrite, .netin, .netout, .uptime] | @tsv' | awk -F'\t' '{
# Convert diskread, diskwrite, netin, and netout to GB
diskread_gb = $9 / (1024 * 1024 * 1024)
diskwrite_gb = $10 / (1024 * 1024 * 1024)
netin_gb = $11 / (1024 * 1024)
netout_gb = $12 / (1024 * 1024)
# Convert uptime to a more readable format
uptime = $13
days = int(uptime / 86400)
uptime -= days * 86400
hours = int(uptime / 3600)
uptime -= hours * 3600
minutes = int(uptime / 60)
uptime -= minutes * 60
seconds = int(uptime)
uptime_str = ""
if (days > 0) uptime_str = days "d "
if (hours > 0) uptime_str = uptime_str hours "h "
if (minutes > 0) uptime_str = uptime_str minutes "m "
uptime_str = uptime_str seconds "s"
# Print the formatted line
printf "🆔编号 %s\n", $3
printf "💻名称 %s\n", $2
printf "#️⃣CPU %.2f%%\n", $4
printf "🧱内存 %.2f%%\n", ($5 / $6) * 100
#printf "📦硬盘 %.2f%%\n", ($7 / $8) * 100
printf "📑读取 %.2fMi\n", diskread_gb
printf "📝写入 %.2fMi\n", diskwrite_gb
printf "⬇️接收 %.2fMi\n", netin_gb
printf "⬆️发送 %.2fMi\n", netout_gb
printf "⏳运行 %s\n", uptime_str
printf "\n"
}'
}
# 获取容器信息
print_lxc_info() {
# Get VM information
# Print VM section
echo "****** 容器 ******"
# Run the command to get the list of VMs and process the output
pvesh get /cluster/resources --output-format json | jq -r '.[] | select(.type == "lxc" and .status == "running") | [.type, .name, .vmid, .cpu, .mem, .maxmem, .disk, .maxdisk, .diskread, .diskwrite, .netin, .netout, .uptime] | @tsv' | awk -F'\t' '{
# Convert diskread, diskwrite, netin, and netout to GB
diskread_gb = $9 / (1024 * 1024 * 1024)
diskwrite_gb = $10 / (1024 * 1024 * 1024)
netin_gb = $11 / (1024 * 1024)
netout_gb = $12 / (1024 * 1024)
# Convert uptime to a more readable format
uptime = $13
days = int(uptime / 86400)
uptime -= days * 86400
hours = int(uptime / 3600)
uptime -= hours * 3600
minutes = int(uptime / 60)
uptime -= minutes * 60
seconds = int(uptime)
uptime_str = ""
if (days > 0) uptime_str = days "d "
if (hours > 0) uptime_str = uptime_str hours "h "
if (minutes > 0) uptime_str = uptime_str minutes "m "
uptime_str = uptime_str seconds "s"
# Print the formatted line
printf "🆔编号 %s\n", $3
printf "🐋名称 %s\n", $2
printf "#️⃣CPU %.2f%%\n", $4
printf "🧱内存 %.2f%%\n", ($5 / $6) * 100
printf "📦硬盘 %.2f%%\n", ($7 / $8) * 100
printf "📑读取 %.2fMi\n", diskread_gb
printf "📝写入 %.2fMi\n", diskwrite_gb
printf "⬇️接收 %.2fMi\n", netin_gb
printf "⬆️发送 %.2fMi\n", netout_gb
printf "⏳运行 %s\n", uptime_str
printf "\n"
}'
}
# SendMessage 函数用于将信息推送到企业微信
send_message() {
# 使用 curl 发送 HTTP 请求将信息推送到企业微信应用
# TODO
#这里根据实际公网服务器IP和token内容进行修改
#
curl "http://localhost:5000/?token=9a537f5d&msg=%F0%9F%8E%97%EF%B8%8FPVE%E7%B3%BB%E7%BB%9F%E7%9B%91%E6%B5%8B%0a%0a$1" > /dev/null 2>&1
}
# 主脚本
functions=("print_cpu_info" "print_memory_info" "print_io_info" "print_traffic_info" "print_storage_info" "print_vm_info" "print_lxc_info")
for func in "${functions[@]}"; do
# 调用各个函数获取信息,并将输出发送到企业微信
combined_output=$(printf "%s\n%s" "$($func)")
encoded_string=$(python3 -c "import urllib.parse; print(urllib.parse.quote('''$combined_output'''))")
send_message "$encoded_string"
done
使用说明
- 将脚本保存为
monitor.sh
。 - 确保你的系统中安装了所需的依赖,如
curl
、python3
、jq
等。 - 设置一个定时任务,以便定期执行该脚本。你可以使用 cron 作业来实现这一点。例如,如果你希望每小时执行一次,可以添加以下 cron 作业:
0 * * * * /path/to/monitor.sh
这将使脚本每小时执行一次,并将最新的 Proxmox VE 系统状态推送到企业微信。
由于企业微信单条信息有长度限制,所以使用每个查询接口单独发送,效果如图
通过这个脚本,你可以轻松地监控 Proxmox VE 系统的运行状态,并在必要时采取相应的行动。