linux 系统指标 简单监控 脚本

#!/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 ]; do
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    abnormal_count=0
    abnormal_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_FILE
    
    if (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l 2>/dev/null) )); then
        echo "⚠️  CPU使用率异常!当前: ${cpu_usage}%" >> $LOG_FILE
        abnormal_count=$((abnormal_count+1))
        # 记录CPU使用率前5的进程
        echo "CPU占用前5进程:" >> $LOG_FILE
        ps aux --sort=-%cpu | awk 'NR<=6 && NR>1' >> $LOG_FILE
        abnormal_processes="${abnormal_processes} CPU"
    fi
    
    # 监控内存使用率
    # 监控内容:物理内存使用百分比
    # 异常阈值:超过90%可能导致系统开始使用交换空间
    mem_usage=$(free -m | awk 'NR==2{printf "%.2f", $3*100/$2}')
    echo "内存使用率: ${mem_usage}%" >> $LOG_FILE
    
    if (( $(echo "$mem_usage > $MEM_THRESHOLD" | bc -l 2>/dev/null) )); then
        echo "⚠️  内存使用率异常!当前: ${mem_usage}%" >> $LOG_FILE
        abnormal_count=$((abnormal_count+1))
        # 记录内存使用率前5的进程
        echo "内存占用前5进程:" >> $LOG_FILE
        ps aux --sort=-%mem | awk 'NR<=6 && NR>1' >> $LOG_FILE
        abnormal_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" ]; then
        echo "IO等待时间: ${io_wait}%" >> $LOG_FILE
        
        if (( $(echo "$io_wait > $IO_WAIT_THRESHOLD" | bc -l 2>/dev/null) )); then
            echo "⚠️  IO等待时间异常!当前: ${io_wait}%" >> $LOG_FILE
            abnormal_count=$((abnormal_count+1))
            # 记录可能产生高IO的进程
            echo "可能产生高IO的进程:" >> $LOG_FILE
            ps aux --sort=-%cpu | awk 'NR<=6 && NR>1' >> $LOG_FILE
            abnormal_processes="${abnormal_processes} IO"
        fi
    else
        echo "IO等待时间: 无法获取" >> $LOG_FILE
    fi
    
    # 监控系统负载
    # 监控内容:系统1分钟平均负载
    # 异常阈值:超过CPU核心数表示系统过载
    load_1min=$(uptime | awk -F'load average:' '{print $2}' | awk -F, '{print $1}' | sed 's/ //g')
    echo "系统负载(1分钟): ${load_1min}" >> $LOG_FILE
    
    if (( $(echo "$load_1min > $LOAD_THRESHOLD" | bc -l 2>/dev/null) )); then
        echo "⚠️  系统负载异常!当前: ${load_1min},CPU核心数: ${LOAD_THRESHOLD}" >> $LOG_FILE
        abnormal_count=$((abnormal_count+1))
        # 记录活跃进程
        echo "活跃进程列表:" >> $LOG_FILE
        ps aux --sort=-%cpu | awk 'NR<=6 && NR>1' >> $LOG_FILE
        abnormal_processes="${abnormal_processes} 负载"
    fi
    
    # 监控磁盘空间使用率
    # 监控内容:根分区磁盘使用百分比
    # 异常阈值:超过90%可能导致系统无法写入新文件
    disk_usage=$(df / | awk 'NR==2{print $5}' | cut -d'%' -f1)
    echo "磁盘使用率: ${disk_usage}%" >> $LOG_FILE
    
    if [ "$disk_usage" -gt "$DISK_THRESHOLD" ] 2>/dev/null; then
        echo "⚠️  磁盘空间异常!当前: ${disk_usage}%" >> $LOG_FILE
        abnormal_count=$((abnormal_count+1))
        # 记录大文件(前5个)
        echo "根分区大文件前5:" >> $LOG_FILE
        find / -type f -size +100M 2>/dev/null | head -5 >> $LOG_FILE
        abnormal_processes="${abnormal_processes} 磁盘"
    fi
    
    # 监控网络连接数
    # 监控内容:当前TCP连接总数
    # 异常阈值:超过1000个连接可能表示网络过载或异常
    if command -v ss >/dev/null 2>&1; then
        net_connections=$(ss -tun 2>/dev/null | wc -l)
        net_connections=$((net_connections-1))  # 减去标题行
        echo "网络连接数: ${net_connections}" >> $LOG_FILE
        
        if [ "$net_connections" -gt "$NET_CONN_THRESHOLD" ] 2>/dev/null; then
            echo "⚠️  网络连接数异常!当前: ${net_connections}" >> $LOG_FILE
            abnormal_count=$((abnormal_count+1))
            # 记录网络连接数前5的进程
            echo "网络连接数前5进程:" >> $LOG_FILE
            ss -tunp 2>/dev/null | awk '{print $7}' | cut -d':' -f2 | sort | uniq -c | sort -rn | head -5 >> $LOG_FILE
            abnormal_processes="${abnormal_processes} 网络"
        fi
    else
        echo "网络连接数: ss命令不可用" >> $LOG_FILE
    fi
    
    # 汇总异常信息
    if [ $abnormal_count -gt 0 ]; then
        echo "🚨 发现 ${abnormal_count} 个异常指标:${abnormal_processes}" >> $LOG_FILE
        echo "当前时间点进程快照(按CPU排序前10):" >> $LOG_FILE
        ps aux --sort=-%cpu | awk 'NR<=11 && NR>1' >> $LOG_FILE
    else
        echo "✅ 所有指标正常" >> $LOG_FILE
    fi
    
    echo "---" >> $LOG_FILE
    
    # 计算距离当天结束还有多少秒
    current_timestamp=$(date +%s)
    remaining_seconds=$((END_TIMESTAMP - current_timestamp))
    
    # 如果剩余时间不足5秒,则调整为剩余时间
    if [ $remaining_seconds -lt 5 ]; then
        sleep $remaining_seconds
    else
        sleep 5
    fi
done

# 脚本结束执行时间
END_TIME=$(date '+%Y-%m-%d %H:%M:%S')
echo "系统监控脚本结束 - 结束时间: $END_TIME" >> $LOG_FILE
echo "当日监控任务完成,日志文件: $LOG_FILE" >> $LOG_FILE
posted @ 2025-10-13 16:42  流失的痕迹  阅读(9)  评论(0)    收藏  举报