当前位置: 首页 > java >正文

Shell 脚本实现系统监控与告警

Shell 脚本实现系统监控与告警

文章目录

    • Shell 脚本实现系统监控与告警
      • 一、脚本整体设计
      • 二、脚本文件(system_monitor.sh)
      • 三、前置准备(必做)
        • 1. 安装依赖工具
        • 2. 配置SMTP邮件服务
      • 四、脚本使用步骤
      • 五、关键说明
      • 六、常见问题排查

以下是一套完整的系统监控Shell脚本,包含CPU、内存、硬盘、IO、网络流量监控及邮件告警功能,支持配置化调整阈值,便于维护和扩展。

一、脚本整体设计

  1. 配置与告警分离:将监控阈值、邮件参数等配置项集中管理,便于修改。
  2. 模块化监控:按“CPU/内存/硬盘/IO/网络”拆分监控逻辑,结构清晰。
  3. 邮件告警优化:支持HTML格式邮件,告警信息排版清晰,附带监控时间和主机信息。
  4. 兼容性:适配CentOS/Ubuntu等主流Linux发行版(依赖vmstatiostatifstat等工具,需提前安装)。

二、脚本文件(system_monitor.sh)

#!/bin/bash
# 系统监控脚本:CPU/内存/硬盘/IO/网络流量监控 + 邮件告警
# 依赖工具:vmstat, iostat, ifstat, df, free, grep, awk, sendmail/postfix##############################################################################
# 1. 配置区(根据实际需求修改以下参数)
##############################################################################
# 监控阈值配置
CPU_THRESHOLD=80          # CPU使用率阈值(%)
MEM_THRESHOLD=80          # 内存使用率阈值(%)
DISK_THRESHOLD=80         # 硬盘使用率阈值(%)
IO_AWAIT_THRESHOLD=50     # IO等待时间阈值(ms)
NET_THRESHOLD=10          # 网络流量阈值(Mbps,上传+下载)# 邮件告警配置
SMTP_SERVER="smtp.qq.com" # SMTP服务器(如QQ邮箱:smtp.qq.com,163邮箱:smtp.163.com)
SMTP_PORT=587             # SMTP端口(QQ/163常用587或465)
SMTP_USER="your_email@qq.com" # 发件人邮箱
SMTP_PASS="your_auth_code"    # 邮箱授权码(非登录密码,需在邮箱设置中开启SMTP并获取)
ALERT_EMAIL="alert_target@example.com" # 告警接收邮箱# 其他配置
MONITOR_INTERVAL=60       # 监控间隔(秒),建议60秒以上避免频繁告警
NETWORK_INTERFACE="eth0"  # 监控的网络接口(用`ifconfig`查看,如eth0、ens33、wlan0)
HOSTNAME=$(hostname)      # 主机名(用于告警邮件标识)
CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S") # 当前时间##############################################################################
# 2. 工具依赖检查
##############################################################################
check_dependencies() {local dependencies=("vmstat" "iostat" "ifstat" "sendmail" "awk" "grep" "free" "df")for tool in "${dependencies[@]}"; doif ! command -v $tool &> /dev/null; thenecho "错误:缺少依赖工具 $tool,请先安装!"exit 1fidone
}##############################################################################
# 3. 邮件发送函数(HTML格式,支持中文)
##############################################################################
send_alert_email() {local subject="$1"local content="$2"# 构造邮件内容(HTML格式,支持换行和加粗)local email_body="
From: $SMTP_USER
To: $ALERT_EMAIL
Subject: $subject
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8<html>
<head><title>系统监控告警</title></head>
<body>
<h3>⚠️  主机 $HOSTNAME 告警通知</h3>
<p>告警时间:$CURRENT_TIME</p>
<p>告警详情:</p>
$content
</body>
</html>"# 通过sendmail发送邮件(需提前配置好SMTP服务,如postfix+sendmail)echo -e "$email_body" | sendmail -v $ALERT_EMAILif [ $? -eq 0 ]; thenecho "[$CURRENT_TIME] 告警邮件已发送至 $ALERT_EMAIL"elseecho "[$CURRENT_TIME] 告警邮件发送失败!"fi
}##############################################################################
# 4. 监控模块:CPU使用率
##############################################################################
monitor_cpu() {# 通过vmstat获取CPU使用率(idle为空闲率,100-idle即为使用率)local cpu_idle=$(vmstat 1 2 | tail -1 | awk '{print $15}')local cpu_usage=$((100 - cpu_idle))echo "[$CURRENT_TIME] CPU使用率:$cpu_usage%"if [ $cpu_usage -ge $CPU_THRESHOLD ]; thenlocal subject="【系统告警】CPU使用率超标"local content="<p>🔹 当前CPU使用率:<b>$cpu_usage%</b></p><p>🔹 阈值:$CPU_THRESHOLD%</p>"send_alert_email "$subject" "$content"fi
}##############################################################################
# 5. 监控模块:内存使用率
##############################################################################
monitor_memory() {# 通过free获取内存信息(单位:KB)local mem_total=$(free -k | grep Mem | awk '{print $2}')local mem_used=$(free -k | grep Mem | awk '{print $3}')# 计算使用率(四舍五入取整)local mem_usage=$(( (mem_used * 100 + mem_total / 2) / mem_total ))echo "[$CURRENT_TIME] 内存使用率:$mem_usage%"if [ $mem_usage -ge $MEM_THRESHOLD ]; thenlocal subject="【系统告警】内存使用率超标"local content="<p>🔹 当前内存使用率:<b>$mem_usage%</b></p><p>🔹 阈值:$MEM_THRESHOLD%</p><p>🔹 总内存:$((mem_total/1024))MB,已用:$((mem_used/1024))MB</p>"send_alert_email "$subject" "$content"fi
}##############################################################################
# 6. 监控模块:硬盘使用率
##############################################################################
monitor_disk() {# 监控所有挂载的硬盘分区(排除tmpfs等虚拟文件系统)local disk_info=$(df -hP | grep -vE 'tmpfs|udev|loop' | awk '{print $6,$5}')echo "[$CURRENT_TIME] 硬盘分区使用率:"echo "$disk_info" | while read -r mount_point usage; do# 去掉使用率的"%"符号,转为数字local usage_num=${usage%\%}echo "  - $mount_point$usage"if [ $usage_num -ge $DISK_THRESHOLD ]; thenlocal subject="【系统告警】硬盘使用率超标"local content="<p>🔹 分区:<b>$mount_point</b></p><p>🔹 当前使用率:<b>$usage</b></p><p>🔹 阈值:$DISK_THRESHOLD%</p>"send_alert_email "$subject" "$content"fidone
}##############################################################################
# 7. 监控模块:IO等待时间(await)
##############################################################################
monitor_io() {# 通过iostat获取IO信息(await:平均等待时间,单位ms)# 取2次采样(间隔1秒),避免瞬时值干扰local io_await=$(iostat -x 1 2 | grep -A1 "^Device" | tail -1 | awk '{print $10}')# 转为整数(四舍五入)local io_await_int=$(printf "%.0f" "$io_await")echo "[$CURRENT_TIME] IO平均等待时间:$io_await_int ms"if [ $io_await_int -ge $IO_AWAIT_THRESHOLD ]; thenlocal subject="【系统告警】IO等待时间超标"local content="<p>🔹 当前IO等待时间:<b>$io_await_int ms</b></p><p>🔹 阈值:$IO_AWAIT_THRESHOLD ms</p>"send_alert_email "$subject" "$content"fi
}##############################################################################
# 8. 监控模块:网络流量(上传+下载)
##############################################################################
monitor_network() {# 通过ifstat获取指定接口的流量(单位:KB/s)# 取2次采样(间隔1秒),计算平均速率local net_stats=$(ifstat -i $NETWORK_INTERFACE 1 2 | grep -v "^ " | tail -1)local download_kbps=$(echo "$net_stats" | awk '{print $1}') # 下载速率(KB/s)local upload_kbps=$(echo "$net_stats" | awk '{print $2}')   # 上传速率(KB/s)# 转为Mbps(1Mbps = 128KB/s),四舍五入取1位小数local download_mbps=$(printf "%.1f" "$(echo "$download_kbps / 128" | bc -l)")local upload_mbps=$(printf "%.1f" "$(echo "$upload_kbps / 128" | bc -l)")local total_mbps=$(printf "%.1f" "$(echo "$download_mbps + $upload_mbps" | bc -l)")echo "[$CURRENT_TIME] 网络流量($NETWORK_INTERFACE):"echo "  - 下载:$download_mbps Mbps,上传:$upload_mbps Mbps,总计:$total_mbps Mbps"# 转为整数比较(避免小数精度问题)local total_int=$(printf "%.0f" "$total_mbps")if [ $total_int -ge $NET_THRESHOLD ]; thenlocal subject="【系统告警】网络流量超标"local content="<p>🔹 接口:<b>$NETWORK_INTERFACE</b></p><p>🔹 总流量:<b>$total_mbps Mbps</b></p><p>🔹 下载:$download_mbps Mbps,上传:$upload_mbps Mbps</p><p>🔹 阈值:$NET_THRESHOLD Mbps</p>"send_alert_email "$subject" "$content"fi
}##############################################################################
# 9. 主执行函数
##############################################################################
main() {echo "======================================"echo "系统监控脚本启动(主机:$HOSTNAME)"echo "监控间隔:$MONITOR_INTERVAL 秒"echo "阈值配置:CPU=$CPU_THRESHOLD% | 内存=$MEM_THRESHOLD% | 硬盘=$DISK_THRESHOLD% | IO等待=$IO_AWAIT_THRESHOLD ms | 网络=$NET_THRESHOLD Mbps"echo "======================================"# 先检查依赖工具check_dependencies# 循环执行监控(无限循环,可通过Ctrl+C停止)while true; doecho -e "\n--------------------------------------"monitor_cpumonitor_memorymonitor_diskmonitor_iomonitor_networkecho "--------------------------------------"echo "等待 $MONITOR_INTERVAL 秒后再次监控..."sleep $MONITOR_INTERVALdone
}# 启动主函数
main

