- PVSM.RU - https://www.pvsm.ru -
Привет, Habr!
Я уже какое-то время живу в мире «маленьких» проектов: пет-проекты, внутренние админки, сервисы для пары команд или одного отдела. И у них почти всегда одна и та же проблема: мониторинга либо нет совсем, либо «на коленке».
Где-то проверяется только nginx 200.
Где-то есть пара shell-скриптов с curl, которые периодически кто-то запускает руками.
Где-то есть сторонние админки, но никто до конца не понимает, что там за дашборды и как они на самом деле помогают.
В какой-то момент я поймал себя на том, что в третий раз пишу похожий набор проверок (API, страницы, базы, очереди, TLS, Docker…) и снова открываю это все в голых логах или простых HTML-страничках.
В итоге я сел и сделал отдельный проект — мониторинг-демон на Python + Next.js-дашборд, который:
постоянно гоняет health-checks (API, страницы, сервера, сети, базы, очереди, Docker, чувствительные пути),
пишет результат в JSON-снапшоты в папку output/,
а Next.js-frontend эти снапшоты читает и рисует живые панели.
Ниже расскажу, что он умеет, зачем я это вообще сделал и — самое важное для меня — это услышать фидбек от более опытных разработчиков про архитектуру, код и задумку в целом.
Мой кейс довольно простой:
Есть несколько внутренних и пет-проектов.
Они крутятся в обычных условиях: , Docker, базы, очереди, немного внешних API.
Настраивать полноценный стек мониторинга ради них — тяжеловато и по времени, и по поддержке.
Но и жить вообще без мониторинга уже страшновато — особенно когда появляются прод-клиенты.
Хотелось:
Один легкий демон, который можно просто положить рядом с проектом, сконфигурировать через файл и забыть.
Минимум зависимостей от инфраструктуры: все хранится в файловой системе, нет обязательных внешних сервисов/БД.
Нормальный дашборд, а не «глянь логи, там где-то ERROR, надеюсь, найдешь сам».
Немного DevOps-фич, чтобы не только смотреть, но и надёжно крутить чужие процессы.
Проект в итоге получился не игрушечным: кода и логики там уже ощутимо, поэтому мне и хочется взгляда со стороны.
Основной цикл крутится в main.py [2] и прогоняет разные типы проверок. Результаты собираются в общий output/report_<timestamp>.json и, при желании, в TXT-отчет.
Поддерживаются:
API: методы, заголовки/авторизация (Bearer), таймауты, базовая валидация JSON (по ключам), превью ответа, при желании — сохранение полного ответа в файл.
Страницы: статус + цепочки редиректов, тайтл/мета, must_contain / must_not_contain, предупреждения по скорости, простые security-подсказки (HTTPS, HSTS, gzip), попытки найти robots.txt и sitemap.
Сервер: CPU/память/диск с порогами, отдельные mount-точки, аптайм в читаемом виде, базовая сетевая статистика.
Версии: Python/Node-зависимости — сравнение pip list с PyPI + npm ls с npm-registry, отмечаются апдейты/мажорные апдейты.
Логи: хвост нужных файлов, подсчет ERROR / WARNING / CRITICAL, сбор последних строк с ошибками, обработка недоступных/отсутствующих файлов.
DNS/WHOIS: запрос нужных типов записей, базовый WHOIS, грубый статус домена (ok / истекает / истек).
Сеть: проверка портов, TCP-payload/ожидаемый ответ, SMTP (EHLO/STARTTLS/LOGIN/NOOP), разбор TLS-сертификата (issuer, SAN, сколько дней до истечения, флаг warn/expired).
Чувствительные пути: перебор базовых URL, список известных файлов/директорий (типа .git, config.php, backup.sql и т.п.), с опцией считать 401/403 как потенциальную проблему.
Базы данных: MySQL (aiomysql) и Postgres (asyncpg) — подключение, версия, тестовый запрос с таймингами.
Очереди: Redis (PING, info, размер БД, длина очередей), RabbitMQ (пасивное объявление очереди и чтение статистики).
Каждая проверка живёт в своём модуле в checker/, плюс логирует старт/успех/ошибки через общий utils/logger.py [3].
Отдельно от периодического отчета крутятся «стримы» в monitoring/ — это фоновые потоки, которые снимают снимки (извините за тавтологию) состояния для конкретных панелей дашборда:
Docker stream: собирает список контейнеров/нод/событий через Docker CLI (плюс опционально обогащает статистикой через psutil), пишет output/docker_stream.json.
Database stream: периодически гоняет check_databases, подхватывает статусы бэкапов, при желании автоматически делает их (mysqldump / pg_dump), пишет output/database_stream.json.
Task manager stream: история CPU/памяти, нагрузка по ядрам, load_avg, топ процессов (pid, user, cmd, CPU, mem), пишет output/task_manager_stream.json.
Queue stream: доступность TCP и Redis-PING к очередям/endpoint’ам — output/queue_stream.json.
Идея простая: дашборд вообще не знает, как устроена система. Он просто читает JSON-файлы и показывает их удобным образом.
Отдельно я заморочился с супервизором (monitoring/supervisor.py [4]). Хотелось иметь не только «сервис, который бы все проверял», но и отдельный модуль, который держит в живыми другие процессы.
Что он делает:
Запускает процессы по конфигу (supervisor.command и supervisor.processes).
Умеет:
рестартить по выходу с кодом ≠ 0,
рестартить даже по exit 0, если так настроить (когда процесс «по бизнес-логике» не должен завершаться),
ловить зависания по признакам (долгое отсутствие активности + низкий CPU) и перезапускать.
Ограничивает ресурсы:
resource_limits через rlimit (память, CPU-секунды),
отдельный блок resource_monitoring — следит за реальной памятью/CPU и может рестартнуть при превышениях или потенциальной утечке.
Логирует stdout/stderr каждого процесса в:
*_latest.json (последние чанки вывода),
и, при включенном text-логировании, ещё и в .log.
Плюс есть watchdog-поток, который следит за самим супервизором и пытается перезапустить его в случае зависания/краша.
Для внешнего мира есть health-check API (/health и /supervisor), который отдает статусы процессов, PID’ы, ресурсы, счетчики рестартов — удобно, чтобы проверять сам мониторинг мониторингом :)
Фронтенд живет в admin-dashboard/ и работает довольно примитивно:
Node 18+, Next.js.
Читает JSON-файлы из ../output (относительно корня дашборда).
Рендерит панели:
общий обзор,
Docker,
базы,
очереди,
supervisor,
настройки.
Почему так? Потому что цель была сделать минимальный UI без отдельной БД и API-сервера. Файловая система — самый простой контракт: Python пишет JSON, JS читает JSON. Можно положить рядом с приложением хоть на обычный
Основной конфиг лежит в config.yaml. Там можно настроить:
Логи:
logging: { level: DEBUG, file: monitoring.log, console: true }
output: { directory: output, json_format: true, text_format: false }
Супервизор:
supervisor:
enabled: true
log_directory: output/supervisor
healthcheck: { enabled: true, host: "127.0.0.1", port: 8130 }
watchdog: { enabled: true, check_interval_sec: 5, stale_threshold_sec: 45 }
command:
executable: "python"
args: ["app.py"]
working_dir: "/path/to/app"
env: { APP_ENV: "prod" }
user: "www-data"
resource_limits: { memory_mb: 512, cpu_seconds: 120 }
resource_monitoring:
enabled: true
sample_interval_sec: 2
max_memory_mb: 700
memory_leak_restart_mb: 128
max_cpu_percent: 90
network_check_host: "8.8.8.8"
network_check_timeout_sec: 2
restart_policy:
mode: "always"
restart_delay_seconds: 5
restart_on_exit_0: true
max_restarts_per_minute: 10
hang_timeout_seconds: 60
hang_cpu_percent_threshold: 3
restart_on_hang: true
processes:
- name: "supervised-task"
enabled: true
command: { executable: "node", args: ["server.js"], working_dir: "/path/to/server" }
restart_policy: { mode: "always", restart_delay_seconds: 5 }
Stream’ы и проверки: включение/выключение, интервалы, пороги, backup-опции и т.д.
Уведомления:
notifications:
enabled: true
common: { tags: ["prod"], retry_attempts: 2 }
telegram: { enabled: true, bot_token: "...", chat_id: "..." }
discord: { enabled: false, webhook_url: "" }
В utils/notifier.py [5] лежит простой, но достаточно гибкий механизм уведомлений:
Поддерживаются Telegram и Discord (через webhook).
Сообщения — по простым шаблонам {{placeholder}}.
Есть общие теги, попытки повторной отправки.
Для каждого канала можно задать, на какие события подписываться (api_failures, tls_expiry, server_alerts, system_error и т.п.).
Если уведомления выключены — все тихо превращается в no-op, без падений.
В идеале хочется, чтобы минимальный сценарий был таким:
# создаем виртуальное окружение
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# правим config.yaml под свои нужды
# запускаем демон
python main.py
И отдельно:
cd admin-dashboard
npm install
npm run dev # http://localhost:3000
Дальше — смотришь на панели, правишь конфиг, добавляешь новые сервисы и т.д.
Я хорошо понимаю, что это не замена Prometheus/Zabbix/ELK и прочему взрослому мониторингу. Скорее это:
«Мониторинг для одного-двух сервисов на VPS».
«Легкий helper к основному стеку, если нужно быстро закрыть базовые риски».
«Площадка, чтобы поиграть с идеями supervisor’а/стримов/дашборда».
И вот тут начинается самое интересное: я бы очень хотел услышать мнение более опытных людей.
Нет ли тут очевидных граблей по надёжности/масштабированию, которые я сейчас не вижу?
Насколько вообще такой сервис нужен?
В каких кейсах вы бы его реально поставили?
Что критически мешает использовать его «в бою»?
Я выкладываю этот проект не как «готовый продукт», а как живой учебный/рабочий инструмент, который использую сам и очень хочу допилить до более вменяемого состояния.
Если вы:
когда-то уже решали похожую задачу мониторинга «маленьких» сервисов,
писали свои демоны/супервизоры,
или просто любите разбирать чужой код и архитектуру,
мне будет очень полезно:
услышать, что бы вы сделали иначе;
какие места у вас сразу вызывают подозрение или желание переписать;
какие проверки/стримы вы считаете обязательными, а каких явно не хватает;
любые замечания по коду, структуре, именованию, тестам и т.д.
Ссылку на репозиторий я оставлю в конце поста — буду признателен за ишью, PR или просто комментарий здесь под статьей.
Спасибо, что дочитали до конца 🙃
Если проект вдруг сэкономит вам пару часов отлова странных падений на проде — я буду очень рад. А если вы еще и расскажете, как сделать его лучше, — будет вообще идеально.
репо [6]
Автор: d1sn3y_1337
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/437713
Ссылки в тексте:
[1] VPS: https://www.reg.ru/?rlink=reflink-717
[2] main.py: http://main.py
[3] logger.py: http://logger.py
[4] supervisor.py: http://supervisor.py
[5] notifier.py: http://notifier.py
[6] репо: https://github.com/iinQ1337/server-watcher
[7] Источник: https://habr.com/ru/articles/971786/?utm_source=habrahabr&utm_medium=rss&utm_campaign=971786
Нажмите здесь для печати.