Перейти к содержимому

Активные мониторы

В отличие от heartbeat-а, где «звонит» сам ваш сервис, активный монитор работает наоборот: serverless-функция Notifly сама раз в N секунд дёргает заданный ресурс. Если заданное число попыток подряд завершилось ошибкой — приходит alert; когда связь возвращается — приходит recovery.

Поддерживается 11 типов проверок — от простого HTTP-GET до lightweight protocol-handshake для SMTP / IMAP / POP3 / SSH / Redis / Postgres / MySQL, DNS-резолва и проверки срока действия TLS-сертификатов:

kindЧто проверяетФормат target
httpGET <url>, ожидаем 2xx (или expectedStatus)https://example.com/health
tcpTCP-handshake — порт открытhost:port
tlsTCP+TLS handshake; expectedStatus = минимальный запас по сроку сертификата (дней)host:port
smtpTCP, читаем баннер 220, шлём EHLO/QUITmx.example.com:25
imapTCP, ждём * OK ..., шлём LOGOUTimap.example.com:143
pop3TCP, ждём +OK ..., шлём QUITpop3.example.com:110
sshTCP, читаем баннер SSH-2.0-...host:22
redisTCP, шлём PING\r\n, ждём +PONGredis.example.com:6379
postgresTCP, шлём StartupMessage, ждём R/E/Ndb.example.com:5432
mysqlTCP, читаем handshake-пакет (protocol_version=10)db.example.com:3306
dnsРезолв имени системным или указанным резолверомexample.com или example.com@8.8.8.8:53

Все TLS-варианты выполняются поверх обычного TCP (без StartTLS), поэтому для шифрованных портов указывайте уже-шифрованный порт (smtp:465, imap:993, pop3:995, redis:6380 и т.п.). Для проверки самого факта работы TCP — используйте kind: "tcp".

каждую минуту: timer-trigger → notifly-monitor
└─▶ SELECT WHERE next_check_at <= now AND status != "paused"
└─▶ HTTP GET / TCP Dial с timeoutSec
├─ успех → status=up, fail_count=0
│ если был "down" и есть recoveryMessage → recovery
└─ ошибка → fail_count++; если ≥ consecutiveFails и не "down":
отправить alert, status=down
  • Хранение — таблица monitors в YDB Serverless, индекс по next_check_at.
  • Проверка — отдельная Cloud Function notifly-monitor, запускается таймер- триггером Yandex Cloud (cron * * * * ? * — раз в минуту).
  • Уведомление — обычное сообщение Notifly, приходит через выбранное при создании монитора канал и доходит до всех ваших клиентов (web, Android, desktop), как любая другая push-нотификация.

Поскольку общение инициирует сам Notifly, есть два явных события:

СобытиеКогда отправляетсяТекст
Потеря связи (alert)После consecutiveFails подряд неудач, только при первом переходе в down. К сообщению добавляется техническая ошибка (например, dial tcp: connect: connection refused)alertMessage
Восстановление связи (recovery)При первой успешной проверке после состояния down, только если задан recoveryMessagerecoveryMessage

Повторного alert-спама не будет: пока монитор в down, новых сообщений не шлётся, проверки продолжаются с обычным интервалом и просто фиксируют статус.

  1. Откройте app.notifly.ruМониторы.
  2. Нажмите «Создать монитор», заполните:
    • Название — для отображения, например «Прод-сайт» или «Postgres-реплика».
    • Канал — через какой канал слать уведомление.
    • Тип проверки — один из 11 поддерживаемых kind (см. таблицу выше).
    • Цель — формат зависит от типа: URL, host:port или DNS-имя.
    • Период (сек) — между проверками (минимум 30, максимум 86400).
    • Таймаут (сек) — сколько ждать ответа в одной попытке (1–60, по умолчанию 10).
    • Подряд неудач — сколько подряд неудачных проверок до alert (по умолчанию 1; типично 2–3, чтобы не реагировать на единичные сетевые джиттеры).
    • Ожидаемый HTTP-код (только http) — 0 означает «любой 2xx», иначе явный код (например, 200).
    • Запас по сертификату, дней (только tls) — 0 = не проверять; 30 = алёрт за 30 дней до expiry.
    • Текст alert / recovery — что прилетит в push.
