disk-alert.py
Мониторинг заполнения дисков с уведомлением в Telegram при превышении порога. Проверяет все смонтированные разделы или только указанные точки монтирования. Без внешних зависимостей.
Зависимости
- Python 3.9+
- Для Telegram-уведомлений: бот-токен и chat ID
Использование
# Проверка всех разделов (порог 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