三、前置准备(必做)

1. 安装依赖工具

脚本依赖以下工具,需提前安装:

# CentOS/RHEL
yum install -y sysstat ifstat sendmail postfix bc# Ubuntu/Debian
apt update && apt install -y sysstat ifstat sendmail postfix bc
2. 配置SMTP邮件服务

脚本通过sendmail发送邮件,需配置SMTP服务(以QQ邮箱为例):

  1. 登录QQ邮箱 → 【设置】→ 【账户】→ 开启“POP3/SMTP服务”,获取授权码(不是登录密码)。
  2. 配置postfix的SMTP中继(以QQ邮箱为例):
    # 编辑postfix配置文件
    vi /etc/postfix/main.cf
    
    添加以下配置(替换为你的邮箱信息):
    relayhost = [smtp.qq.com]:587  # SMTP服务器及端口
    smtp_use_tls = yes
    smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
    smtp_sasl_auth_enable = yes
    smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
    smtp_sasl_security_options = noanonymous
    
  3. 创建SMTP密码文件:
    echo "[smtp.qq.com]:587 your_email@qq.com:your_auth_code" > /etc/postfix/sasl_passwd
    chmod 600 /etc/postfix/sasl_passwd
    postmap /etc/postfix/sasl_passwd
    
  4. 重启postfix和sendmail服务:
    systemctl restart postfix sendmail
    systemctl enable postfix sendmail
    

