监控硬盘利用率

硬盘利用率监控脚本:分区级别的磁盘空间预警

使用fdisk来分析硬盘使用信息

#!/bin/bash

# 配置参数
THRESHOLD=80          # 磁盘使用率报警阈值(%)
COOLDOWN=3600         # 重复报警冷却时间(秒)
MAIL="example@mail.com"
LOG_FILE="/var/log/disk_monitor.log"
ALERT_HISTORY="/var/log/disk_alert_history.log"  # 记录报警历史,用于冷却控制

# 初始化文件
touch $LOG_FILE $ALERT_HISTORY
chmod 644 $LOG_FILE $ALERT_HISTORY

# 日志函数
log() {
    echo "[$(date +%F" "%H:%M:%S)] $1" >> $LOG_FILE
}

# 获取系统信息
get_system_info() {
    DATE=$(date +%F" "%H:%M)
    IP=$(hostname -I | awk '{print $1}')  # 兼容更多系统的IP获取方式
    if [ -z "$IP" ]; then
        IP=$(ifconfig | grep 'inet ' | grep -v '127.0.0.1' | head -1 | awk '{print $2}')
    fi
}

# 获取总磁盘信息(兼容sd、vd、nvme等类型)
get_total_disk() {
    TOTAL=$(fdisk -l 2>/dev/null | awk -F'[: ]+' '
        BEGIN{OFS="="}
        /^Disk \/dev\/(sd|vd|nvme)/{  # 支持多种磁盘命名
            size=$3
            if ($4 == "GB") size=$3
            else if ($4 == "TB") size=$3*1024  # 转换TB为GB
            printf "%s=%.0fG,", $2, size
        }
    ')
    # 移除末尾多余的逗号
    TOTAL=${TOTAL%,}
}

# 检查是否在冷却期内
is_in_cooldown() {
    local part=$1
    local current_time=$(date +%s)
    # 查找该分区最后一次报警时间
    local last_alert=$(grep "$part" $ALERT_HISTORY | tail -1 | awk '{print $1}')
    
    if [ -n "$last_alert" ]; then
        local time_diff=$((current_time - last_alert))
        if [ $time_diff -lt $COOLDOWN ]; then
            return 0  # 在冷却期内
        fi
    fi
    return 1  # 不在冷却期内
}

# 记录报警历史
record_alert() {
    local part=$1
    echo "$(date +%s) $part" >> $ALERT_HISTORY
}

# 发送报警邮件
send_alert() {
    local part=$1
    local use=$2
    local mount=$3
    
    # 检查冷却期
    if is_in_cooldown "$part"; then
        log "分区 $part 仍在冷却期内,暂不重复报警"
        return
    fi
    
    SUBJECT="磁盘报警: $IP 分区 $part 使用率过高"
    BODY="
    服务器磁盘分区使用率超过阈值,请及时处理!
    
    日期时间: $DATE
    服务器IP: $IP
    总磁盘容量: $TOTAL
    问题分区: $part
    使用率: $use%
    挂载点: $mount
    报警阈值: $THRESHOLD%
    "
    echo "$BODY" | mail -s "$SUBJECT" $MAIL
    record_alert "$part"
    log "已发送 $part 报警邮件至 $MAIL"
}

# 主监控逻辑
main() {
    get_system_info
    get_total_disk
    log "开始磁盘监控检查 - 总磁盘: $TOTAL"
    
    # 遍历所有挂载的磁盘分区(排除tmpfs等虚拟文件系统)
    df -h | awk 'BEGIN{OFS="="}/^\/dev\/(sd|vd|nvme)/{print $1, $5+0, $6}' | while read -r line; do
        PART=$(echo $line | cut -d"=" -f1)
        USE=$(echo $line | cut -d"=" -f2)
        MOUNT=$(echo $line | cut -d"=" -f3)
        
        log "检查分区 $PART - 使用率: $USE% 挂载点: $MOUNT"
        
        if [ $USE -gt $THRESHOLD ]; then
            log "分区 $PART 使用率 $USE% 超过阈值 $THRESHOLD%"
            send_alert "$PART" "$USE" "$MOUNT"
        fi
    done
}

# 执行主函数
main