#!/bin/bash
# 系统监控脚本 - 每日执行版
# 通过crontab每天00:01触发,执行到23:59:59结束
# 使用方法:添加到crontab - 01 00 * * * /root/sys_monitor.sh# 定义日志目录和文件
LOG_DIR="/root/logs/sys_monitor"
CURRENT_DATE=$(date '+%Y-%m-%d')
LOG_FILE="${LOG_DIR}/monitor_${CURRENT_DATE}.log"# 创建日志目录
mkdir -p $LOG_DIR# 清理15天前的旧日志文件
# 监控内容:删除超过15天的监控日志文件
# 异常阈值:超过15天的日志文件将被自动删除
find $LOG_DIR -name "monitor_*.log" -mtime +15 -delete
echo "已清理15天前的旧日志文件" >> $LOG_FILE# 定义监控阈值
CPU_THRESHOLD=80 # CPU使用率超过80%为异常
MEM_THRESHOLD=90 # 内存使用率超过90%为异常
IO_WAIT_THRESHOLD=5 # IO等待时间超过5%为异常
LOAD_THRESHOLD=$(grep -c ^processor /proc/cpuinfo) # 负载超过CPU核心数为异常
DISK_THRESHOLD=90 # 磁盘使用率超过90%为异常
NET_CONN_THRESHOLD=1000 # 网络连接数超过1000为异常# 脚本开始执行时间
START_TIME=$(date '+%Y-%m-%d %H:%M:%S')
echo "系统监控脚本启动 - 启动时间: $START_TIME" >> $LOG_FILE
echo "监控阈值设置:" >> $LOG_FILE
echo "CPU: ${CPU_THRESHOLD}% | 内存: ${MEM_THRESHOLD}% | IO等待: ${IO_WAIT_THRESHOLD}%" >> $LOG_FILE
echo "负载: ${LOAD_THRESHOLD} | 磁盘: ${DISK_THRESHOLD}% | 网络连接: ${NET_CONN_THRESHOLD}" >> $LOG_FILE
echo "==========================================" >> $LOG_FILE# 计算当天结束时间(23:59:59)
END_TIMESTAMP=$(date -d "23:59:59" +%s)# 主监控循环 - 持续运行直到当天结束
while [ $(date +%s) -le $END_TIMESTAMP ]; dotimestamp=$(date '+%Y-%m-%d %H:%M:%S')abnormal_count=0abnormal_processes=""echo "=== $timestamp ===" >> $LOG_FILE# 监控CPU使用率# 监控内容:总体CPU使用率百分比# 异常阈值:持续高于80%表示CPU负载过重cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)echo "CPU使用率: ${cpu_usage}%" >> $LOG_FILEif (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l 2>/dev/null) )); thenecho "⚠️ CPU使用率异常!当前: ${cpu_usage}%" >> $LOG_FILEabnormal_count=$((abnormal_count+1))# 记录CPU使用率前5的进程echo "CPU占用前5进程:" >> $LOG_FILEps aux --sort=-%cpu | awk 'NR<=6 && NR>1' >> $LOG_FILEabnormal_processes="${abnormal_processes} CPU"fi# 监控内存使用率# 监控内容:物理内存使用百分比# 异常阈值:超过90%可能导致系统开始使用交换空间mem_usage=$(free -m | awk 'NR==2{printf "%.2f", $3*100/$2}')echo "内存使用率: ${mem_usage}%" >> $LOG_FILEif (( $(echo "$mem_usage > $MEM_THRESHOLD" | bc -l 2>/dev/null) )); thenecho "⚠️ 内存使用率异常!当前: ${mem_usage}%" >> $LOG_FILEabnormal_count=$((abnormal_count+1))# 记录内存使用率前5的进程echo "内存占用前5进程:" >> $LOG_FILEps aux --sort=-%mem | awk 'NR<=6 && NR>1' >> $LOG_FILEabnormal_processes="${abnormal_processes} 内存"fi# 监控IO等待时间# 监控内容:CPU等待IO操作的时间百分比# 异常阈值:超过5%表示磁盘IO可能成为瓶颈io_wait=$(iostat -c 2>/dev/null | awk 'NR==4{print $4}' | cut -d'%' -f1)if [ -n "$io_wait" ]; thenecho "IO等待时间: ${io_wait}%" >> $LOG_FILEif (( $(echo "$io_wait > $IO_WAIT_THRESHOLD" | bc -l 2>/dev/null) )); thenecho "⚠️ IO等待时间异常!当前: ${io_wait}%" >> $LOG_FILEabnormal_count=$((abnormal_count+1))# 记录可能产生高IO的进程echo "可能产生高IO的进程:" >> $LOG_FILEps aux --sort=-%cpu | awk 'NR<=6 && NR>1' >> $LOG_FILEabnormal_processes="${abnormal_processes} IO"fielseecho "IO等待时间: 无法获取" >> $LOG_FILEfi# 监控系统负载# 监控内容:系统1分钟平均负载# 异常阈值:超过CPU核心数表示系统过载load_1min=$(uptime | awk -F'load average:' '{print $2}' | awk -F, '{print $1}' | sed 's/ //g')echo "系统负载(1分钟): ${load_1min}" >> $LOG_FILEif (( $(echo "$load_1min > $LOAD_THRESHOLD" | bc -l 2>/dev/null) )); thenecho "⚠️ 系统负载异常!当前: ${load_1min},CPU核心数: ${LOAD_THRESHOLD}" >> $LOG_FILEabnormal_count=$((abnormal_count+1))# 记录活跃进程echo "活跃进程列表:" >> $LOG_FILEps aux --sort=-%cpu | awk 'NR<=6 && NR>1' >> $LOG_FILEabnormal_processes="${abnormal_processes} 负载"fi# 监控磁盘空间使用率# 监控内容:根分区磁盘使用百分比# 异常阈值:超过90%可能导致系统无法写入新文件disk_usage=$(df / | awk 'NR==2{print $5}' | cut -d'%' -f1)echo "磁盘使用率: ${disk_usage}%" >> $LOG_FILEif [ "$disk_usage" -gt "$DISK_THRESHOLD" ] 2>/dev/null; thenecho "⚠️ 磁盘空间异常!当前: ${disk_usage}%" >> $LOG_FILEabnormal_count=$((abnormal_count+1))# 记录大文件(前5个)echo "根分区大文件前5:" >> $LOG_FILEfind / -type f -size +100M 2>/dev/null | head -5 >> $LOG_FILEabnormal_processes="${abnormal_processes} 磁盘"fi# 监控网络连接数# 监控内容:当前TCP连接总数# 异常阈值:超过1000个连接可能表示网络过载或异常if command -v ss >/dev/null 2>&1; thennet_connections=$(ss -tun 2>/dev/null | wc -l)net_connections=$((net_connections-1)) # 减去标题行echo "网络连接数: ${net_connections}" >> $LOG_FILEif [ "$net_connections" -gt "$NET_CONN_THRESHOLD" ] 2>/dev/null; thenecho "⚠️ 网络连接数异常!当前: ${net_connections}" >> $LOG_FILEabnormal_count=$((abnormal_count+1))# 记录网络连接数前5的进程echo "网络连接数前5进程:" >> $LOG_FILEss -tunp 2>/dev/null | awk '{print $7}' | cut -d':' -f2 | sort | uniq -c | sort -rn | head -5 >> $LOG_FILEabnormal_processes="${abnormal_processes} 网络"fielseecho "网络连接数: ss命令不可用" >> $LOG_FILEfi# 汇总异常信息if [ $abnormal_count -gt 0 ]; thenecho "🚨 发现 ${abnormal_count} 个异常指标:${abnormal_processes}" >> $LOG_FILEecho "当前时间点进程快照(按CPU排序前10):" >> $LOG_FILEps aux --sort=-%cpu | awk 'NR<=11 && NR>1' >> $LOG_FILEelseecho "✅ 所有指标正常" >> $LOG_FILEfiecho "---" >> $LOG_FILE# 计算距离当天结束还有多少秒current_timestamp=$(date +%s)remaining_seconds=$((END_TIMESTAMP - current_timestamp))# 如果剩余时间不足5秒,则调整为剩余时间if [ $remaining_seconds -lt 5 ]; thensleep $remaining_secondselsesleep 5fi
done# 脚本结束执行时间
END_TIME=$(date '+%Y-%m-%d %H:%M:%S')
echo "系统监控脚本结束 - 结束时间: $END_TIME" >> $LOG_FILE
echo "当日监控任务完成,日志文件: $LOG_FILE" >> $LOG_FILE