← все скрипты

disk-alert.py

python 3.9+ ~ 60 строк обновлён 10 марта 2026

Мониторинг заполнения дисков с уведомлением в Telegram при превышении порога. Проверяет все смонтированные разделы или только указанные точки монтирования. Без внешних зависимостей.

Зависимости

Использование

# Проверка всех разделов (порог 80%)
python3 disk-alert.py --tg-token BOT_TOKEN --tg-chat CHAT_ID

# Свой порог и конкретные разделы
python3 disk-alert.py --threshold 90 --mounts /,/home,/var

# Без Telegram — только вывод в терминал
python3 disk-alert.py --threshold 75

Код

#!/usr/bin/env python3
"""disk-alert.py — мониторинг заполнения дисков с уведомлением в Telegram."""

import shutil
import argparse
import subprocess
from urllib.request import urlopen, Request
from urllib.parse import urlencode

def get_mount_points() -> list[str]:
    """Получает список точек монтирования (исключая виртуальные ФС)."""
    result = subprocess.run(
        ["df", "--output=target", "-x", "tmpfs", "-x", "devtmpfs", "-x", "squashfs"],
        capture_output=True, text=True
    )
    lines = result.stdout.strip().splitlines()[1:]  # пропускаем заголовок
    return [line.strip() for line in lines if line.strip()]

def check_disk(mount: str) -> tuple[float, float, float]:
    """Возвращает (total_gb, used_gb, percent_used) для точки монтирования."""
    usage = shutil.disk_usage(mount)
    total_gb = usage.total / (1024 ** 3)
    used_gb = usage.used / (1024 ** 3)
    percent = (usage.used / usage.total) * 100
    return total_gb, used_gb, percent

def send_telegram(token: str, chat_id: str, message: str) -> None:
    """Отправляет сообщение в Telegram."""
    url = f"https://api.telegram.org/bot{token}/sendMessage"
    data = urlencode({"chat_id": chat_id, "text": message, "parse_mode": "HTML"}).encode()
    req = Request(url, data=data, method="POST")
    urlopen(req, timeout=10)

def main():
    parser = argparse.ArgumentParser(description="Мониторинг дисков")
    parser.add_argument("--threshold", type=float, default=80, help="Порог в %% (по умолчанию 80)")
    parser.add_argument("--mounts", help="Точки монтирования через запятую")
    parser.add_argument("--tg-token", help="Telegram bot token")
    parser.add_argument("--tg-chat", help="Telegram chat ID")
    args = parser.parse_args()

    mounts = args.mounts.split(",") if args.mounts else get_mount_points()
    alerts = []

    print(f"  Порог: {args.threshold}%\n")

    for mount in mounts:
        try:
            total, used, percent = check_disk(mount)
            symbol = "⚠" if percent >= args.threshold else "✓"
            print(f"  {symbol} {mount:<20} {used:.1f} / {total:.1f} GB ({percent:.1f}%)")
            if percent >= args.threshold:
                alerts.append(f"⚠ {mount}: {percent:.1f}% ({used:.1f}/{total:.1f} GB)")
        except OSError as e:
            print(f"  ✗ {mount}: {e}")

    if alerts and args.tg_token and args.tg_chat:
        import socket
        host = socket.gethostname()
        msg = f"<b>Disk Alert [{host}]</b>\n" + "\n".join(alerts)
        send_telegram(args.tg_token, args.tg_chat, msg)
        print(f"\n  Уведомление отправлено в Telegram.")
    elif not alerts:
        print(f"\n  ✓ Все разделы в норме.")

if __name__ == "__main__":
    main()

Автоматизация через cron

Добавьте в crontab -e:

# Проверка дисков каждый час
0 * * * * /usr/bin/python3 /opt/scripts/disk-alert.py --tg-token BOT_TOKEN --tg-chat CHAT_ID