Мониторинг iQBot
У каждого узла iQBot три служебных адреса. Они не требуют авторизации (кроме /metrics, если задан токен) и доступны на порту ядра, по умолчанию 3000.
| Адрес | Для чего | Код ответа |
|---|---|---|
GET /health | Проверка живости для системы мониторинга и балансировщика: узел принимает трафик и нужные компоненты работают | 200, если всё в порядке; 503 с перечнем причин, если нет |
GET /metrics | Метрики в формате Prometheus | 200; 401, если задан IQB_METRICS_TOKEN и он не передан |
GET /status | Состояние компонентов для человека и для чек-листа консоли | 200, пока узел готов; 503, пока узел запускается или завершает работу |
/health
curl -i http://localhost:3000/health
{"healthy":true,"failed":[],"core":"up","database":"up","messaging":"up","nlu":"up","nluVersion":"2.0.0",
"duckling":"n/a","lang":"up","languages":["en","ru"],"languagesLoading":[],"assets":"up","redis":"n/a","cluster":{"enabled":false,"nodes":1},
"uptimeSeconds":86400,
"ready":true,"draining":false,"converse":{"inFlight":0,"limit":100,"rejected":0}}
Ответ 200 означает одновременно: узел смонтировал ботов (ready), не завершает работу (draining) и компоненты database, messaging, nlu, lang в состоянии up. Состояние n/a (компонент не настроен на этом узле) ошибкой не считается, down и error считаются. Какие компоненты проверять, задаёт параметр components:
curl http://localhost:3000/health?components=database,nlu,redis,duckling
В поле failed перечислены причины: not_ready, draining или имя компонента.
Для балансировщика в режиме распределения нагрузки по-прежнему подходит /status: он отвечает 503 только по состоянию самого узла, а не его соседей по сети. /health нужен системе мониторинга, которой важно, что узел действительно может обслужить клиента.
/metrics
Формат Prometheus (text exposition 0.0.4). Значения относятся к одному узлу: в кластере опрашивайте каждый узел отдельно, так видно, какой из них перегружен.
| Метрика | Тип | Что показывает |
|---|---|---|
iqbot_build_info{version,iqbot} | gauge | Версия платформы, всегда 1 |
iqbot_node_ready, iqbot_node_draining | gauge | Узел готов принимать трафик; узел останавливается |
iqbot_converse_in_flight | gauge | Сообщения клиентов в обработке прямо сейчас |
iqbot_converse_limit | gauge | Лимит одновременных сообщений (IQB_CONVERSE_MAX_IN_FLIGHT), 0 без лимита |
iqbot_converse_requests_total{result} | counter | Запросы диалога по результату: ok, timeout (бот не ответил за converse.timeout), rejected (сверх лимита или при остановке), error |
iqbot_converse_duration_seconds | histogram | Время от запроса до полного ответа бота, корзины 0,1–30 с |
iqbot_events_total{direction} | counter | События движка: incoming, outgoing |
iqbot_component_up{component} | gauge | 1, если компонент отвечает: database, messaging, nlu, assets, redis (только в кластере) |
iqbot_cluster_nodes | gauge | Узлы ядра на шине Redis, 1 без кластера |
iqbot_bots_mounted | gauge | Смонтированные на узле боты |
process_uptime_seconds, process_cpu_seconds_total, process_resident_memory_bytes | gauge | Процесс ядра |
nodejs_heap_size_used_bytes, nodejs_heap_size_total_bytes | gauge | Куча V8 |
nodejs_eventloop_lag_seconds{quantile="mean"|"0.99"} | gauge | Задержка цикла событий с прошлого опроса |
Доступ к метрикам ограничивает переменная IQB_METRICS_TOKEN: если она задана, запрос обязан нести заголовок Authorization: Bearer <токен>. Без переменной метрики открыты так же, как /status; в этом случае закройте порт файрволом для всех, кроме системы мониторинга.
Пример задания для Prometheus:
scrape_configs:
- job_name: iqbot
scrape_interval: 30s
metrics_path: /metrics
authorization:
credentials: <значение IQB_METRICS_TOKEN>
static_configs:
- targets: ['node1.example.com:3000', 'node2.example.com:3000']
На что ставить оповещения
| Сигнал | Условие | О чём говорит |
|---|---|---|
| Узел недоступен | /health не отвечает 200 дольше минуты | Отказ узла или компонента; на /health?components= можно уточнить, какого |
| Компонент упал | iqbot_component_up{component="nlu"} == 0 (так же для database, messaging, lang) | Сервер NLU, языковой сервер или Messaging остановился; боты не понимают фразы, не обучаются или не доставляют сообщения |
| Перегрузка | rate(iqbot_converse_requests_total{result="rejected"}[5m]) > 0 или iqbot_converse_in_flight / iqbot_converse_limit > 0.8 | Узлов не хватает, см. Требования к серверам |
| Медленные ответы | histogram_quantile(0.95, rate(iqbot_converse_duration_seconds_bucket[5m])) > 2 | Действия ботов ждут внешние системы или узел перегружен |
| Таймауты диалога | rate(iqbot_converse_requests_total{result="timeout"}[5m]) > 0 | Бот не укладывается в converse.timeout (по умолчанию 5 с): долгие вызовы API или ИИ-шлюза |
| Перезапуски | resets(process_uptime_seconds[1h]) > 0 | Процесс перезапускался: обновление или завершение системой при нехватке памяти (в журнале платформы при этом нет ни ошибки, ни остановки), см. Диагностика |
| Память | process_resident_memory_bytes > 3e9 на узле с 4 ГБ | Память ядра растёт пилой с размахом около 1 ГБ, устойчивый рост выше 3 ГБ означает утечку или слишком много ботов на узле |
| Кластер разошёлся | iqbot_cluster_nodes меньше числа узлов | Узел потерял Redis и не получает изменения ботов, см. Распределение нагрузки |
/status
Состояние компонентов словами: up, down, error или n/a. Поля: core, database, messaging, nlu и nluVersion, duckling (n/a, если Duckling отключён в настройках NLU), lang (языковой сервер, который ядро опрашивает напрямую: up, down или n/a, если адрес сервера не задан), languages и languagesLoading (языки, которые языковой сервер загрузил и ещё загружает), uptimeSeconds (секунд с запуска процесса: если значение снова и снова сбрасывается, процесс перезапускается), assets (файлы консоли и веб-чата на месте), redis и cluster (в режиме кластера), ready, draining, converse (сообщения в обработке, лимит, отклонено с запуска). Этот же ответ читает раздел «Готовность к продуктиву» консоли. Версию ядра отдаёт GET /version.
Языковой сервер опрашивается напрямую, потому что сервер NLU помнит список языков и после остановки языкового сервера. Типичный случай: системе не хватило памяти, и она остановила языковой сервер, а NLU при этом отвечает up. Без языкового сервера боты не понимают фразы и не обучаются, поэтому lang входит в состав компонентов /health по умолчанию. Если языковой сервер размещён на отдельном узле и вы не хотите, чтобы его отказ выводил узел из балансировки, задайте компоненты явно: /health?components=database,messaging,nlu.
Плашки состояния в консоли и в Studio
Те же данные показывают плашки состояния сервисов: в консоли администрирования они стоят в заголовке страницы, в Studio в верхней панели рядом с названием бота. Зелёная плашка значит, что служба работает, красная что не отвечает, жёлтая что работает с ограничением (например, не запущен Duckling или WebSocket заменён обычными запросами). Плашки «БД» и «Сервер» появляются, только когда с ними проблема; плашка «Сервер» жёлтая и первые пять минут после запуска, чтобы перезапуски процесса были видны пользователям. «Redis» и «Duckling» показаны, только когда эти службы настроены. Подсказка по каждой плашке объясняет последствия и подсказывает действие. Описание плашек для пользователя Studio: Интерфейс Studio.
Журналы
Журнал платформы пишется в консоль процесса (journalctl -u iqbot -f, docker compose logs -f iqbot), в базу данных (раздел «Журналы» консоли, срок хранения logs.dbOutput.expiration) и при включённом logs.fileOutput.enabled в файлы. Для системы сбора логов направляйте файлы или стандартный вывод. Строки, на которые стоит ставить оповещения: [Error и [Critical в начале сообщения, Cluster mode: с предупреждением о Redis, sign-in failed при проблемах единого входа.