Загрузить файлы в «/»
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
|||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
build-essential \
|
||||||
|
curl \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN mkdir -p /app/config /app/.graph_images
|
||||||
|
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8081"]
|
||||||
@@ -0,0 +1,534 @@
|
|||||||
|
# LLM-Zabbix
|
||||||
|
|
||||||
|
LLM-Zabbix — это связка из двух отдельных Python-проектов:
|
||||||
|
|
||||||
|
- `alert-receiver` — принимает webhook из Zabbix, валидирует токен и пересылает событие дальше;
|
||||||
|
- `alert-processor` — асинхронно обрабатывает события через Redis queue, делает enrichment, triage, correlation/RCA, remediation и доставку уведомлений.
|
||||||
|
|
||||||
|
В текущей схеме **Ollama разворачивается отдельно** от стека LLM-Zabbix. `alert-processor` обращается к нему по адресу хоста Docker, например:
|
||||||
|
|
||||||
|
```env
|
||||||
|
LLM_BASE_URL=http://host.docker.internal:11434
|
||||||
|
```
|
||||||
|
|
||||||
|
Для Linux-хоста это работает при наличии в `docker-compose.yml` строки:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Архитектура
|
||||||
|
|
||||||
|
Поток обработки такой:
|
||||||
|
|
||||||
|
1. Zabbix отправляет webhook в `alert-receiver`.
|
||||||
|
2. `alert-receiver` проверяет `WEBHOOK_TOKEN`, нормализует payload и пересылает его в `alert-processor`.
|
||||||
|
3. `alert-processor-ingest` кладет событие в Redis queue и сразу возвращает `202 Accepted`.
|
||||||
|
4. `alert-processor-worker` забирает событие из очереди и выполняет:
|
||||||
|
- state tracking;
|
||||||
|
- suppress / flap / recovery logic;
|
||||||
|
- Zabbix API enrichment;
|
||||||
|
- LLM triage для low severity;
|
||||||
|
- deterministic correlation + LLM correlation fallback;
|
||||||
|
- LLM remediation;
|
||||||
|
- отправку уведомлений в Matrix / Mail;
|
||||||
|
- audit logging.
|
||||||
|
5. `alert-worker-health` показывает состояние worker и очередей.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Структура репозитория
|
||||||
|
|
||||||
|
```text
|
||||||
|
LLM-Zabbix/
|
||||||
|
├── docker-compose.yml
|
||||||
|
├── alert-receiver/
|
||||||
|
│ ├── .env
|
||||||
|
│ ├── Dockerfile
|
||||||
|
│ ├── requirements.txt
|
||||||
|
│ └── app/
|
||||||
|
│ └── main.py
|
||||||
|
└── alert-processor/
|
||||||
|
├── .env
|
||||||
|
├── Dockerfile
|
||||||
|
├── requirements.txt
|
||||||
|
├── config/
|
||||||
|
│ ├── event_kind_rules.yaml
|
||||||
|
│ └── root_cause_map.yaml
|
||||||
|
└── app/
|
||||||
|
├── main.py
|
||||||
|
├── worker.py
|
||||||
|
└── worker_health.py
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
- Docker Engine / Docker Compose plugin;
|
||||||
|
- отдельный Redis в составе compose;
|
||||||
|
- отдельно развернутый Ollama;
|
||||||
|
- доступ `alert-processor` к:
|
||||||
|
- Zabbix API;
|
||||||
|
- Matrix homeserver / MAS;
|
||||||
|
- SMTP relay;
|
||||||
|
- Ollama API.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Как работает `.env`
|
||||||
|
|
||||||
|
В проекте **два отдельных `.env` файла**:
|
||||||
|
|
||||||
|
- `alert-receiver/.env`
|
||||||
|
- `alert-processor/.env`
|
||||||
|
|
||||||
|
Они не взаимозаменяемы: каждый управляет только своим приложением.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `alert-receiver/.env`
|
||||||
|
|
||||||
|
### Назначение
|
||||||
|
|
||||||
|
Файл управляет входной точкой webhook из Zabbix и пересылкой события в `alert-processor`.
|
||||||
|
|
||||||
|
### Что обычно находится в этом `.env`
|
||||||
|
|
||||||
|
Минимальный пример:
|
||||||
|
|
||||||
|
```env
|
||||||
|
APP_NAME=alert-receiver
|
||||||
|
APP_HOST=0.0.0.0
|
||||||
|
APP_PORT=8080
|
||||||
|
|
||||||
|
WEBHOOK_TOKEN=change_me_webhook_token
|
||||||
|
|
||||||
|
FORWARD_ENABLED=true
|
||||||
|
PROCESSOR_URL=http://alert-processor-ingest:8081/internal/events
|
||||||
|
INTERNAL_API_TOKEN=change_internal_token
|
||||||
|
FORWARD_TIMEOUT_SECONDS=10
|
||||||
|
```
|
||||||
|
|
||||||
|
> Если у вас в `alert-receiver` имена переменных отличаются, ориентируйтесь на фактический `config.py` этого проекта. По смыслу переменные должны отвечать именно за эти функции.
|
||||||
|
|
||||||
|
### Назначение переменных
|
||||||
|
|
||||||
|
- `APP_NAME` — имя сервиса в логах.
|
||||||
|
- `APP_HOST` — адрес bind внутри контейнера.
|
||||||
|
- `APP_PORT` — порт FastAPI/uvicorn внутри контейнера.
|
||||||
|
- `WEBHOOK_TOKEN` — токен, который должен передать Zabbix в webhook. **Обязателеен для минимальной настройки.**
|
||||||
|
- `FORWARD_ENABLED` — включена ли пересылка событий в `alert-processor`.
|
||||||
|
- `PROCESSOR_URL` — endpoint ingest-сервиса `alert-processor`.
|
||||||
|
- `INTERNAL_API_TOKEN` — токен, которым `alert-receiver` аутентифицируется перед `alert-processor`. **Обязателеен для минимальной настройки.**
|
||||||
|
- `FORWARD_TIMEOUT_SECONDS` — timeout ожидания ответа от ingest.
|
||||||
|
|
||||||
|
### Пример для Docker Compose
|
||||||
|
|
||||||
|
```env
|
||||||
|
APP_NAME=alert-receiver
|
||||||
|
APP_HOST=0.0.0.0
|
||||||
|
APP_PORT=8080
|
||||||
|
WEBHOOK_TOKEN=super_webhook_token
|
||||||
|
FORWARD_ENABLED=true
|
||||||
|
PROCESSOR_URL=http://alert-processor-ingest:8081/internal/events
|
||||||
|
INTERNAL_API_TOKEN=super_internal_token
|
||||||
|
FORWARD_TIMEOUT_SECONDS=10
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `alert-processor/.env`
|
||||||
|
|
||||||
|
### Назначение
|
||||||
|
|
||||||
|
Файл управляет всей логикой асинхронной обработки: очередь, Redis, Matrix, Mail, Zabbix enrichment, LLM triage/remediation/correlation, audit, correlation YAML.
|
||||||
|
|
||||||
|
Ниже — рабочий пример.
|
||||||
|
|
||||||
|
```env
|
||||||
|
APP_NAME=alert-processor
|
||||||
|
APP_HOST=0.0.0.0
|
||||||
|
APP_PORT=8081
|
||||||
|
|
||||||
|
INTERNAL_API_TOKEN=super_internal_token
|
||||||
|
REQUIRE_INTERNAL_API_TOKEN=true
|
||||||
|
|
||||||
|
REDIS_ENABLED=true
|
||||||
|
REDIS_URL=redis://redis:6379/0
|
||||||
|
REDIS_KEY_PREFIX=alert
|
||||||
|
REDIS_FINGERPRINT_TTL_SECONDS=86400
|
||||||
|
REDIS_EVENT_TTL_SECONDS=604800
|
||||||
|
|
||||||
|
SUPPRESS_ENABLED=true
|
||||||
|
SUPPRESS_WINDOW_SECONDS=900
|
||||||
|
SUPPRESS_APPLY_TO_AVERAGE=true
|
||||||
|
|
||||||
|
FLAP_ENABLED=true
|
||||||
|
FLAP_WINDOW_SECONDS=120
|
||||||
|
FLAP_THRESHOLD=4
|
||||||
|
FLAP_APPLY_TO_AVERAGE=true
|
||||||
|
|
||||||
|
CORRELATION_ENABLED=true
|
||||||
|
CORRELATION_WINDOW_SECONDS=180
|
||||||
|
CORRELATION_SUPPRESS_CHILDREN=true
|
||||||
|
CORRELATION_KIND_RULES_PATH=/app/config/event_kind_rules.yaml
|
||||||
|
CORRELATION_ROOT_CAUSE_PATH=/app/config/root_cause_map.yaml
|
||||||
|
|
||||||
|
MATRIX_ENABLED=true
|
||||||
|
MATRIX_HOMESERVER_URL=https://mr.example.org
|
||||||
|
MATRIX_ROOM_ID=!roomid:mr.example.org
|
||||||
|
MATRIX_ACCESS_TOKEN=initial_access_token
|
||||||
|
MATRIX_REFRESH_TOKEN=initial_refresh_token
|
||||||
|
MATRIX_OAUTH_TOKEN_ENDPOINT=https://ms.example.org/oauth2/token
|
||||||
|
MATRIX_OAUTH_CLIENT_ID=LLMZABBIX01
|
||||||
|
MATRIX_OAUTH_CLIENT_SECRET=
|
||||||
|
MATRIX_ACCESS_TOKEN_EXPIRES_IN_SECONDS=300
|
||||||
|
MATRIX_REFRESH_MARGIN_SECONDS=60
|
||||||
|
MATRIX_TOKEN_STATE_FILE=/app/.matrix_token_state.json
|
||||||
|
MATRIX_MESSAGE_TYPE=m.notice
|
||||||
|
MATRIX_REQUEST_TIMEOUT_SECONDS=10
|
||||||
|
MATRIX_VERIFY_TLS=true
|
||||||
|
|
||||||
|
MAIL_ENABLED=true
|
||||||
|
MAIL_SMTP_HOST=smtp.example.org
|
||||||
|
MAIL_SMTP_PORT=587
|
||||||
|
MAIL_SMTP_USERNAME=monitoring@example.org
|
||||||
|
MAIL_SMTP_PASSWORD=change_me
|
||||||
|
MAIL_FROM=monitoring@example.org
|
||||||
|
MAIL_TO=ops@example.org
|
||||||
|
MAIL_USE_STARTTLS=true
|
||||||
|
MAIL_USE_TLS=false
|
||||||
|
MAIL_TIMEOUT_SECONDS=15
|
||||||
|
MAIL_SUBJECT_PREFIX=[LLM-Zabbix]
|
||||||
|
|
||||||
|
ZABBIX_API_ENABLED=true
|
||||||
|
ZABBIX_API_URL=https://zb.example.org/api_jsonrpc.php
|
||||||
|
ZABBIX_API_TOKEN=change_me_zabbix_api_token
|
||||||
|
ZABBIX_WEB_URL=https://zb.example.org
|
||||||
|
ZABBIX_API_TIMEOUT_SECONDS=10
|
||||||
|
ZABBIX_API_VERIFY_TLS=true
|
||||||
|
ZABBIX_GRAPH_PERIOD_HOURS=1
|
||||||
|
ZABBIX_GRAPH_TIMEZONE=Europe/Moscow
|
||||||
|
ZABBIX_ENRICH_ONLY_NOTIFY=true
|
||||||
|
|
||||||
|
LLM_ENABLED=true
|
||||||
|
LLM_BASE_URL=http://host.docker.internal:11434
|
||||||
|
LLM_MODEL=qwen3.5:4b
|
||||||
|
LLM_TIMEOUT_SECONDS=45
|
||||||
|
LLM_VERIFY_TLS=true
|
||||||
|
LLM_TEMPERATURE=0.1
|
||||||
|
LLM_MAX_STEPS=4
|
||||||
|
LLM_MAX_COMMANDS=4
|
||||||
|
|
||||||
|
LLM_TRIAGE_ENABLED=true
|
||||||
|
LLM_TRIAGE_CACHE_TTL_SECONDS=3600
|
||||||
|
|
||||||
|
LLM_CORRELATION_ENABLED=true
|
||||||
|
LLM_CORRELATION_MIN_CONFIDENCE=medium
|
||||||
|
|
||||||
|
QUEUE_ENABLED=true
|
||||||
|
QUEUE_NAME=alert:queue:events
|
||||||
|
QUEUE_PROCESSING_NAME=alert:queue:processing
|
||||||
|
QUEUE_DEADLETTER_NAME=alert:queue:deadletter
|
||||||
|
QUEUE_BLOCK_TIMEOUT_SECONDS=5
|
||||||
|
QUEUE_MAX_ATTEMPTS=3
|
||||||
|
QUEUE_DEDUP_TTL_SECONDS=86400
|
||||||
|
QUEUE_REQUEUE_PROCESSING_ON_STARTUP=true
|
||||||
|
|
||||||
|
AUDIT_ENABLED=true
|
||||||
|
AUDIT_KEY_PREFIX=alert:audit
|
||||||
|
AUDIT_TTL_SECONDS=604800
|
||||||
|
AUDIT_MAX_STAGE_RECORDS=200
|
||||||
|
```
|
||||||
|
|
||||||
|
### Блоки переменных и из назначение
|
||||||
|
|
||||||
|
#### Общие
|
||||||
|
- `APP_NAME`, `APP_HOST`, `APP_PORT` — базовые параметры FastAPI ingest.
|
||||||
|
- `INTERNAL_API_TOKEN` — токен для запросов от `alert-receiver`. **Обязателеен для минимальной настройки, должен совпадать с alert-receiver.**
|
||||||
|
- `REQUIRE_INTERNAL_API_TOKEN` — обязательность токена.
|
||||||
|
|
||||||
|
#### Redis / state
|
||||||
|
- `REDIS_URL` — подключение к Redis.
|
||||||
|
- `REDIS_KEY_PREFIX` — префикс ключей.
|
||||||
|
- `REDIS_FINGERPRINT_TTL_SECONDS` — TTL fingerprint state.
|
||||||
|
- `REDIS_EVENT_TTL_SECONDS` — TTL снапшотов событий.
|
||||||
|
|
||||||
|
#### Suppress / flap
|
||||||
|
- `SUPPRESS_*` — антиспам по повторяющимся событиям.
|
||||||
|
- `FLAP_*` — подавление флаппинга.
|
||||||
|
|
||||||
|
#### Correlation / RCA
|
||||||
|
- `CORRELATION_ENABLED` — включает корреляцию.
|
||||||
|
- `CORRELATION_WINDOW_SECONDS` — временное окно для поиска связанных событий.
|
||||||
|
- `CORRELATION_SUPPRESS_CHILDREN` — suppress дочерних low/average событий.
|
||||||
|
- `CORRELATION_KIND_RULES_PATH` — YAML классификации event kinds.
|
||||||
|
- `CORRELATION_ROOT_CAUSE_PATH` — YAML root-cause mapping.
|
||||||
|
|
||||||
|
#### Matrix
|
||||||
|
- `MATRIX_*` — доставка уведомлений в Matrix и refresh токенов через MAS.
|
||||||
|
- `MATRIX_TOKEN_STATE_FILE` — файл хранения актуальных rotated токенов.
|
||||||
|
|
||||||
|
#### Mail
|
||||||
|
- `MAIL_*` — SMTP-доставка email уведомлений.
|
||||||
|
|
||||||
|
#### Zabbix enrichment
|
||||||
|
- `ZABBIX_API_*` — подключение к Zabbix API.
|
||||||
|
- `ZABBIX_WEB_URL` — базовый URL Zabbix Web UI для ссылок.
|
||||||
|
- `ZABBIX_GRAPH_*` — генерация графиков.
|
||||||
|
- `ZABBIX_ENRICH_ONLY_NOTIFY` — enrich только для реально отправляемых событий.
|
||||||
|
|
||||||
|
#### LLM
|
||||||
|
- `LLM_BASE_URL` — адрес Ollama. В текущей схеме **Ollama развернут отдельно** и доступен через `host.docker.internal`.
|
||||||
|
- `LLM_MODEL` — имя локальной модели.
|
||||||
|
- `LLM_TIMEOUT_SECONDS` — timeout запросов к LLM.
|
||||||
|
- `LLM_TEMPERATURE` — temperature для triage/remediation/correlation.
|
||||||
|
- `LLM_MAX_STEPS`, `LLM_MAX_COMMANDS` — ограничение размера remediation.
|
||||||
|
|
||||||
|
#### LLM triage
|
||||||
|
- `LLM_TRIAGE_ENABLED` — включает triage low-severity событий.
|
||||||
|
- `LLM_TRIAGE_CACHE_TTL_SECONDS` — TTL кэша triage verdicts.
|
||||||
|
|
||||||
|
#### LLM correlation fallback
|
||||||
|
- `LLM_CORRELATION_ENABLED` — включает fallback-корреляцию через LLM, если deterministic correlation не дал результата.
|
||||||
|
- `LLM_CORRELATION_MIN_CONFIDENCE` — минимальная уверенность LLM (`low`, `medium`, `high`).
|
||||||
|
|
||||||
|
#### Queue
|
||||||
|
- `QUEUE_*` — параметры Redis queue и deadletter.
|
||||||
|
|
||||||
|
#### Audit
|
||||||
|
- `AUDIT_*` — аудит обработки и хранение event journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## YAML для корреляции
|
||||||
|
|
||||||
|
Файлы лежат в `alert-processor/config/`.
|
||||||
|
|
||||||
|
### `event_kind_rules.yaml`
|
||||||
|
|
||||||
|
Определяет, как событие классифицируется в `kind`.
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
event_kind_rules:
|
||||||
|
- kind: postgresql_unavailable
|
||||||
|
trigger_patterns:
|
||||||
|
- "postgresql.+unavailable"
|
||||||
|
- "postgres.+unavailable"
|
||||||
|
|
||||||
|
- kind: mssql_unavailable
|
||||||
|
trigger_patterns:
|
||||||
|
- "mssql.+unavailable"
|
||||||
|
- "sql server.+unavailable"
|
||||||
|
scope_in:
|
||||||
|
- "host_os"
|
||||||
|
```
|
||||||
|
|
||||||
|
### `root_cause_map.yaml`
|
||||||
|
|
||||||
|
Определяет, какие `kind` могут объяснять другие `kind`.
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
root_cause_map:
|
||||||
|
postgresql_unavailable:
|
||||||
|
explains:
|
||||||
|
- service_unavailable
|
||||||
|
- db_connection_error
|
||||||
|
|
||||||
|
mssql_unavailable:
|
||||||
|
explains:
|
||||||
|
- service_unavailable
|
||||||
|
- db_connection_error
|
||||||
|
```
|
||||||
|
|
||||||
|
После изменения YAML нужно **перезапустить worker**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Отдельный Ollama
|
||||||
|
|
||||||
|
Ollama в текущей схеме **не входит в compose LLM-Zabbix**.
|
||||||
|
|
||||||
|
Он разворачивается отдельно и должен быть доступен с Docker host на `11434`.
|
||||||
|
|
||||||
|
Пример compose для Ollama:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
ollama:
|
||||||
|
image: ollama/ollama:latest
|
||||||
|
container_name: ollama
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "11434:11434"
|
||||||
|
volumes:
|
||||||
|
- ./ollama-data:/root/.ollama
|
||||||
|
```
|
||||||
|
|
||||||
|
Затем внутри Ollama нужно загрузить модель:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -it ollama ollama pull qwen3.5:4b
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверка:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:11434/api/tags
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Подготовка каталогов
|
||||||
|
|
||||||
|
Перед первым запуском из корня репозитория:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p alert-processor/config
|
||||||
|
mkdir -p alert-processor/.graph_images
|
||||||
|
mkdir -p redis-data
|
||||||
|
|
||||||
|
touch alert-processor/.matrix_token_state.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Если YAML уже лежат в репозитории, просто убедитесь, что файлы на месте:
|
||||||
|
|
||||||
|
- `alert-processor/config/event_kind_rules.yaml`
|
||||||
|
- `alert-processor/config/root_cause_map.yaml`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Запуск через Docker Compose
|
||||||
|
|
||||||
|
Из корня репозитория:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверить контейнеры:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
Посмотреть логи worker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose logs -f alert-processor-worker
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Health-check и полезные endpoints
|
||||||
|
|
||||||
|
### Receiver
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:8080/health
|
||||||
|
```
|
||||||
|
|
||||||
|
### Processor ingest
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:8081/health
|
||||||
|
```
|
||||||
|
|
||||||
|
### Worker health
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:8082/health
|
||||||
|
```
|
||||||
|
|
||||||
|
### Audit recent
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:8081/audit/recent?limit=5
|
||||||
|
```
|
||||||
|
|
||||||
|
### Audit by correlation_id
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:8081/audit/events/<correlation_id>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Audit by event_id
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://127.0.0.1:8081/audit/by-event/<event_id>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Как подключить Zabbix
|
||||||
|
|
||||||
|
В Zabbix Media Type / webhook используйте URL `alert-receiver`, а не `alert-processor`.
|
||||||
|
|
||||||
|
Пример макросов:
|
||||||
|
|
||||||
|
```text
|
||||||
|
{$ALERT_RECEIVER_URL} = http://<ip-or-dns>:8080/webhook/zabbix
|
||||||
|
{$ALERT_RECEIVER_TOKEN} = <WEBHOOK_TOKEN>
|
||||||
|
```
|
||||||
|
|
||||||
|
То есть Zabbix отправляет только в:
|
||||||
|
|
||||||
|
```text
|
||||||
|
http://<host>:8080/webhook/zabbix
|
||||||
|
```
|
||||||
|
|
||||||
|
Дальше маршрутизация происходит внутри LLM-Zabbix автоматически.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Пример безопасной последовательности запуска
|
||||||
|
|
||||||
|
1. Поднять отдельно Ollama с загруженной языковой моделью.
|
||||||
|
2. Проверить, что хост отвечает на `http://127.0.0.1:11434/api/tags`.
|
||||||
|
3. Заполнить `alert-receiver/.env`.
|
||||||
|
4. Заполнить `alert-processor/.env`.
|
||||||
|
5. Убедиться, что:
|
||||||
|
- `LLM_BASE_URL=http://host.docker.internal:11434`
|
||||||
|
- в compose есть `extra_hosts: ["host.docker.internal:host-gateway"]`
|
||||||
|
6. Запустить:
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
7. Проверить `8080/health`, `8081/health`, `8082/health`.
|
||||||
|
8. Отправить тестовый alert.
|
||||||
|
9. Проверить `audit/recent`.
|
||||||
|
10. Только потом переключать production webhook Zabbix.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Что хранить в backup
|
||||||
|
|
||||||
|
Минимально:
|
||||||
|
|
||||||
|
- `alert-receiver/.env`
|
||||||
|
- `alert-processor/.env`
|
||||||
|
- `alert-processor/config/*.yaml`
|
||||||
|
- `alert-processor/.matrix_token_state.json`
|
||||||
|
- `redis-data/`
|
||||||
|
- `.graph_images/` — по желанию
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Примечания
|
||||||
|
|
||||||
|
- `alert-processor-ingest` быстро отвечает `202`, вся тяжелая логика выполняется в worker.
|
||||||
|
- Если `LLM correlation` в audit имеет статус `skipped`, это значит, что fallback вызвался, но его результат не был применен.
|
||||||
|
- Если `correlation_source=deterministic`, значит LLM fallback не понадобился.
|
||||||
|
- Для Linux доступ к отдельно развернутому Ollama из контейнера реализован через:
|
||||||
|
- `LLM_BASE_URL=http://host.docker.internal:11434`
|
||||||
|
- `extra_hosts: ["host.docker.internal:host-gateway"]`
|
||||||
|
- При недоступности языковой модели алерты обрабатываются базовым функционалом, но теряется remidiation
|
||||||
|
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
services:
|
||||||
|
redis:
|
||||||
|
image: redis:8.8-trixie
|
||||||
|
container_name: llm-zabbix-redis
|
||||||
|
command: ["redis-server", "--appendonly", "yes"]
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./redis-data:/data
|
||||||
|
networks:
|
||||||
|
- llm-zabbix
|
||||||
|
|
||||||
|
alert-receiver:
|
||||||
|
build:
|
||||||
|
context: ./alert-receiver
|
||||||
|
container_name: alert-receiver
|
||||||
|
env_file:
|
||||||
|
- ./alert-receiver/.env
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- alert-processor-ingest
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
networks:
|
||||||
|
- llm-zabbix
|
||||||
|
|
||||||
|
alert-processor-ingest:
|
||||||
|
build:
|
||||||
|
context: ./alert-processor
|
||||||
|
container_name: alert-processor-ingest
|
||||||
|
command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8081"]
|
||||||
|
env_file:
|
||||||
|
- ./alert-processor/.env
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
volumes:
|
||||||
|
- ./alert-processor/config:/app/config:ro
|
||||||
|
- ./alert-processor/.matrix_token_state.json:/app/.matrix_token_state.json
|
||||||
|
- ./alert-processor/.graph_images:/app/.graph_images
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8081:8081"
|
||||||
|
networks:
|
||||||
|
- llm-zabbix
|
||||||
|
|
||||||
|
alert-processor-worker:
|
||||||
|
build:
|
||||||
|
context: ./alert-processor
|
||||||
|
container_name: alert-processor-worker
|
||||||
|
command: ["python", "-m", "app.worker"]
|
||||||
|
env_file:
|
||||||
|
- ./alert-processor/.env
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
volumes:
|
||||||
|
- ./alert-processor/config:/app/config:ro
|
||||||
|
- ./alert-processor/.matrix_token_state.json:/app/.matrix_token_state.json
|
||||||
|
- ./alert-processor/.graph_images:/app/.graph_images
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- llm-zabbix
|
||||||
|
|
||||||
|
alert-worker-health:
|
||||||
|
build:
|
||||||
|
context: ./alert-processor
|
||||||
|
container_name: alert-worker-health
|
||||||
|
command: ["uvicorn", "app.worker_health:app", "--host", "0.0.0.0", "--port", "8082"]
|
||||||
|
env_file:
|
||||||
|
- ./alert-processor/.env
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
volumes:
|
||||||
|
- ./alert-processor/config:/app/config:ro
|
||||||
|
- ./alert-processor/.matrix_token_state.json:/app/.matrix_token_state.json
|
||||||
|
- ./alert-processor/.graph_images:/app/.graph_images
|
||||||
|
depends_on:
|
||||||
|
- redis
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8082:8082"
|
||||||
|
networks:
|
||||||
|
- llm-zabbix
|
||||||
|
|
||||||
|
networks:
|
||||||
|
llm-zabbix:
|
||||||
|
driver: bridge
|
||||||
Reference in New Issue
Block a user