Почему это важно
Заполненный диск убивает базу данных, останавливает logrotate и ломает деплой. Обычно узнаёшь когда что-то другое уже сломалось. Простой cron с df и Nerve ловит проблему до каскада.
Проверка одного диска
#!/bin/bash
# /usr/local/bin/nerve-disk-check.sh
export NERVE_DSN="nerve://TOKEN:[email protected]"
THRESHOLD=90
USAGE=$(df / --output=pcent | tail -1 | tr -d ' %')
if [ "$USAGE" -ge "$THRESHOLD" ]; then
echo "ДИСК: / заполнен на ${USAGE}% ($(hostname))" | nerve send --severity critical
fi
# Cron: каждые 15 минут
*/15 * * * * /usr/local/bin/nerve-disk-check.sh
Все разделы
#!/bin/bash
export NERVE_DSN="nerve://TOKEN:[email protected]"
THRESHOLD=90
df -h --output=target,pcent -x tmpfs -x devtmpfs | tail -n +2 | while read -r mount pct; do
usage="${pct%%%}"
if [ "$usage" -ge "$THRESHOLD" ]; then
echo "ДИСК: $mount на ${usage}% ($(hostname))" | nerve send --severity critical
fi
done
С cooldown (без спама)
Не алертить чаще чем раз в час на один раздел:
#!/bin/bash
export NERVE_DSN="nerve://TOKEN:[email protected]"
THRESHOLD=90
COOLDOWN_DIR="/tmp/nerve-disk-cooldown"
COOLDOWN_SEC=3600
mkdir -p "$COOLDOWN_DIR"
df -h --output=target,pcent -x tmpfs -x devtmpfs | tail -n +2 | while read -r mount pct; do
usage="${pct%%%}"
if [ "$usage" -ge "$THRESHOLD" ]; then
LOCK="$COOLDOWN_DIR/$(echo "$mount" | tr '/' '_')"
if [ ! -f "$LOCK" ] || [ $(( $(date +%s) - $(stat -c %Y "$LOCK") )) -gt "$COOLDOWN_SEC" ]; then
echo "ДИСК: $mount на ${usage}% ($(hostname))" | nerve send --severity critical
touch "$LOCK"
fi
fi
done
Inode-ы закончились
Диск может быть полупустой, но без свободных inode. Запись молча ломается.
INODE=$(df -i / --output=ipcent | tail -1 | tr -d ' %')
if [ "$INODE" -ge 90 ]; then
echo "INODE: / ${INODE}% inode ($(hostname))" | nerve send --severity critical
fi
Docker жрёт диск
/var/lib/docker часто заполняется незаметно — образы, volumes, build cache:
DOCKER_USE=$(df /var/lib/docker --output=pcent 2>/dev/null | tail -1 | tr -d ' %')
if [ -n "$DOCKER_USE" ] && [ "$DOCKER_USE" -ge 85 ]; then
echo "DOCKER: ${DOCKER_USE}% ($(hostname))" | nerve send --severity alert
fi
Совет: docker system prune -af --volumes освобождает место, но удаляет всё неиспользуемое.
Логи переполняют /var/log
LOG_SIZE=$(du -sm /var/log 2>/dev/null | awk '{print $1}')
if [ "$LOG_SIZE" -gt 5000 ]; then
echo "ЛОГИ: /var/log ${LOG_SIZE}MB ($(hostname))" | nerve send --severity alert
fi
FAQ
Как получить уведомление когда диск заполнен?
Cron-задача проверяет df каждые 15 минут. При заполнении выше порога — nerve send отправляет push.
Как не получать спам?
Cooldown-файл: скрипт не алертит повторно для того же диска в течение часа.