四、脚本使用步骤

  1. 修改配置:打开system_monitor.sh,根据实际需求修改“配置区”参数(尤其是邮件信息和网络接口)。
  2. 添加执行权限
    chmod +x system_monitor.sh
    
  3. 测试运行
    ./system_monitor.sh
    
    观察输出是否正常,可通过dd if=/dev/zero of=/tmp/test bs=1G count=1等命令模拟高负载测试告警。
  4. 后台运行(推荐)
    为避免终端关闭后脚本停止,使用nohup后台运行:
    nohup ./system_monitor.sh > /var/log/system_monitor.log 2>&1 &
    
    日志会输出到/var/log/system_monitor.log,便于后续排查。

五、关键说明

  1. 阈值调整:网络流量阈值NET_THRESHOLD可根据实际带宽调整(单位:Mbps),例如100Mbps带宽可设为80。
  2. IO等待时间iostatawait指标反映IO请求的平均等待时间(包括队列等待和处理时间),大于50ms通常表示IO压力较大。
  3. 告警频率:脚本按MONITOR_INTERVAL间隔监控,若阈值持续超标,会每次都发送告警。如需“告警抑制”(如5分钟内只发一次),可在发送邮件前添加文件锁判断(例如创建临时文件,5分钟后删除)。
  4. 多接口监控:若需监控多个网络接口,可将NETWORK_INTERFACE改为数组(如("eth0" "eth1")),并修改monitor_network函数为循环遍历接口。

