ses-monitor/README.md
2026-06-23 15:06:25 +07:00

321 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.
Настройка:
1. Импортировать шаблон `zabbix/zbx_ses_template_5.0_up.xml` в Zabbix
2. Привязать шаблон к хосту (Configuration → Hosts → выберите хост → Templates)
3. В конфиге монитора `config/config.yaml` установить `mode: "userparameter"`
4. В `/etc/zabbix/zabbix_agentd.conf` добавить строку:
```
Include=/opt/ses-monitor/config/zbx_agentd_ses.conf
```
5. Перезапустить 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
### 2. Установка пакета
```bash
# Клонируем репозиторий на сервер
git clone https://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. Настройка конфигурации
Скопируйте шаблон и отредактируйте:
```bash
cp config/config.yaml.example config/config.yaml
nano config/config.yaml
```
Основные поля:
```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. Создание сценария
Скопируйте пример и адаптируйте под ваш проект:
```bash
cp config/scenarios/example_liveness.yaml config/scenarios/my_project.yaml
```
### 5. Запуск
```bash
# Проверка вручную:
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
1. Zabbix Frontend → **Configuration → Templates → Import**
2. Выбрать файл `zabbix/zbx_ses_template_5.0.xml` (для sender) или `zabbix/zbx_ses_template_5.0_up.xml` (для UserParameter)
3. Нажать Import
4. Привязать шаблон "SES Monitor" к нужному хосту
## Формат сценариев
Сценарии описываются в YAML-файлах в каталоге `config/scenarios/`. Это гибкий DSL, который не зависит от конкретного проекта SES.
### Полный формат
```yaml
# Имя сценария (используется в логах)
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)
Формат: `ключ.подключ[индекс].поле`
```yaml
# Корневое поле
path: "error"
# Массив → первый элемент → поле
path: "answer[0].messages[0]"
# Глубокая вложенность
path: "request.data[0].reply.confidence"
```
## Как адаптировать под ваш проект
1. **Узнайте robot_id** вашего сценария:
```bash
curl -s http://<ses-host>:6190/ses/robot/listall
```
2. **Пропишите robot_id** в файле сценария (поле `robot_id` в YAML)
3. **Создайте файл сценария**, описав шаги диалога:
```bash
cp config/scenarios/example_liveness.yaml config/scenarios/$(hostname).yaml
vim config/scenarios/$(hostname).yaml
```
4. **Протестируйте вручную** шаги через curl:
```bash
curl -X POST "http://<ses-host>:6190/ses/ask/<robot_id>?text=Привет&channel=monitoring"
```
5. **Запустите демон** — метрики агрегируются автоматически (шаблон Zabbix универсален)
## Расширение системы
### Добавление нового сценария
1. Создать `config/scenarios/my_scenario.yaml`
2. Скопировать структуру из примеров
3. Указать `robot_id` вашего робота (узнать: `GET /ses/robot/listall`)
4. Описать шаги и ожидания
5. Сценарий автоматически подхватится через hot-reload (каждые 60 секунд)
### Добавление новой метрики
1. В нужном модуле добавить поле в датакласс-результат
2. В `main.py` вызвать `self._zabbix.add(key, value)`
3. Добавить item в Zabbix шаблон
## Мониторинг самого монитора
- **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