在日常运维工作中,我们经常会遇到服务器负载飙升、磁盘空间不足等突发情况。如果每次都靠人工盯着监控系统,不仅效率低下,还容易错过关键告警。今天我们就来聊聊如何用Shell脚本打造一个智能的系统告警系统,让异常通知自动飞到你的办公桌上。
一、为什么需要自动化系统告警
想象一下这样的场景:凌晨三点,数据库服务器突然宕机。如果没有自动告警机制,可能直到第二天上班才会发现问题,这期间造成的业务损失将无法估量。自动化系统告警就像是一个24小时在线的哨兵,时刻守护着你的系统健康。
传统的人工监控方式有几个明显缺陷:响应速度慢、容易遗漏、无法持续工作。而Shell脚本实现的自动化告警系统可以完美解决这些问题,它能够:
- 实时监控系统指标
- 精确触发告警条件
- 通过多种渠道发送通知
- 记录完整的告警历史
二、基础告警脚本实现
我们先从一个最简单的磁盘空间监控脚本开始(技术栈:Bash Shell):
#!/bin/bash
# 设置磁盘使用率阈值(百分比)
THRESHOLD=90
# 获取根分区使用率
usage=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
# 判断是否超过阈值
if [ $usage -ge $THRESHOLD ]; then
# 构造告警信息
message="警告!根分区使用率已达 ${usage}%,超过阈值 ${THRESHOLD}%"
# 这里暂时用echo模拟发送通知
echo "$message"
# 实际环境中可以替换为邮件或短信发送命令
# mail -s "磁盘空间告警" admin@example.com <<< "$message"
fi
这个脚本虽然简单,但已经具备了自动化告警的核心要素:
- 定义监控指标(磁盘使用率)
- 设置告警阈值
- 执行条件判断
- 触发告警动作
三、进阶:多指标监控与通知
实际生产环境中,我们通常需要监控多个系统指标。下面这个增强版脚本可以同时监控CPU、内存和磁盘(技术栈:Bash Shell):
#!/bin/bash
# 配置各指标阈值
CPU_THRESHOLD=80 # CPU使用率阈值%
MEM_THRESHOLD=90 # 内存使用率阈值%
DISK_THRESHOLD=85 # 磁盘使用率阈值%
# 获取系统指标
cpu_usage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
mem_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
# 初始化告警信息
alerts=()
# 检查CPU使用率
if (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l) )); then
alerts+=("CPU使用率过高: ${cpu_usage}%")
fi
# 检查内存使用率
if (( $(echo "$mem_usage > $MEM_THRESHOLD" | bc -l) )); then
alerts+=("内存使用率过高: ${mem_usage}%")
fi
# 检查磁盘使用率
if [ $disk_usage -ge $DISK_THRESHOLD ]; then
alerts+=("磁盘使用率过高: ${disk_usage}%")
fi
# 如果有告警则发送通知
if [ ${#alerts[@]} -gt 0 ]; then
# 拼接告警信息
message="系统告警通知:\n$(printf '%s\n' "${alerts[@]}")"
# 发送邮件通知(需要系统配置好mailutils)
echo -e "$message" | mail -s "【紧急】系统异常告警" admin@example.com
# 同时记录到日志文件
echo "$(date "+%Y-%m-%d %H:%M:%S") - $message" >> /var/log/system_alerts.log
fi
这个脚本做了几处重要改进:
- 同时监控CPU、内存、磁盘三个关键指标
- 使用数组收集多个告警信息
- 同时支持邮件通知和本地日志记录
- 添加了时间戳便于追踪
四、高级功能:告警抑制与升级
频繁告警会导致"狼来了"效应,我们需要实现更智能的告警策略:
#!/bin/bash
# 配置参数
CPU_THRESHOLD=80
ALERT_INTERVAL=3600 # 相同告警最小间隔(秒)
ALERT_COUNT_FILE="/tmp/alert_count.txt"
# 获取CPU使用率
cpu_usage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
# 检查是否超过阈值
if (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l) )); then
current_time=$(date +%s)
last_alert_time=0
alert_count=0
# 读取上次告警记录
if [ -f "$ALERT_COUNT_FILE" ]; then
read last_alert_time alert_count < "$ALERT_COUNT_FILE"
fi
# 计算时间差
time_diff=$((current_time - last_alert_time))
# 判断是否需要发送告警
if [ $time_diff -ge $ALERT_INTERVAL ]; then
# 发送普通告警
message="CPU使用率持续过高: ${cpu_usage}%"
echo "$message" | mail -s "系统告警" admin@example.com
# 如果是第3次告警,升级为紧急告警
if [ $alert_count -ge 2 ]; then
echo "$message" | mail -s "【紧急】系统告警" admin@example.com
alert_count=0 # 重置计数器
else
((alert_count++))
fi
# 更新告警记录
echo "$current_time $alert_count" > "$ALERT_COUNT_FILE"
fi
fi
这个脚本实现了:
- 告警抑制:避免短时间内重复告警
- 告警升级:持续异常时提升告警级别
- 状态持久化:记录告警次数和时间
五、通知渠道扩展
除了邮件,我们还可以集成更多通知方式。以下是集成企业微信机器人的示例(技术栈:Bash Shell + cURL):
#!/bin/bash
# 企业微信机器人Webhook地址
WEBHOOK_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=your-key"
# 构造JSON消息体
build_wechat_message() {
local content="$1"
cat <<EOF
{
"msgtype": "text",
"text": {
"content": "$content",
"mentioned_mobile_list":["13800001111"] # 要@的群成员手机号
}
}
EOF
}
# 监控磁盘空间
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
if [ $disk_usage -gt 90 ]; then
message="【服务器告警】磁盘使用率已达 ${disk_usage}%,请及时处理!"
# 发送到企业微信
curl -s -H "Content-Type: application/json" \
-d "$(build_wechat_message "$message")" \
$WEBHOOK_URL >/dev/null
# 同时发送邮件备份
echo "$message" | mail -s "磁盘空间告警" admin@example.com
fi
这个方案的优势在于:
- 多通道通知,提高触达率
- 支持移动端即时提醒
- 可以@特定负责人
- 与现有监控系统无缝集成
六、最佳实践与注意事项
在实施自动化告警系统时,有几个关键点需要注意:
阈值设置要合理:太敏感会导致告警泛滥,太宽松会漏掉重要问题。建议:
- 先观察系统正常运行时的基准值
- 设置多级阈值(警告、严重、紧急)
- 针对不同时段设置动态阈值
告警信息要明确:每条告警应该包含:
- 明确的告警级别
- 具体的异常指标
- 发生时间
- 可能的影响范围
- 建议的处置措施
维护告警历史:完整的告警日志有助于:
- 分析系统稳定性趋势
- 追踪告警处置情况
- 优化告警策略
定期测试告警通道:建议每月测试一次所有告警通道,确保:
- 通知能够正常送达
- 接收人联系方式是最新的
- 各集成接口仍然有效
七、总结
通过Shell脚本实现系统告警自动化,我们可以将运维人员从24小时待命的状态中解放出来。从简单的磁盘监控到复杂的多指标告警系统,Shell脚本以其轻量、灵活的特性,成为系统监控的理想工具。
一个好的告警系统应该像经验丰富的值班医生,能够准确判断病情轻重,及时通知正确的负责人,同时记录完整的"病历"。希望本文介绍的技巧能够帮助你打造出更智能、更可靠的系统告警方案。
记住,告警不是目的,快速解决问题才是。在设计告警系统时,始终要以" actionable alert "(可操作的告警)为目标,确保每一条告警都能引导运维人员采取正确的行动。
评论