六、常见问题排查

  1. 邮件发送失败
    • 检查postfix日志:tail -f /var/log/maillog
    • 确认SMTP授权码正确,且未开启“异地登录保护”。
  2. IO监控无数据:确保sysstat已安装,且内核支持IO统计(iostat -x有输出则正常)。
  3. 网络流量为0:确认NETWORK_INTERFACE参数与实际接口名称一致(用ifconfigip addr查看)。

通过以上脚本,可实现对系统关键指标的实时监控和及时告警,保障系统稳定运行。

http://www.xdnf.cn/news/20457.html

相关文章:

  • Spring Boot中MyBatis的定义与使用
  • IOC为什么交由spring容器管理?
  • 操作系统研发工作心得体会 - 于复杂性中构建秩序
  • 每日一题(2)
  • MySQL学习记录-索引
  • 携程社招前端面经
  • pthread_detach函数
  • 2025最新超详细FreeRTOS入门教程:第二章 FreeRTOS任务创建
  • 设计一个 AB 测试平台
  • 实例和对象的区别
  • 【目录-单选】鸿蒙HarmonyOS开发者基础
  • 自适应滤波器:Ch4 最小均方(LMS)算法
  • [光学原理与应用-433]:晶体光学 - 晶体光学是研究光在单晶体中传播规律及其伴随现象的分支学科,聚焦于各向异性光学媒质的光学特性
  • 上海“我店”模式:消费增值新玩法及其隐忧
  • 论文阅读:VGGT Visual Geometry Grounded Transformer
  • 【C++】引用的本质与高效应用
  • 【高等数学】第十一章 曲线积分与曲面积分——第三节 格林公式及其应用
  • javascript 国际化方法
  • AI 生成式艺术重塑动漫角色创作:从技术逻辑到多元可能性(一)
  • GPT-5发布:统一智能体时代的开启——从“工具”到“协作者”的范式跃迁
  • 详解MySQL环境变量配置及其在备份中的应用
  • 计算机内存的工作原理
  • 打工人日报#20250906
  • 模电仿真软件:MultSim14.3下载与安装
  • 【面板数据】各省制造业出口技术复杂度数据集(2010-2023年)
  • AP1271:高性能低功耗LDO稳压器,为精密电子设备提供稳定动力
  • python graphviz中文测试
  • queue容器的常用函数 和注意事项
  • windows server 2022安装终端
  • 计算机视觉(八):开运算和闭运算