服务器资源监控告警脚本
实时监控CPU、内存、磁盘使用率,超过阈值时自动发送邮件/企业微信告警,支持自定义阈值和检测间隔
详细内容
#!/bin/bash
# ==========================================
# 服务器资源监控告警脚本
# 用途:监控CPU、内存、磁盘使用率,超阈值告警
# 使用方法:bash resource_monitor.sh (建议加入crontab每分钟执行)
# ==========================================
# ========== 配置 ==========
CPU_THRESHOLD=80 # CPU使用率告警阈值(%)
MEM_THRESHOLD=85 # 内存使用率告警阈值(%)
DISK_THRESHOLD=90 # 磁盘使用率告警阈值(%)
LOAD_THRESHOLD=0 # 系统负载阈值(0表示不检测,按核心数设置,如4核设为4)
CHECK_INTERVAL=60 # 检测间隔(秒),持续监控模式使用
LOG_FILE="/var/log/resource_monitor.log"
ALERT_EMAIL="" # 告警邮箱,留空则不发邮件
WECOM_WEBHOOK="" # 企业微信机器人Webhook,留空则不发
# ==========================
mkdir -p "$(dirname "$LOG_FILE")"
log_msg() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
send_alert() {
local title="$1"
local content="$2"
log_msg "【告警】$title: $content"
# 邮件告警
if [ -n "$ALERT_EMAIL" ]; then
echo -e "$content" | mail -s "【服务器告警】$title" "$ALERT_EMAIL" 2>/dev/null
fi
# 企业微信告警
if [ -n "$WECOM_WEBHOOK" ]; then
curl -s "$WECOM_WEBHOOK" -H "Content-Type: application/json" -d "{
"msgtype": "text",
"text": {"content": "【服务器告警】$title\n$content\n主机: $(hostname)\n时间: $(date '+%Y-%m-%d %H:%M:%S')"}
}" >/dev/null 2>&1
fi
}
check_cpu() {
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d. -f1)
if [ -z "$CPU_USAGE" ]; then
CPU_USAGE=$(vmstat 1 2 | tail -1 | awk '{print 100-$15}')
fi
if [ "$CPU_USAGE" -gt "$CPU_THRESHOLD" ]; then
TOP_PROC=$(ps aux --sort=-%cpu | head -4 | tail -3 | awk '{print $11" ("$3"%)"}' | tr '\n' ' ')
send_alert "CPU使用率过高" "当前CPU使用率: ${CPU_USAGE}% (阈值: ${CPU_THRESHOLD}%)\nTop进程: $TOP_PROC"
else
log_msg "CPU使用率: ${CPU_USAGE}% (正常)"
fi
}
check_memory() {
MEM_TOTAL=$(free -m | awk 'NR==2{print $2}')
MEM_USED=$(free -m | awk 'NR==2{print $3}')
MEM_USAGE=$((MEM_USED * 100 / MEM_TOTAL))
if [ "$MEM_USAGE" -gt "$MEM_THRESHOLD" ]; then
TOP_PROC=$(ps aux --sort=-%mem | head -4 | tail -3 | awk '{print $11" ("$4"%)"}' | tr '\n' ' ')
send_alert "内存使用率过高" "当前内存使用率: ${MEM_USAGE}% (阈值: ${MEM_THRESHOLD}%)\n已用: ${MEM_USED}MB / 总计: ${MEM_TOTAL}MB\nTop进程: $TOP_PROC"
else
log_msg "内存使用率: ${MEM_USAGE}% (正常)"
fi
}
check_disk() {
df -hP | grep -vE "tmpfs|devtmpfs|overlay" | awk 'NR>1{print $6" "$5}' | while read mount usage; do
usage_num=${usage%\%}
if [ "$usage_num" -gt "$DISK_THRESHOLD" ]; then
send_alert "磁盘使用率过高" "分区 $mount 使用率: ${usage} (阈值: ${DISK_THRESHOLD}%)\n$(df -h "$mount" | tail -1)"
else
log_msg "磁盘 $mount 使用率: $usage (正常)"
fi
done
}
check_load() {
if [ "$LOAD_THRESHOLD" -gt 0 ]; then
LOAD1=$(cat /proc/loadavg | awk '{print $1}')
LOAD_STATUS=$(echo "$LOAD1 > $LOAD_THRESHOLD" | bc)
if [ "$LOAD_STATUS" = "1" ]; then
send_alert "系统负载过高" "1分钟负载: $LOAD1 (阈值: $LOAD_THRESHOLD)\n$(uptime)"
else
log_msg "系统负载: $LOAD1 (正常)"
fi
fi
}
# 单次检测模式(crontab使用)
if [ "$1" = "--once" ]; then
log_msg "===== 开始单次资源检测 ====="
check_cpu
check_memory
check_disk
check_load
log_msg "===== 检测完成 ====="
exit 0
fi
# 持续监控模式
log_msg "===== 资源监控启动,间隔${CHECK_INTERVAL}秒 ====="
while true; do
check_cpu
check_memory
check_disk
check_load
sleep "$CHECK_INTERVAL"
done
适配环境
适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+
依赖环境:bash 4.0+
参数说明
[{"name": "CPU_THRESHOLD", "label": "CPU\u544a\u8b66\u9608\u503c(%)", "default": "80"}, {"name": "MEM_THRESHOLD", "label": "\u5185\u5b58\u544a\u8b66\u9608\u503c(%)", "default": "85"}, {"name": "DISK_THRESHOLD", "label": "\u78c1\u76d8\u544a\u8b66\u9608\u503c(%)", "default": "90"}, {"name": "ALERT_EMAIL", "label": "\u544a\u8b66\u90ae\u7bb1(\u53ef\u9009)", "default": ""}, {"name": "WECOM_WEBHOOK", "label": "\u4f01\u4e1a\u5fae\u4fe1Webhook(\u53ef\u9009)", "default": ""}]