Привет, Habr!
Я уже какое-то время живу в мире «маленьких» проектов: пет-проекты, внутренние админки, сервисы для пары команд или одного отдела. И у них почти всегда одна и та же проблема: мониторинга либо нет совсем, либо «на коленке».
Где-то проверяется только nginx 200.
Где-то есть пара shell-скриптов с
curl, которые периодически кто-то запускает руками.Где-то есть сторонние админки, но никто до конца не понимает, что там за дашборды и как они на самом деле помогают.
В какой-то момент я поймал себя на том, что в третий раз пишу похожий набор проверок (API, страницы, базы, очереди, TLS, Docker…) и снова открываю это все в голых логах или простых HTML-страничках.
В итоге я сел и сделал отдельный проект — мониторинг-демон на Python + Next.js-дашборд, который:
постоянно гоняет health-checks (API, страницы, сервера, сети, базы, очереди, Docker, чувствительные пути),
пишет результат в JSON-снапшоты в папку
output/,а Next.js-frontend эти снапшоты читает и рисует живые панели.
Ниже расскажу, что он умеет, зачем я это вообще сделал и — самое важное для меня — это услышать фидбек от более опытных разработчиков про архитектуру, код и задумку в целом.
Зачем я это написал и кому это может быть полезно
Мой кейс довольно простой:
Есть несколько внутренних и пет-проектов.
Они крутятся в обычных условиях: VPS, Docker, базы, очереди, немного внешних API.
Настраивать полноценный стек мониторинга ради них — тяжеловато и по времени, и по поддержке.
Но и жить вообще без мониторинга уже страшновато — особенно когда появляются прод-клиенты.
Хотелось:
Один легкий демон, который можно просто положить рядом с проектом, сконфигурировать через файл и забыть.
Минимум зависимостей от инфраструктуры: все хранится в файловой системе, нет обязательных внешних сервисов/БД.
Нормальный дашборд, а не «глянь логи, там где-то ERROR, надеюсь, найдешь сам».
Немного DevOps-фич, чтобы не только смотреть, но и надёжно крутить чужие процессы.
Проект в итоге получился не игрушечным: кода и логики там уже ощутимо, поэтому мне и хочется взгляда со стороны.
Что умеет демон: проверки и стримы
Health-checks
Основной цикл крутится в main.py и прогоняет разные типы проверок. Результаты собираются в общий 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.
Streams — данные для UI
Отдельно от периодического отчета крутятся «стримы» в 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-файлы и показывает их удобным образом.
Supervisor: маленький «процесс-менеджер» внутри
Отдельно я заморочился с супервизором (monitoring/supervisor.py). Хотелось иметь не только «сервис, который бы все проверял», но и отдельный модуль, который держит в живыми другие процессы.
Что он делает:
Запускает процессы по конфигу (
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’ы, ресурсы, счетчики рестартов — удобно, чтобы проверять сам мониторинг мониторингом :)
Дашборд на Next.js
Фронтенд живет в admin-dashboard/ и работает довольно примитивно:
Node 18+, Next.js.
Читает JSON-файлы из
../output(относительно корня дашборда).-
Рендерит панели:
общий обзор,
Docker,
базы,
очереди,
supervisor,
настройки.
Почему так? Потому что цель была сделать минимальный UI без отдельной БД и API-сервера. Файловая система — самый простой контракт: Python пишет JSON, JS читает JSON. Можно положить рядом с приложением хоть на обычный VPS, хоть в контейнер и вмонтировать директории.
Конфигурация: все через config.yaml
Основной конфиг лежит в 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: "" }
Уведомления: Telegram/Discord
В utils/notifier.py лежит простой, но достаточно гибкий механизм уведомлений:
Поддерживаются 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 или просто комментарий здесь под статьей.
Спасибо, что дочитали до конца ?
Если проект вдруг сэкономит вам пару часов отлова странных падений на проде — я буду очень рад. А если вы еще и расскажете, как сделать его лучше, — будет вообще идеально.
репо
Комментарии (5)

pravosleva
30.11.2025 16:20Добавьте скринов. А то запускать нет времени, а посмотреть охота, что у вас там получилось.

opsmon
30.11.2025 16:20Развернул, в идеале свой UI прикручивать надо. А если так по шурику глянуть + алертинг прикрутить, то легковесный. До 10ти машин думаю идеально пойдет

nikulin_krd
30.11.2025 16:20ТС, хранение горячих данных на диске уже в целом плохая идея с точки зрения масштабирования. Пока метрик и источников мало, все +- работает, но как только нужно будет полезть за историческими данными за месяц или когда источников метрик станет существенно больше например начнутся проблемы с IO. Может все же сделать для горячих данных БД на SQLite в памяти и постепенно сгружать все на диск ?
opsmon
Полезная статья, спасибо! Делалось под реальные нужды, ощущается. Очень понравилась простота идеи.
Есть пара мелких идей для улучшения:
Стоит добавить ротацию файлов и авто-чистку старых JSON, чтобы они не разрастались со временем. Круто иметь чуть более удобный способ подключать свои кастомные проверки , и скриншотов с примерами.
d1sn3y_1337 Автор
спасибо большое за фидбек! обязательно займусь авто чисткой в ближайшее время