侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

编写Shell脚本监控进程资源使用并发送告警邮件

2025-12-12 / 0 评论 / 3 阅读

题目

编写Shell脚本监控进程资源使用并发送告警邮件

信息

  • 类型:问答
  • 难度:⭐⭐

考点

进程监控,资源阈值判断,邮件告警

快速回答

该脚本需要实现以下核心功能:

  • 使用pstop获取指定进程的CPU和内存使用率
  • 设置可配置的阈值参数
  • 通过mail命令发送告警邮件
  • 包含错误处理和日志记录机制
## 解析

问题需求

编写一个Shell脚本,监控指定进程的CPU和内存使用情况,当超过预设阈值时自动发送告警邮件。要求:

  • 支持通过进程名监控
  • CPU和内存阈值可配置
  • 包含时间戳和详细资源数据
  • 防止告警风暴(如添加冷却机制)

核心实现方案

#!/bin/bash

# 配置参数
PROCESS_NAME="nginx"
CPU_THRESHOLD=80   # CPU使用率百分比
MEM_THRESHOLD=50   # 内存使用率百分比
EMAIL="admin@example.com"
LOG_FILE="/var/log/process_monitor.log"
COOL_DOWN=300      # 5分钟冷却时间(秒)

# 获取进程资源使用
get_process_stats() {
  # 使用ps提取进程资源数据(兼容不同Unix变体)
  ps_output=$(ps aux | grep "[${PROCESS_NAME:0:1}]${PROCESS_NAME:1}" | awk '{cpu+=$3; mem+=$4} END {print cpu, mem}')
  echo $ps_output
}

# 发送告警邮件
send_alert() {
  local metric=$1
  local value=$2
  local timestamp=$(date "+%Y-%m-%d %H:%M:%S")

  echo "[$timestamp] 告警: $PROCESS_NAME $metric 使用率 ${value}%" >> "$LOG_FILE"
  mail -s "[$PROCESS_NAME] $metric 超标告警" "$EMAIL" << EOF
时间: $timestamp
进程: $PROCESS_NAME
当前${metric}使用率: ${value}%
阈值: ${!metric}_THRESHOLD%
EOF
}

# 主监控逻辑
while true; do
  read cpu_usage mem_usage <<< $(get_process_stats)

  # 浮点数比较(使用bc)
  if (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l) )); then
    send_alert "CPU" "$cpu_usage"
    sleep $COOL_DOWN  # 触发冷却机制
  fi

  if (( $(echo "$mem_usage > $MEM_THRESHOLD" | bc -l) )); then
    send_alert "MEM" "$mem_usage"
    sleep $COOL_DOWN
  fi

  sleep 60  # 每分钟检查一次

done

关键考点解析

  • 进程资源获取:使用ps aux配合grepawk精确统计目标进程资源
    • 避免grep自身:grep "[x]xx"语法排除grep进程
    • 多进程统计:awk累加所有匹配进程的资源值
  • 阈值比较
    • 使用bc处理浮点数比较(Shell原生只支持整数)
    • 动态变量引用:${!metric}_THRESHOLD根据参数名获取阈值
  • 防告警风暴:触发告警后进入sleep $COOL_DOWN冷却期
  • 邮件集成
    • 依赖系统mailutilssendmail服务
    • 使用Here Document生成邮件正文

最佳实践

  • 日志记录:所有操作记录到日志文件,便于审计
  • 参数化配置:关键参数放在脚本开头,便于维护
  • 进程存活检查:添加pgrep验证进程是否存在
  • 信号处理:添加trap捕获SIGTERM实现优雅退出

常见错误

  • grep匹配错误:未处理grep自身进程导致统计偏差
  • 浮点数比较:直接使用[ ]比较浮点值会语法报错
  • 邮件服务未配置:未安装mailutils导致发送失败
  • 资源消耗:监控间隔过短可能消耗系统资源

扩展知识

  • 替代工具
    • 使用top -b -n1批处理模式获取实时数据
    • 专业监控工具:Prometheus + Node Exporter
  • 进程组监控:通过pgrep -f匹配完整命令行
  • 容器环境适配:在Docker中需使用docker stats命令
  • 云服务集成:AWS SNS/Slack webhook替代邮件告警