题目
编写Shell脚本监控进程资源使用并发送告警邮件
信息
- 类型:问答
- 难度:⭐⭐
考点
进程监控,资源阈值判断,邮件告警
快速回答
该脚本需要实现以下核心功能:
- 使用
ps或top获取指定进程的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配合grep和awk精确统计目标进程资源- 避免grep自身:
grep "[x]xx"语法排除grep进程 - 多进程统计:
awk累加所有匹配进程的资源值
- 避免grep自身:
- 阈值比较:
- 使用
bc处理浮点数比较(Shell原生只支持整数) - 动态变量引用:
${!metric}_THRESHOLD根据参数名获取阈值
- 使用
- 防告警风暴:触发告警后进入
sleep $COOL_DOWN冷却期 - 邮件集成:
- 依赖系统
mailutils或sendmail服务 - 使用Here Document生成邮件正文
- 依赖系统
最佳实践
- 日志记录:所有操作记录到日志文件,便于审计
- 参数化配置:关键参数放在脚本开头,便于维护
- 进程存活检查:添加
pgrep验证进程是否存在 - 信号处理:添加
trap捕获SIGTERM实现优雅退出
常见错误
- grep匹配错误:未处理grep自身进程导致统计偏差
- 浮点数比较:直接使用
[ ]比较浮点值会语法报错 - 邮件服务未配置:未安装
mailutils导致发送失败 - 资源消耗:监控间隔过短可能消耗系统资源
扩展知识
- 替代工具:
- 使用
top -b -n1批处理模式获取实时数据 - 专业监控工具:Prometheus + Node Exporter
- 使用
- 进程组监控:通过
pgrep -f匹配完整命令行 - 容器环境适配:在Docker中需使用
docker stats命令 - 云服务集成:AWS SNS/Slack webhook替代邮件告警