You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何预判容器内目录两小时内占满空间?Nginx日志缓存告警脚本实现

容器部署Nginx的存储监控与告警实现

一、查看容器内存储空间使用情况

根据目录是否挂载到宿主机,有两种常用操作方式:

1. 直接查看宿主机挂载目录(推荐)

如果Nginx的日志/缓存目录通过-v参数挂载到宿主机,直接在宿主机执行命令:

# 查看目录所在分区的整体使用情况
df -h /宿主机挂载路径
# 查看目录自身占用的存储空间
du -sh /宿主机挂载路径

2. 进入容器内部查看

若目录是容器内部路径,通过docker exec进入容器执行命令:

# 查看目标目录所在分区的剩余空间
docker exec <容器ID/名称> df -h /容器内目标目录
# 查看目录自身占用空间
docker exec <容器ID/名称> du -sh /容器内目标目录

3. 确认容器存储挂载配置

用docker inspect查看容器的挂载详情,快速定位宿主机对应路径:

docker inspect <容器ID/名称> | grep -A 15 "Mounts"

二、计算过去一小时的目录平均写入速度

核心逻辑是记录两个时间点的目录大小,用差值除以时间间隔得到平均速度,以下是两种可行实现:

1. 单脚本定时对比(适合周期性执行)

脚本每次运行时读取一小时前的目录大小记录,对比当前值计算速度:

#!/bin/bash
TARGET_DIR="/宿主机挂载路径"  # 替换为实际路径
RECORD_FILE="/tmp/dir_size_record.txt"

# 获取当前目录大小(单位:KB)
current_size=$(du -s "$TARGET_DIR" | awk '{print $1}')

if [ -f "$RECORD_FILE" ]; then
    read -r old_time old_size < "$RECORD_FILE"
    current_time=$(date +%s)
    
    # 校验记录是否在一小时内(3600秒)
    if [ $((current_time - old_time)) -le 3600 ]; then
        # 计算平均写入速度(KB/秒)
        speed=$(( (current_size - old_size) / (current_time - old_time) ))
        echo "过去一小时平均写入速度:$speed KB/s"
    else
        # 记录过期,更新为当前时间和大小
        echo "$current_time $current_size" > "$RECORD_FILE"
        echo "首次记录,一小时后再计算速度"
    fi
else
    # 首次运行,初始化记录文件
    echo "$(date +%s) $current_size" > "$RECORD_FILE"
    echo "首次记录,一小时后再计算速度"
fi

2. 持续监控记录(适合精准统计)

用循环每5分钟记录一次目录大小,保留最近1小时的记录,通过首尾差值计算平均速度:

#!/bin/bash
TARGET_DIR="/宿主机挂载路径"
LOG_FILE="/tmp/dir_size_history.log"

# 每5分钟记录一次目录大小与时间戳
while true; do
    echo "$(date +%s) $(du -s "$TARGET_DIR" | awk '{print $1}')" >> "$LOG_FILE"
    # 只保留最近1小时的记录(12条,5分钟/条)
    tail -n 12 "$LOG_FILE" > "$LOG_FILE.tmp" && mv "$LOG_FILE.tmp" "$LOG_FILE"
    sleep 300
done

单独编写计算脚本:

#!/bin/bash
LOG_FILE="/tmp/dir_size_history.log"

# 获取首尾两条记录
first_line=$(head -n 1 "$LOG_FILE")
last_line=$(tail -n 1 "$LOG_FILE")

read -r first_time first_size <<< "$first_line"
read -r last_time last_size <<< "$last_line"

time_diff=$((last_time - first_time))
size_diff=$((last_size - first_size))

if [ $time_diff -gt 0 ]; then
    avg_speed=$((size_diff / time_diff))
    echo "过去一小时平均写入速度:$avg_speed KB/s"
else
    echo "时间间隔不足,无法计算速度"
fi

三、告警逻辑实现

结合存储信息与速度计算,编写告警脚本,判断剩余空间是否能支撑2小时:

#!/bin/bash
TARGET_DIR="/宿主机挂载路径"
RECORD_FILE="/tmp/dir_size_record.txt"
ALERT_THRESHOLD=7200  # 2小时对应的秒数

# 获取当前剩余空间(单位:KB)
free_space=$(df -k "$TARGET_DIR" | awk 'NR==2 {print $4}')

# 计算平均写入速度
current_size=$(du -s "$TARGET_DIR" | awk '{print $1}')
if [ -f "$RECORD_FILE" ]; then
    read -r old_time old_size < "$RECORD_FILE"
    current_time=$(date +%s)
    if [ $((current_time - old_time)) -le 3600 ]; then
        speed=$(( (current_size - old_size) / (current_time - old_time) ))
        # 避免除以0
        if [ $speed -gt 0 ]; then
            time_remaining=$((free_space / speed))
            if [ $time_remaining -lt $ALERT_THRESHOLD ]; then
                # 触发告警,可替换为邮件、企业微信等通知方式
                echo "告警:目标目录剩余空间仅能支撑 $time_remaining 秒,预计2小时后耗尽!"
                # 示例:发送邮件告警
                # echo "Nginx存储告警:剩余空间不足,预计2小时后耗尽" | mail -s "存储告警" admin@example.com
            else
                echo "剩余空间充足,还能支撑 $time_remaining 秒"
            fi
        else
            echo "目录写入速度为0,无需告警"
        fi
    else
        echo "记录过期,更新记录"
        echo "$current_time $current_size" > "$RECORD_FILE"
    fi
else
    echo "首次运行,创建记录"
    echo "$(date +%s) $current_size" > "$RECORD_FILE"
fi

将脚本加入crontab,设置周期性执行(比如每分钟一次):

# 编辑crontab
crontab -e
# 添加执行规则
* * * * * /path/to/alert_script.sh >> /tmp/alert_log.log 2>&1

内容的提问来源于stack exchange,提问作者palmasd1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 10:38:28