5.8.4 资源监控与告警触发脚本

资源监控与告警触发脚本#

本节聚焦通过 Shell 脚本完成主机资源监控、阈值判断与告警触发,覆盖 CPU、内存、磁盘、网络与关键进程,并支持邮件、Webhook 或日志告警。脚本强调可配置、可扩展、可观测,适配 cron 与监控平台二次集成。

原理草图(采集→判定→告警)#

文章图片

环境准备与安装#

  • 采集工具(多数系统自带)
  • topfreedfpsss
  • 扩展工具(可选)
  • sysstat 提供 sariostatmpstat
  • mailx 用于邮件告警

安装示例(CentOS/RHEL)

sudo yum install -y sysstat mailx
sudo systemctl enable --now sysstat

安装示例(Ubuntu/Debian)

sudo apt update
sudo apt install -y sysstat mailutils
sudo systemctl enable --now sysstat

关键命令与解释#

  • CPU 使用率(取 top 非交互模式)
top -bn1 | awk -F',' '/Cpu/ {print 100-$4}'
# 解释:100-空闲% 即使用率(%),$4 为 idle
  • 内存使用率(基于 free -m)
free -m | awk '/Mem:/ {printf "%.2f", $3/$2*100}'
# 解释:已用/总量 * 100
  • 磁盘使用率(检查根分区)
df -hP / | awk 'NR==2 {print $5}' | tr -d '%'
# 解释:-P 保证输出格式稳定,去掉 %
  • 网络连接数(全部 TCP)
ss -s | awk '/TCP:/ {print $2}' | tr -d ','
# 解释:TCP: 连接数等指标,$2 为当前连接数
  • 关键进程是否存活(示例:nginx)
pgrep -x nginx >/dev/null && echo "nginx ok" || echo "nginx down"
# 解释:-x 精确匹配进程名

示例脚本:CPU/内存/磁盘监控与告警(可执行)#

脚本路径: /opt/ops/monitor.sh
日志路径: /var/log/ops_monitor.log
配置路径: /etc/ops_monitor.conf

配置文件 /etc/ops_monitor.conf

# 阈值配置(百分比)
CPU_WARN=80
MEM_WARN=85
DISK_WARN=90

# 告警配置
ALERT_COOLDOWN=300          # 告警冷却时间(秒)
ALERT_EMAIL="ops@example.com"
WEBHOOK_URL="https://example.com/webhook"
HOSTNAME_TAG="$(hostname -s)"

脚本文件 /opt/ops/monitor.sh

#!/bin/bash
set -euo pipefail

CONF="/etc/ops_monitor.conf"
LOG="/var/log/ops_monitor.log"
STATE_DIR="/var/run/ops_monitor"
mkdir -p "$STATE_DIR"

# 加载配置
[ -f "$CONF" ] && source "$CONF"

now_ts=$(date +%s)
log() { echo "$(date '+%F %T') $*" | tee -a "$LOG"; }

cooldown_ok() {
  local key="$1"
  local state="$STATE_DIR/$key"
  if [ -f "$state" ]; then
    local last_ts
    last_ts=$(cat "$state")
    [ $((now_ts - last_ts)) -ge "${ALERT_COOLDOWN:-300}" ] || return 1
  fi
  return 0
}

mark_alert() {
  local key="$1"
  echo "$now_ts" > "$STATE_DIR/$key"
}

send_alert() {
  local msg="$1"
  log "ALERT $msg"

  # 邮件告警(可选)
  if command -v mail >/dev/null && [ -n "${ALERT_EMAIL:-}" ]; then
    echo "$msg" | mail -s "OPS ALERT ${HOSTNAME_TAG}" "$ALERT_EMAIL" || true
  fi

  # Webhook 告警(可选)
  if command -v curl >/dev/null && [ -n "${WEBHOOK_URL:-}" ]; then
    curl -s -X POST -H "Content-Type: application/json" \
      -d "{\"host\":\"${HOSTNAME_TAG}\",\"msg\":\"${msg}\"}" \
      "$WEBHOOK_URL" >/dev/null || true
  fi
}

# 采集指标
cpu_used=$(top -bn1 | awk -F',' '/Cpu/ {print 100-$4}' | awk '{printf "%.2f",$1}')
mem_used=$(free -m | awk '/Mem:/ {printf "%.2f", $3/$2*100}')
disk_used=$(df -hP / | awk 'NR==2 {print $5}' | tr -d '%')

log "INFO cpu=${cpu_used}% mem=${mem_used}% disk=${disk_used}%"

# 阈值判断与告警
if (( $(echo "$cpu_used >= ${CPU_WARN:-80}" | bc -l) )); then
  cooldown_ok cpu && send_alert "CPU high ${cpu_used}%" && mark_alert cpu
fi

if (( $(echo "$mem_used >= ${MEM_WARN:-85}" | bc -l) )); then
  cooldown_ok mem && send_alert "MEM high ${mem_used}%" && mark_alert mem
fi

if [ "$disk_used" -ge "${DISK_WARN:-90}" ]; then
  cooldown_ok disk && send_alert "DISK high ${disk_used}%" && mark_alert disk
fi

运行与预期

sudo mkdir -p /opt/ops
sudo cp monitor.sh /opt/ops/monitor.sh
sudo chmod +x /opt/ops/monitor.sh
sudo /opt/ops/monitor.sh
# 预期:在 /var/log/ops_monitor.log 看到 INFO 行,超阈值则出现 ALERT

定时任务(cron)#

sudo crontab -e
# 每分钟执行一次
* * * * * /opt/ops/monitor.sh >/dev/null 2>&1

进阶示例:关键进程存活检测告警#

#!/bin/bash
# /opt/ops/check_service.sh
SERV="nginx"
if ! pgrep -x "$SERV" >/dev/null; then
  echo "$(date '+%F %T') $SERV down" | tee -a /var/log/ops_monitor.log
  # 触发告警
  curl -s -X POST -H "Content-Type: application/json" \
    -d "{\"host\":\"$(hostname -s)\",\"msg\":\"$SERV down\"}" \
    "https://example.com/webhook" >/dev/null
fi

排错指南#

  • 脚本报错 bc: command not found
  • 安装:sudo yum install -y bcsudo apt install -y bc
  • mail 命令不可用
  • 安装 mailxmailutils,并检查 /etc/mail.rc 或 SMTP 配置
  • Webhook 无响应
  • curl -v 验证 URL 与证书;确认防火墙与代理
  • top 输出格式异常
  • 更换 mpstatsar 采集方式,保证 awk 字段稳定

练习#

  1. 将脚本扩展为同时监控 //data 两个分区,并分别告警。
  2. 新增网络流量阈值告警(使用 sar -n DEV 1 1 统计)。
  3. 为同一告警增加“恢复通知”,当指标低于阈值 10% 时发送恢复消息。