📋 详细大纲
- 1.
明确监控目标与指标
- •
核心指标:CPU使用率与负载、内存使用率、磁盘空间使用率、磁盘I/O等待时间、网络带宽流量、关键进程状态。
- •
辅助指标:系统运行时间、登录用户数、网络连接数、系统日志中的错误信息。
- •
- 2.
设计监控脚本结构
- •
参数配置区:定义各项监控指标的阈值、报警邮箱、日志文件路径等。
- •
数据采集函数:为每个监控指标编写独立的数据采集函数。
- •
阈值判断与报警逻辑:将采集到的数据与预设阈值比较,超出阈值则触发报警。
- •
日志记录功能:所有监控操作和报警信息都应记录到日志文件中,便于追溯。
- •
- 3.
实现报警机制
- •
邮件报警 (最常用):使用
mail
命令或msmtp
等工具发送报警邮件。需预先配置SMTP服务(如QQ邮箱的SMTP服务及其授权码)。 - •
其他报警方式:企业微信、钉钉机器人等,通常通过调用Webhook API实现。
- •
- 4.
部署与定时执行
- •
为脚本添加可执行权限 (
chmod +x
)。 - •
利用 cron计划任务 定时执行脚本,例如:
- •
0 * * * * /path/to/script.sh
(每小时) - •
*/30 * * * * /path/to/script.sh
(每30分钟)
- •
- •
- 5.
考虑进阶功能与优化
- •
日志轮转 (Log Rotation):防止日志文件过大,可配合
logrotate
工具或脚本自行清理旧日志。 - •
安全考虑:脚本中涉及密码、授权码等敏感信息,应注意权限控制(如设置配置文件为
600
权限)。 - •
性能影响:监控脚本本身应轻量,避免频繁执行或复杂操作消耗过多系统资源。
- •
集中监控:对于多台服务器,考虑使用 Zabbix、Prometheus 等专业监控系统,功能更强大、全面。
- •
一份通过Shell脚本实现Linux系统资源监控与邮件告警的实用指南
本文将详细介绍如何使用Shell脚本监控Linux系统的CPU使用率、内存使用率、磁盘使用率、IO等待时间以及网络流量,并在资源使用超过设定阈值时自动发送邮件告警。这套方案轻量、灵活,非常适合中小型项目或个人服务器使用。
一、监控脚本核心命令概述
在开始编写监控脚本前,我们先了解一些Linux系统监控的基础命令:
命令 | 主要功能 | 常用示例 |
---|---|---|
top /htop |
实时查看CPU、内存、进程负载 | top -bn1 (批处理模式) |
vmstat |
报告进程、内存、分页、块IO、陷阱和CPU活动 | vmstat 1 5 (每秒刷新,共5次) |
iostat |
监控系统输入输出设备和CPU使用情况 | iostat -dx 2 (每2秒刷新) |
free |
显示内存使用情况 | free -m (以MB为单位显示) |
df |
报告文件系统磁盘空间使用情况 | df -h (人类可读格式) |
iftop /nload |
实时网络流量监控 | iftop -i eth0 (监控指定网卡) |
这些命令为我们编写监控脚本提供了基础数据来源。
二、完整监控脚本实现
下面是一个综合性的监控脚本,它涵盖了CPU、内存、磁盘、IO等待和网络流量的监控,并支持邮件告警功能。
#!/bin/bash
#############################################################################
# 系统资源监控脚本
# 功能:监控CPU、内存、磁盘、IO等待和网络流量,支持邮件告警
# 配置说明:使用前请修改以下配置项以适应您的环境
#############################################################################
# ======================
# 核心配置区(必须修改)
# ======================
# 告警阈值配置
CPU_THRESHOLD=80 # CPU使用率阈值(%)
MEM_THRESHOLD=80 # 内存使用率阈值(%)
DISK_THRESHOLD=80 # 根分区磁盘使用率阈值(%)
IO_THRESHOLD=50 # IO await阈值(毫秒)
NET_THRESHOLD=10 # 网络流量阈值(MB/s)
# 网络监控配置
INTERFACE="eth0" # 监控的网卡名称(通过ifconfig或ip addr查看)
# 邮件配置(以QQ邮箱为例)
MAIL_TO="your_email@qq.com" # 接收告警的邮箱
SMTP_USER="your_qq@qq.com" # 发件邮箱(需开启SMTP服务)
SMTP_PASSWORD="your_authorization_code" # 邮箱授权码(不是登录密码)
SMTP_SERVER="smtp.qq.com" # SMTP服务器地址
SMTP_PORT="465" # SMTP端口
# 日志配置
LOG_FILE="/var/log/system_monitor.log" # 监控日志文件路径
# ======================
# 函数定义区
# ======================
# 初始化邮件配置
setup_mail_config() {
# 检查是否已安装msmtp
if ! command -v msmtp &> /dev/null; then
echo "[错误] msmtp未安装,请先执行安装: sudo apt install msmtp -y 或 sudo yum install msmtp -y"
exit 1
fi
# 创建msmtp配置文件
local MAIL_CONFIG="$HOME/.msmtprc"
cat > "$MAIL_CONFIG" << EOF
# 默认账户
account default
host ${SMTP_SERVER}
port ${SMTP_PORT}
from ${SMTP_USER}
auth on
user ${SMTP_USER}
password ${SMTP_PASSWORD}
tls on
tls_starttls off
tls_certcheck off
logfile ${LOG_FILE}
EOF
# 设置配置文件权限
chmod 600 "$MAIL_CONFIG"
echo "[信息] 邮件配置完成" >> "$LOG_FILE"
}
# 发送邮件函数
send_alert_mail() {
local subject="$1"
local content="$2"
{
echo "Subject: $subject"
echo "From: $SMTP_USER"
echo "To: $MAIL_TO"
echo
echo -e "$content"
echo
echo "监控时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "主机名: $(hostname)"
} | msmtp --from="$SMTP_USER" "$MAIL_TO" 2>> "$LOG_FILE"
}
# 记录日志函数
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 检查CPU使用率
check_cpu() {
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4}' | cut -d'%' -f1)
local cpu_rounded=$(printf "%.0f" "$cpu_usage")
if [ "$cpu_rounded" -ge "$CPU_THRESHOLD" ]; then
send_alert_mail "CPU告警" "CPU使用率过高:${cpu_rounded}% (阈值:${CPU_THRESHOLD}%)"
log_message "CPU使用率过高:${cpu_rounded}%"
fi
}
# 检查内存使用率
check_memory() {
local mem_usage=$(free | awk '/Mem/{printf "%.0f", $3/$2 * 100}')
if [ "$mem_usage" -ge "$MEM_THRESHOLD" ]; then
send_alert_mail "内存告警" "内存使用率过高:${mem_usage}% (阈值:${MEM_THRESHOLD}%)"
log_message "内存使用率过高:${mem_usage}%"
fi
}
# 检查磁盘使用率
check_disk() {
local disk_usage=$(df -h / | awk 'NR==2{print $5}' | tr -d '%')
if [ "$disk_usage" -ge "$DISK_THRESHOLD" ]; then
send_alert_mail "磁盘告警" "根分区磁盘使用率过高:${disk_usage}% (阈值:${DISK_THRESHOLD}%)"
log_message "磁盘使用率过高:${disk_usage}%"
fi
}
# 检查IO等待时间
check_io() {
if ! command -v iostat &> /dev/null; then
log_message "警告:iostat未安装,无法监控IO状态"
return
fi
local io_wait=$(iostat -x 1 2 | awk '/^avg-cpu/{getline; print $NF}' | tail -n1)
local io_rounded=$(printf "%.0f" "$io_wait")
if [ "$io_rounded" -ge "$IO_THRESHOLD" ]; then
send_alert_mail "IO等待告警" "磁盘IO等待时间过高:${io_rounded}ms (阈值:${IO_THRESHOLD}ms)"
log_message "IO等待时间过高:${io_rounded}ms"
fi
}
# 检查网络流量
check_network() {
if [ ! -d "/sys/class/net/$INTERFACE" ]; then
log_message "错误:网络接口 $INTERFACE 不存在"
return
fi
# 获取初始流量数据
local rx_bytes_start=$(cat /sys/class/net/$INTERFACE/statistics/rx_bytes)
local tx_bytes_start=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes)
# 等待1秒再次测量
sleep 1
local rx_bytes_end=$(cat /sys/class/net/$INTERFACE/statistics/rx_bytes)
local tx_bytes_end=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes)
# 计算流量速率(MB/s)
local rx_rate=$(( (rx_bytes_end - rx_bytes_start) / 1024 / 1024 ))
local tx_rate=$(( (tx_bytes_end - tx_bytes_start) / 1024 / 1024 ))
if [ "$rx_rate" -ge "$NET_THRESHOLD" ]; then
send_alert_mail "网络下载流量告警" "下载流量过高:${rx_rate}MB/s (阈值:${NET_THRESHOLD}MB/s)"
log_message "下载流量过高:${rx_rate}MB/s"
fi
if [ "$tx_rate" -ge "$NET_THRESHOLD" ]; then
send_alert_mail "网络上载流量告警" "上传流量过高:${tx_rate}MB/s (阈值:${NET_THRESHOLD}MB/s)"
log_message "上传流量过高:${tx_rate}MB/s"
fi
}
# ======================
# 主程序
# ======================
# 初始化日志文件
if [ ! -f "$LOG_FILE" ]; then
touch "$LOG_FILE"
chmod 644 "$LOG_FILE"
fi
# 初始化邮件配置
setup_mail_config
log_message "开始系统监控检查..."
# 执行所有监控检查
check_cpu
check_memory
check_disk
check_io
check_network
log_message "系统监控检查完成"
三、脚本使用说明
1. 前置准备工作
在使用此脚本前,需要完成以下准备工作:
安装必要工具:
# Ubuntu/Debian系统 sudo apt update sudo apt install sysstat msmtp mailutils -y # CentOS/RHEL系统 sudo yum install sysstat msmtp mailx -y
配置邮箱SMTP服务:
- 登录您的QQ邮箱(或其他支持SMTP的邮箱)
- 进入「设置」→「账户」
- 开启「POP3/SMTP服务」
- 获取「授权码」(不是邮箱密码)
2. 脚本配置
使用前,请修改脚本「核心配置区」中的以下参数:
- 告警阈值:根据您的需求调整各指标阈值
- 网络接口:通过
ifconfig
或ip addr
命令查看并设置正确的网卡名称 - 邮箱配置:填写您的发件邮箱、授权码和收件邮箱
3. 运行方式
- 将脚本保存为
system_monitor.sh
- 添加执行权限:
chmod +x system_monitor.sh
- 手动测试运行:
./system_monitor.sh
4. 设置定时任务
要实现自动监控,需要设置cron定时任务:
- 编辑cron任务:
crontab -e
- 添加以下行(每30分钟检查一次):
*/30 * * * * /path/to/system_monitor.sh > /dev/null 2>&1
- 保存并退出
四、故障排除与常见问题
邮件发送失败:
- 检查邮箱授权码是否正确(注意不是邮箱密码)
- 确认SMTP服务器地址和端口是否正确
- 检查系统防火墙是否允许SMTP通信
命令不存在错误:
- 确保已安装所有必要工具(sysstat、msmtp)
- 对于IO监控,需要安装sysstat包
网络接口不存在错误:
- 使用
ifconfig
或ip addr
命令确认正确的网卡名称
- 使用
脚本执行权限错误:
- 使用
chmod +x script.sh
为脚本添加执行权限
- 使用
五、进阶改进建议
当基本监控满足需求后,可以考虑以下进阶改进:
添加进程监控:监控关键进程的存活状态
check_process() { if ! pgrep -x "$1" > /dev/null; then echo "[错误] 进程 $1 未运行!" fi }
数据可视化:将监控数据保存到数据库中,并使用Grafana等工具进行可视化展示
集成专业监控工具:随着需求增长,可以考虑集成Zabbix、Prometheus等专业监控工具
生成HTML报告:使用awk生成HTML格式的报告,更直观展示系统状态
六、总结
💎 核心总结
编写 Linux 系统监控脚本是一项非常实用的运维技能。其核心思路是:“采集 - 判断 - 报警”。
- 1.
采集是关键:熟练使用
top
,free
,df
,iostat
,/sys/class/net/
等命令和接口是基础。 - 2.
判断要准确:在脚本中合理设置阈值(如CPU使用率80%),并进行数值比较。
- 3.
报警须可靠:邮件报警是常见方式,务必正确配置SMTP。记得处理报警风暴,避免频繁发送。
- 4.
自动化运行:通过 cron 让脚本在后台定时执行,实现真正自动化的监控。
- 5.
记录很重要:详细的日志有助于问题排查和历史回顾。
对于初学者,可以从监控一两个关键指标(如CPU和磁盘)开始,逐步增加功能。对于复杂环境或更高要求,建议直接采用成熟的监控平台如 Zabbix 或 Prometheus,它们提供了更完善的数据采集、存储、可视化、报警和扩展能力。
注意事项:
- 所有脚本应在测试环境验证后再投入生产环境使用
- 定期检查日志文件(
/var/log/system_monitor.log
)以确保监控正常运行 - 根据实际硬件性能和服务负载调整监控阈值
希望本文能帮助您构建有效的系统监控方案。如有任何问题或建议,欢迎交流讨论!