К содержимому
Все кейсы

AI-системы

Pulse

Watchdog для десятка сервисов, который не превращается в шум

Python 3.11+ (asyncio)aiogram 3httpxRailway GraphQL APIVercel REST APISQLiteAnthropic structured outputsDockerRailway
6
реальных адресов в проверке
40
тестов
3.11–3.13
Python в CI

Проблема

Дёргать URL раз в минуту и писать в Telegram на каждый пятисотый — час работы. Через день такой бот превращается в поток, который перестают читать, и тогда он хуже, чем ничего: создаёт ощущение контроля, которого нет.

Система

Пробы по HTTP, Railway GraphQL и Vercel REST — обвязка; ядро это политика алертинга. Инцидент подтверждается N подряд отказами, поэтому одиночный таймаут сети никого не будит. Пока инцидент открыт, повтор не шлётся — только редкое напоминание по cooldown. Отдельный статус «не знаю» разводит падение сервиса и неспособность пробы это выяснить: протухший токен не выглядит как отказ и не закрывает открытый инцидент. Состояние живёт в SQLite, иначе перезапуск контейнера рассылал бы алерты по уже известным падениям заново. При подтверждённом падении тянется хвост логов деплоя и модель называет причину по схеме — причина, строка-основание, действие, уверенность.

Роль

Соло-разработка: архитектура, политика алертинга, интеграции с провайдерами.

Результат

Политика проверена не на моках, а на шести реальных адресах: первый отказ проходит молча, второй открывает инцидент, третий давится дедупом, восстановление инцидент закрывает — живые сервисы всё это время молчат, как и должны. Отдельно вскрылся барьер в порядке действий: разовый прогон требовал Telegram-токен, то есть проверить «вижу ли я вообще свои сервисы» нельзя было, не заведя сначала бота. Теперь он работает без единого токена. 40 тестов, CI на Python 3.11–3.13. Падение триажа не роняет алерт — сообщение о том, что сервис лежит, важнее объяснения почему; перезапуск деплоя из чата требует отдельного подтверждения.