Watchdog-демон для непрерывного мониторинга SES. - Liveness-проверки API, лицензии, списка роботов - Диалоговые сценарии из YAML с агрегацией в 6 фиксированных Zabbix-метрик - Доставка: zabbix_sender (push) или UserParameter (poll) - Hot-reload сценариев без перезапуска
SES Monitor
Система непрерывного мониторинга диалоговой сценарной машины SES (Service Engine Server).
Что делает
Watchdog-демон, который:
- Проверяет доступность SES API каждые 30 секунд
- Имитирует диалоги пользователей по сценариям, описанным в YAML-файлах
- Отправляет метрики в Zabbix через zabbix_sender или UserParameter
SES — универсальная сценарная машина, поэтому мониторинг не привязан к конкретному проекту. Один и тот же демон может обслуживать любой сценарий: голосового ассистента, чат-бота, IVR, диалогов поддержки и любых других.
Архитектура
┌─────────────────────────────────────────────────────┐
│ ses-monitor (watchdog-демон) │
│ │
│ ┌──────────────┐ ┌────────────────┐ │
│ │ LivenessCheck │ │ ScenarioRunner │ │
│ │ (30 сек) │ │ (по YAML) │ │
│ │ │ │ │ │
│ │ GET /hostname│ │ POST /ses/ask │ │
│ │ GET /license │ │ шаги+expect │ │
│ └──────┬───────┘ └───────┬─────────┘ │
│ │ │ │
│ ┌──────▼──────────────────▼──────┐ │
│ │ Zabbix (sender / UP) │ │
│ └──────────────┬─────────────────┘ │
└─────────────────┼────────────────────────────────────┘
│ TCP 10051 / JSON file
┌───────────▼───────────┐
│ Zabbix Server │
│ (триггеры, алерты) │
└───────────────────────┘
Режимы доставки в Zabbix
Монитор поддерживает два режима отправки метрик:
sender (по умолчанию) — zabbix_sender (активный push)
Монитор запускает утилиту zabbix_sender и передаёт метрики через stdin.
Данные отправляются на Zabbix сервер или прокси (порт 10051, trapper).
В Zabbix элементы данных имеют тип "Zabbix траппер".
Требуется: установленный zabbix_sender на сервере с монитором.
userparameter — Zabbix агент (пассивный опрос)
Монитор пишет JSON со всеми метриками в файл (/var/tmp/ses_monitor/metrics.json).
Zabbix агент по запросу сервера запускает скрипт scripts/zbx_get.py,
который возвращает содержимое JSON-файла.
В Zabbix используется master-элемент ses.metrics (тип "Zabbix агент", текст)
и зависимые элементы с препроцессингом JSONPath.
Настройка:
- Импортировать шаблон
zabbix/zbx_ses_template_5.0_up.xmlв Zabbix - Привязать шаблон к хосту (Configuration → Hosts → выберите хост → Templates)
- В конфиге монитора
config/config.yamlустановитьmode: "userparameter" - В
/etc/zabbix/zabbix_agentd.confдобавить строку:Include=/opt/ses-monitor/config/zbx_agentd_ses.conf - Перезапустить Zabbix агента:
sudo systemctl restart zabbix-agent
Структура проекта
/opt/ses-monitor/
├── src/
│ └── ses_monitor/ # Python-пакет (src-layout)
│ ├── __init__.py # Версия, метаданные
│ ├── __main__.py # Точка входа: python -m ses_monitor
│ ├── main.py # Главный asyncio watchdog-цикл
│ ├── config.py # Загрузка YAML-конфигурации
│ ├── checker.py # Liveness-проверки (API, лицензия, роботы)
│ ├── session_client.py # HTTP-клиент для SES API
│ ├── scenario_runner.py # Движок выполнения сценариев
│ ├── log_client.py # Чтение логов SES (задел на будущее)
│ ├── zabbix.py # Интеграция с Zabbix (sender / UserParameter)
│ └── utils.py # Утилиты (логирование, JSON-пути, проверки)
├── config/
│ ├── config.yaml.example # Шаблон конфигурации (скопировать в config.yaml)
│ └── scenarios/
│ ├── example_liveness.yaml # Пример: быстрая проверка
│ └── example_dialog.yaml # Пример: многошаговый диалог
├── zabbix/
│ ├── zbx_ses_template_5.0.xml # Шаблон для sender (trapper)
│ ├── zbx_ses_template_5.0_up.xml # Шаблон для UserParameter
│ └── zbx_ses_monitor.conf # UserParameter для Zabbix агента
├── scripts/
│ └── zbx_get.py # Скрипт чтения JSON для UserParameter
├── systemd/
│ └── ses-monitor.service # Systemd unit
├── tests/
│ ├── __init__.py
│ └── test_scenario_runner.py # 48 тестов
├── pyproject.toml # Зависимости и метаданные пакета
└── README.md
Установка на сервере
1. Требования
- Python 3.9+
- Git — для клонирования репозитория
- Zabbix Agent с утилитой
zabbix_sender - Доступ к SES API (
http://<ses-host>:6190) - Доступ к Zabbix Server по порту 10051
- SSH-ключ, добавленный в Git-репозиторий (
git.totmin.ru)
2. Установка пакета
# Клонируем репозиторий на сервер
git clone git@git.totmin.ru:en2zmax/ses-monitor.git /opt/ses-monitor
# Переходим в каталог проекта
cd /opt/ses-monitor
# Создаём виртуальное окружение и устанавливаем пакет
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
# Создаём каталог для логов
mkdir -p /var/log/ses-monitor
3. Настройка конфигурации
Скопируйте шаблон и отредактируйте:
cp config/config.yaml.example config/config.yaml
nano config/config.yaml
Основные поля:
ses:
base_url: "http://YOUR_SES_HOST:6190" # URL вашего SES API
channel: "monitoring" # Канал для мониторинговых сессий
request_timeout: 30
zabbix:
enabled: true
mode: "userparameter" # или "sender"
host: "my-server-name" # Имя хоста в Zabbix
server: "127.0.0.1" # IP Zabbix сервера (только sender)
port: 10051
sender_path: "/usr/bin/zabbix_sender"
metrics_file: "/var/tmp/ses_monitor/metrics.json" # (только userparameter)
4. Создание сценария
Скопируйте пример и адаптируйте под ваш проект:
cp config/scenarios/example_liveness.yaml config/scenarios/my_project.yaml
5. Запуск
# Проверка вручную:
cd /opt/ses-monitor
.venv/bin/python -m ses_monitor
# Установка как systemd-сервиса:
cp systemd/ses-monitor.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now ses-monitor
# Просмотр логов:
journalctl -u ses-monitor -f
6. Импорт шаблона Zabbix
- Zabbix Frontend → Configuration → Templates → Import
- Выбрать файл
zabbix/zbx_ses_template_5.0.xml(для sender) илиzabbix/zbx_ses_template_5.0_up.xml(для UserParameter) - Нажать Import
- Привязать шаблон "SES Monitor" к нужному хосту
Формат сценариев
Сценарии описываются в YAML-файлах в каталоге config/scenarios/. Это гибкий DSL, который не зависит от конкретного проекта SES.
Полный формат
# Имя сценария (используется в логах)
name: "example: проверка диалога"
# Описание для документации
description: "Проверяет что бот корректно отвечает на вопросы"
# Включён ли сценарий (false — отключён)
enabled: true
# Интервал запуска в секундах
interval: 300
# Таймаут HTTP-запроса в секундах
timeout: 30
# ID робота (обязательно). Узнать: GET /ses/robot/listall
robot_id: "uuid-вашего-робота"
# Канал (если не указан — берётся из config.yaml)
channel: "monitoring"
# Не переоткрывать закрытые сессии (false — создаём новую сессию каждый раз)
restart_closed: false
# Шаги сценария
steps:
- send: "Привет"
expect:
# Каждое ожидание проверяет значение в JSON-ответе
- path: "error"
equals: 0
- path: "answer[0].messages[0]"
contains: "Здрав"
- send: "Как дела?"
expect:
- path: "error"
equals: 0
- path: "answer"
not_empty: true
Условия проверки (expect)
| Условие | Описание | Пример |
|---|---|---|
equals |
Точное совпадение | equals: 0 |
contains |
Подстрока содержится (без учёта регистра) | contains: "здравствуйте" |
not_contains |
Подстрока отсутствует | not_contains: "ошибка" |
not_empty |
Поле не пустое | not_empty: true |
regex |
Регулярное выражение | regex: "\\d{10,}" |
exists |
Поле существует и не None | exists (без значения) |
Пути JSON (path)
Формат: ключ.подключ[индекс].поле
# Корневое поле
path: "error"
# Массив → первый элемент → поле
path: "answer[0].messages[0]"
# Глубокая вложенность
path: "request.data[0].reply.confidence"
Как адаптировать под ваш проект
-
Узнайте robot_id вашего сценария:
curl -s http://<ses-host>:6190/ses/robot/listall -
Пропишите robot_id в файле сценария (поле
robot_idв YAML) -
Создайте файл сценария, описав шаги диалога:
cp config/scenarios/example_liveness.yaml config/scenarios/$(hostname).yaml vim config/scenarios/$(hostname).yaml -
Протестируйте вручную шаги через curl:
curl -X POST "http://<ses-host>:6190/ses/ask/<robot_id>?text=Привет&channel=monitoring" -
Запустите демон — метрики агрегируются автоматически (шаблон Zabbix универсален)
Расширение системы
Добавление нового сценария
- Создать
config/scenarios/my_scenario.yaml - Скопировать структуру из примеров
- Указать
robot_idвашего робота (узнать:GET /ses/robot/listall) - Описать шаги и ожидания
- Сценарий автоматически подхватится через hot-reload (каждые 60 секунд)
Добавление новой метрики
- В нужном модуле добавить поле в датакласс-результат
- В
main.pyвызватьself._zabbix.add(key, value) - Добавить item в Zabbix шаблон
Prometheus/Grafana
При необходимости можно добавить экспорт метрик в Prometheus:
from prometheus_client import Gauge, start_http_server
api_liveness = Gauge("ses_api_liveness", "SES API availability")
Мониторинг самого монитора
- systemd:
systemctl is-active ses-monitor - Zabbix Active Agent:
proc.num[python,root,ses_monitor] - Логи:
journalctl -u ses-monitor --since "10 min ago" -o cat | grep ERROR
Отказоустойчивость
- Автоперезапуск: systemd Restart=always, RestartSec=10
- Graceful shutdown: по SIGTERM отправляет последний батч метрик
- Таймауты: все HTTP-запросы с ограничением по времени (по умолчанию 30с)
- Изоляция сценариев: ошибка в одном сценарии не влияет на другие
- Hot-reload: сценарии перечитываются без перезапуска демона
Лицензия
MIT