Окно терминала
# HTTP-проверка
curl -X POST "$NOTIFLY_URL/monitor" \
-H "Content-Type: application/json" \
-H "X-Gotify-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "Прод-сайт",
"kind": "http",
"target": "https://example.com/health",
"intervalSec": 60,
"timeoutSec": 10,
"expectedStatus": 0,
"consecutiveFails": 2,
"alertMessage": "Сайт недоступен!",
"alertPriority": 9,
"recoveryMessage": "Сайт снова отвечает."
}'
# TCP-проверка
curl -X POST "$NOTIFLY_URL/monitor" \
-H "Content-Type: application/json" \
-H "X-Gotify-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "Postgres-реплика",
"kind": "tcp",
"target": "db-replica.internal:5432",
"intervalSec": 60,
"timeoutSec": 5,
"consecutiveFails": 3,
"alertMessage": "Реплика не принимает соединения.",
"recoveryMessage": "Реплика снова доступна."
}'
# TLS — алёрт за 30 дней до истечения сертификата
curl -X POST "$NOTIFLY_URL/monitor" \
-H "Content-Type: application/json" \
-H "X-Gotify-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "SSL prod",
"kind": "tls",
"target": "example.com:443",
"intervalSec": 3600,
"timeoutSec": 10,
"expectedStatus": 30,
"alertMessage": "Сертификат example.com истекает менее чем через 30 дней!"
}'
# DNS — проверка резолва через указанный сервер
curl -X POST "$NOTIFLY_URL/monitor" \
-H "Content-Type: application/json" \
-H "X-Gotify-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "DNS prod-зоны",
"kind": "dns",
"target": "example.com@8.8.8.8:53",
"intervalSec": 300,
"timeoutSec": 5,
"alertMessage": "DNS-зона example.com не резолвится через 8.8.8.8"
}'

Характерные комбинации kind + target для частых задач:

{ "kind": "smtp", "target": "mx.example.com:25" } // SMTP-MX отвечает
{ "kind": "imap", "target": "imap.example.com:143" } // IMAP жив (plain)
{ "kind": "pop3", "target": "pop3.example.com:110" } // POP3 жив
{ "kind": "ssh", "target": "jump.example.com:22" } // SSH-баннер
{ "kind": "redis", "target": "redis.example.com:6379"} // Redis отвечает на PING
{ "kind": "postgres", "target": "pg.example.com:5432" } // PostgreSQL принимает соединения
{ "kind": "mysql", "target": "db.example.com:3306" } // MySQL шлёт handshake
{ "kind": "tls", "target": "smtps.example.com:465", "expectedStatus": 14 } // SSL-сертификат жив и не истечёт в ближайшие 14 дней

Если у вас настроен MCP-сервер Notifly (см. MCP), просто попросите:

Создай монитор для https://api.example.com/health, проверять каждые 30 секунд, алёрт после 3 подряд неудач с текстом «API лежит», recovery «API снова работает».

Доступные MCP-инструменты: list_monitors, create_monitor, update_monitor, delete_monitor, pause_monitor, resume_monitor.

МетодПутьОписание
GET/monitorСписок мониторов пользователя
POST/monitorСоздать
PUT/monitor/:idОбновить настройки (нельзя сменить appid)
DELETE/monitor/:idУдалить
POST/monitor/:id/pauseПриостановить (проверки не выполняются)
POST/monitor/:id/resumeВозобновить

Все endpoints, кроме pause/resume, требуют клиентский (или MCP) токен с правом write.

См. ту же аргументацию для heartbeat: индексированный точечный запрос по next_check_at дешевле и быстрее, чем перечисление S3-объектов.

  • Минимальный период: 30 секунд (чтобы не перегружать YDB).
  • Максимальный период: 24 часа (для редких проверок выгоднее использовать heartbeat).
  • Один вызов notifly-monitor обрабатывает не более 200 просроченных мониторов (cron срабатывает раз в минуту, проверки выполняются последовательно).
  • Запросы идут из Yandex Cloud, поэтому целевой ресурс должен быть доступен из публичного интернета (или из приватной сети YC, если функция в нужной VPC).
  • Все протокол-специфичные проверки (smtp/imap/pop3/…) выполняются без StartTLS — для шифрованного варианта используйте уже-шифрованный порт (:465, :993, :995, :6380) с kind: "tls" или kind: "tcp".