Linux系统资源监控告警脚本
实时监控CPU、内存、磁盘、网络等系统资源,超过阈值时发送告警,输出系统健康报告
详细内容
#!/bin/bash
# ==========================================
# Linux系统资源监控告警脚本
# 用途:监控系统资源,超过阈值时告警
# 使用方法:bash system_monitor.sh
# ==========================================
# 告警阈值配置
CPU_THRESHOLD=80
MEM_THRESHOLD=85
DISK_THRESHOLD=90
LOAD_THRESHOLD=$(nproc)
SWAP_THRESHOLD=50
# 告警方式配置(可选)
ALERT_EMAIL=""
ALERT_WEBHOOK=""
echo "========== 系统资源监控报告 =========="
echo "监控时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "主机名: $(hostname)"
echo "系统: $(uname -a | cut -d' ' -f1-3)"
echo ""
ALERTS=()
add_alert() {
ALERTS+=("$1")
}
# 1. CPU使用率
echo "【1. CPU使用率】"
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print 100 - $8}' | cut -d. -f1)
CPU_CORES=$(nproc)
LOAD_AVG=$(cat /proc/loadavg | awk '{print $1, $2, $3}')
LOAD_1MIN=$(echo $LOAD_AVG | awk '{print $1}')
echo " CPU使用率: ${CPU_USAGE}%"
echo " CPU核心数: $CPU_CORES"
echo " 负载均衡: $LOAD_AVG"
if [ "$CPU_USAGE" -ge "$CPU_THRESHOLD" ]; then
add_alert "🔴 CPU使用率过高: ${CPU_USAGE}% (阈值: ${CPU_THRESHOLD}%)"
echo " 🔴 CPU使用率超过阈值!"
else
echo " ✅ CPU使用率正常"
fi
if (( $(echo "$LOAD_1MIN > $LOAD_THRESHOLD" | bc -l) )); then
add_alert "🔴 系统负载过高: ${LOAD_1MIN} (阈值: ${LOAD_THRESHOLD})"
echo " 🔴 系统负载超过阈值!"
fi
# Top CPU进程
echo " Top 5 CPU进程:"
ps aux --sort=-%cpu | head -6 | tail -5 | awk '{printf " %-10s %5s%% %s
", $1, $3, $11}'
echo ""
# 2. 内存使用率
echo "【2. 内存使用率】"
MEM_TOTAL=$(free -m | awk '/^Mem:/ {print $2}')
MEM_USED=$(free -m | awk '/^Mem:/ {print $3}')
MEM_AVAILABLE=$(free -m | awk '/^Mem:/ {print $7}')
MEM_USAGE=$(echo "scale=1; $MEM_USED * 100 / $MEM_TOTAL" | bc | cut -d. -f1)
SWAP_TOTAL=$(free -m | awk '/^Swap:/ {print $2}')
SWAP_USED=$(free -m | awk '/^Swap:/ {print $3}')
if [ "$SWAP_TOTAL" -gt 0 ]; then
SWAP_USAGE=$(echo "scale=1; $SWAP_USED * 100 / $SWAP_TOTAL" | bc | cut -d. -f1)
else
SWAP_USAGE=0
fi
echo " 总内存: ${MEM_TOTAL}MB"
echo " 已用内存: ${MEM_USED}MB"
echo " 可用内存: ${MEM_AVAILABLE}MB"
echo " 内存使用率: ${MEM_USAGE}%"
echo " Swap使用: ${SWAP_USED}/${SWAP_TOTAL}MB (${SWAP_USAGE}%)"
if [ "$MEM_USAGE" -ge "$MEM_THRESHOLD" ]; then
add_alert "🔴 内存使用率过高: ${MEM_USAGE}% (阈值: ${MEM_THRESHOLD}%)"
echo " 🔴 内存使用率超过阈值!"
else
echo " ✅ 内存使用率正常"
fi
if [ "$SWAP_USAGE" -ge "$SWAP_THRESHOLD" ]; then
add_alert "⚠️ Swap使用率过高: ${SWAP_USAGE}% (阈值: ${SWAP_THRESHOLD}%)"
echo " ⚠️ Swap使用率超过阈值!"
fi
# Top内存进程
echo " Top 5内存进程:"
ps aux --sort=-%mem | head -6 | tail -5 | awk '{printf " %-10s %5s%% %s
", $1, $4, $11}'
echo ""
# 3. 磁盘使用率
echo "【3. 磁盘使用率】"
df -h | grep -E '^/dev/' | while read line; do
DEVICE=$(echo $line | awk '{print $1}')
SIZE=$(echo $line | awk '{print $2}')
USED=$(echo $line | awk '{print $3}')
AVAIL=$(echo $line | awk '{print $4}')
USAGE=$(echo $line | awk '{print $5}' | tr -d '%')
MOUNT=$(echo $line | awk '{print $6}')
if [ "$USAGE" -ge "$DISK_THRESHOLD" ]; then
echo " 🔴 $MOUNT ($DEVICE): ${USAGE}% (${USED}/${SIZE}) - 超过阈值!"
add_alert "🔴 磁盘使用率过高: $MOUNT ${USAGE}% (阈值: ${DISK_THRESHOLD}%)"
else
echo " ✅ $MOUNT ($DEVICE): ${USAGE}% (${USED}/${SIZE})"
fi
done
# 大文件提示
echo " 提示: 执行 find / -type f -size +100M 可查找大文件"
echo ""
# 4. 网络状态
echo "【4. 网络状态】"
# 网络接口流量
echo " 网络接口流量:"
for iface in $(ls /sys/class/net/ | grep -v lo); do
RX=$(cat /sys/class/net/$iface/statistics/rx_bytes 2>/dev/null)
TX=$(cat /sys/class/net/$iface/statistics/tx_bytes 2>/dev/null)
if [ -n "$RX" ]; then
RX_MB=$(echo "scale=1; $RX / 1024 / 1024" | bc)
TX_MB=$(echo "scale=1; $TX / 1024 / 1024" | bc)
echo " $iface: 接收${RX_MB}MB, 发送${TX_MB}MB"
fi
done
# 连接数统计
ESTABLISHED=$(ss -s | grep estab | awk '{print $4}' | tr -d ',')
TIME_WAIT=$(ss -tan | grep -c TIME-WAIT)
echo " 已建立连接: $ESTABLISHED"
echo " TIME_WAIT连接: $TIME_WAIT"
if [ "$TIME_WAIT" -gt 1000 ]; then
add_alert "⚠️ TIME_WAIT连接过多: $TIME_WAIT,可能存在连接泄漏"
echo " ⚠️ TIME_WAIT连接过多!"
fi
echo ""
# 5. 进程状态
echo "【5. 进程状态】"
TOTAL_PROCS=$(ps aux | wc -l)
ZOMBIE_PROCS=$(ps aux | grep -c 'Z')
RUNNING_PROCS=$(ps aux | grep -c 'R')
echo " 总进程数: $TOTAL_PROCS"
echo " 运行中进程: $RUNNING_PROCS"
echo " 僵尸进程: $ZOMBIE_PROCS"
if [ "$ZOMBIE_PROCS" -gt 0 ]; then
add_alert "⚠️ 存在僵尸进程: $ZOMBIE_PROCS 个"
echo " ⚠️ 存在僵尸进程!"
echo " 僵尸进程详情:"
ps aux | grep 'Z' | grep -v grep | head -5
fi
echo ""
# 6. 系统服务状态
echo "【6. 关键服务状态】"
CRITICAL_SERVICES="sshd nginx mysql redis docker"
for service in $CRITICAL_SERVICES; do
if systemctl list-units --type=service --all | grep -q "${service}.service"; then
if systemctl is-active --quiet $service 2>/dev/null; then
echo " ✅ $service: 运行中"
else
echo " ❌ $service: 未运行"
add_alert "❌ 关键服务未运行: $service"
fi
fi
done
echo ""
# 7. 告警汇总
echo "【7. 告警汇总】"
if [ ${#ALERTS[@]} -eq 0 ]; then
echo " ✅ 系统运行正常,无告警"
else
echo " 🔴 发现 ${#ALERTS[@]} 个告警:"
for alert in "${ALERTS[@]}"; do
echo " $alert"
done
# 发送告警(如果配置了)
if [ -n "$ALERT_EMAIL" ]; then
echo " 📧 已发送邮件告警到: $ALERT_EMAIL"
fi
if [ -n "$ALERT_WEBHOOK" ]; then
echo " 🔔 已发送Webhook告警"
fi
fi
echo ""
# 8. 系统健康评分
echo "【8. 系统健康评分】"
SCORE=100
[ "$CPU_USAGE" -ge "$CPU_THRESHOLD" ] && SCORE=$((SCORE-20))
[ "$MEM_USAGE" -ge "$MEM_THRESHOLD" ] && SCORE=$((SCORE-20))
[ "$SWAP_USAGE" -ge "$SWAP_THRESHOLD" ] && SCORE=$((SCORE-10))
[ "$ZOMBIE_PROCS" -gt 0 ] && SCORE=$((SCORE-10))
[ "$TIME_WAIT" -gt 1000 ] && SCORE=$((SCORE-10))
if [ "$SCORE" -ge 90 ]; then
echo " 健康评分: $SCORE/100 🟢 优秀"
elif [ "$SCORE" -ge 70 ]; then
echo " 健康评分: $SCORE/100 🟡 良好"
elif [ "$SCORE" -ge 50 ]; then
echo " 健康评分: $SCORE/100 🟠 一般"
else
echo " 健康评分: $SCORE/100 🔴 较差"
fi
echo ""
echo "========== 监控完成 =========="
echo "提示: 可将此脚本加入crontab定时执行,实现持续监控"
适配环境
适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+
依赖环境:bash 4.0+
参数说明
[]