Server 系统性能监控自动报警脚本配置
Server 系统性能监控自动报警脚本配置指南
在现代运维实践中,服务器系统性能的稳定性直接关系到业务连续性与用户体验。当 CPU 使用率持续飙升、内存耗尽或磁盘空间告急时,人工巡检往往滞后于故障发生。因此,构建一套轻量、可靠、可扩展的自动化监控与报警脚本,成为中小规模服务环境中的关键能力。本文将完整介绍如何基于 Linux 环境,使用 Shell 与 Python 协同实现系统级指标采集、阈值判断与多通道报警(邮件+本地日志),无需依赖第三方监控平台,全程可本地部署、自主可控。
一、监控指标设计与采集逻辑
我们聚焦三大核心维度:CPU 平均负载、内存使用率、根分区磁盘使用率。所有数据均通过系统内置命令实时获取,避免额外依赖:
- CPU 负载:取
/proc/loadavg中 5 分钟平均值,对比逻辑处理器数量; - 内存使用率:解析
/proc/meminfo,计算Used / Total × 100%; - 磁盘使用率:调用
df -P /获取根分区挂载点使用百分比。
所有采集操作均控制在毫秒级,单次执行无显著资源开销。
二、Shell 主控脚本:定时触发与状态分发
以下为主控脚本 monitor.sh,负责每 5 分钟调度一次检测,并根据返回码决定是否触发报警:
#!/bin/bash
# monitor.sh —— 系统性能主监控脚本
# 运行方式:chmod +x monitor.sh && ./monitor.sh
# 配置项(可根据实际调整)
ALERT_CPU_LOAD="3.0" # CPU 5分钟负载阈值(按核数倍数设定)
ALERT_MEM_PERCENT="85" # 内存使用率阈值(%)
ALERT_DISK_PERCENT="90" # 根分区磁盘使用率阈值(%)
LOG_FILE="/var/log/system_monitor.log"
ALERT_SCRIPT="/opt/scripts/send_alert.py"
# 记录日志函数
log_info() {
echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] $1" >> "$LOG_FILE"
}
log_alert() {
echo "$(date '+%Y-%m-%d %H:%M:%S') [ALERT] $1" >> "$LOG_FILE"
}
# 获取当前 CPU 负载(5分钟平均)
get_cpu_load() {
awk '{print $2}' /proc/loadavg | tr -d '\n'
}
# 获取内存使用率(整数百分比)
get_mem_usage() {
local total=$(awk '/MemTotal:/ {print $2}' /proc/meminfo)
local free=$(awk '/MemFree:/ {print $2}' /proc/meminfo)
local available=$(awk '/MemAvailable:/ {print $2}' /proc/meminfo)
# 采用 MemAvailable 更准确反映可用内存
if [ -n "$available" ]; then
echo $(( (total - available) * 100 / total ))
else
echo $(( (total - free) * 100 / total ))
fi
}
# 获取根分区磁盘使用率(整数)
get_disk_usage() {
df -P / | awk 'NR==2 {gsub(/%/,"",$5); print $5}'
}
# 执行检测并返回状态码:0=正常,1=需报警
run_check() {
local cpu=$(get_cpu_load)
local mem=$(get_mem_usage)
local disk=$(get_disk_usage)
log_info "CPU=$cpu, MEM=${mem}%, DISK=${disk}%"
# 判断是否超限(支持浮点比较)
awk -v c="$cpu" -v a="$ALERT_CPU_LOAD" \
-v m="$mem" -v am="$ALERT_MEM_PERCENT" \
-v d="$disk" -v ad="$ALERT_DISK_PERCENT" \
'BEGIN { exit (c > a || m > am || d > ad) ? 1 : 0 }'
}
# 主流程
if run_check; then
log_info "All metrics within normal range."
else
log_alert "Threshold exceeded: CPU=$cpu, MEM=${mem}%, DISK=${disk}%"
# 调用 Python 报警模块(支持邮件/钉钉等扩展)
if [ -x "$ALERT_SCRIPT" ]; then
"$ALERT_SCRIPT" \
--cpu "$cpu" \
--mem "$mem" \
--disk "$disk" \
--alert-time "$(date '+%Y-%m-%d %H:%M:%S')"
fi
fi
三、Python 报警模块:多通道通知与容错处理
send_alert.py 实现结构化报警发送,当前支持本地日志与 SMTP 邮件双通道,代码简洁、异常捕获完备:
#!/usr/bin/env python3
# send_alert.py —— 报警通知模块
# 需安装:pip3 install smtplib email
import argparse
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import datetime
import logging
# 日志配置
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [ALERT] %(message)s',
handlers=[logging.FileHandler('/var/log/system_alert.log')]
)
def send_email(cpu, mem, disk, alert_time):
# 邮件配置(请按需修改)
smtp_server = "localhost" # 可替换为真实 SMTP 地址
smtp_port = 25
sender = "monitor@localhost"
recipients = ["admin@example.com"]
subject = f"[ALERT] Server Resource Threshold Exceeded at {alert_time}"
body = f"""\
Server performance alert detected:
Time: {alert_time}
CPU Load (5min): {cpu}
Memory Usage: {mem}%
Root Disk Usage: {disk}%
Please check system health immediately.
"""
try:
msg = MIMEMultipart()
msg["From"] = sender
msg["To"] = ", ".join(recipients)
msg["Subject"] = subject
msg.attach(MIMEText(body, "plain"))
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.send_message(msg)
logging.info(f"Email alert sent to {recipients}")
except Exception as e:
logging.error(f"Failed to send email: {e}")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--cpu", required=True, type=str)
parser.add_argument("--mem", required=True, type=str)
parser.add_argument("--disk", required=True, type=str)
parser.add_argument("--alert-time", required=True, type=str)
args = parser.parse_args()
logging.info(f"Alert triggered: CPU={args.cpu}, MEM={args.mem}%, DISK={args.disk}%")
# 当前启用邮件通道;如需禁用,注释下一行即可
send_email(args.cpu, args.mem, args.disk, args.alert_time)
if __name__ == "__main__":
main()
四、部署与运行保障
将两个脚本保存后,赋予执行权限,并通过 crontab 设置周期任务:
# 添加至 crontab(每 5 分钟执行一次)
*/5 * * * * /opt/scripts/monitor.sh
建议创建专用用户运行脚本,限制其仅具备必要读取权限(如 /proc/、/var/log/)。同时配置 logrotate 对日志文件进行定期轮转,防止磁盘占满。
五、结语
本文提供的监控报警方案以最小依赖、最大透明为设计原则,全部组件均可审计、可调试、可定制。它不替代专业 APM 工具,但在快速响应初期异常、降低人工值守成本方面表现优异。随着业务演进,您可轻松扩展指标类型(如网络连接数、特定进程存活状态)或接入 Webhook 推送至企业微信、飞书等平台。真正的运维效能,始于对系统脉搏的持续感知——而这一切,从一段清晰、稳健、自洽的脚本开始。

