Initial commit: Message Gateway project
- FastAPI приложение для отправки мониторинговых алертов в мессенджеры - Поддержка Telegram и MAX/VK - Интеграция с Grafana, Zabbix, AlertManager - Автоматическое создание тикетов в Jira - Управление группами мессенджеров через API - Декораторы для авторизации и скрытия эндпоинтов - Подробная документация в папке docs/ Автор: Сергей Антропов Сайт: https://devops.org.ru
This commit is contained in:
32
docs/README.md
Normal file
32
docs/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Документация Message Gateway
|
||||
|
||||
Добро пожаловать в документацию проекта Message Gateway!
|
||||
|
||||
## Содержание
|
||||
|
||||
### Основная документация
|
||||
|
||||
- [Настройка ботов](bots.md) - как создать ботов в Telegram и MAX/VK
|
||||
- [Конфигурация групп](groups.md) - как настроить группы мессенджеров
|
||||
- [Шаблоны сообщений](templates.md) - как работают шаблоны Jinja2
|
||||
- [Конфигурация Jira Mapping](jira-mapping.md) - как настроить маппинг алертов в Jira
|
||||
- [Отправка сообщений](messaging.md) - как работает отправка сообщений
|
||||
|
||||
### Настройка систем мониторинга
|
||||
|
||||
- [Настройка Grafana](monitoring/grafana.md) - как настроить Grafana для отправки алертов
|
||||
- [Настройка Zabbix](monitoring/zabbix.md) - как настроить Zabbix для отправки алертов
|
||||
- [Настройка AlertManager](monitoring/alertmanager.md) - как настроить AlertManager для отправки алертов
|
||||
|
||||
### API документация
|
||||
|
||||
- [API для управления группами](api/groups.md) - управление группами мессенджеров через API
|
||||
- [API для отправки сообщений](api/message.md) - отправка простых сообщений в мессенджеры
|
||||
- [API для проверки здоровья](api/health.md) - проверка здоровья и готовности приложения
|
||||
- [API для отладки](api/debug.md) - сохранение JSON данных для отладки
|
||||
- [Декораторы API](api/decorators.md) - декораторы для авторизации и скрытия эндпоинтов
|
||||
|
||||
---
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
105
docs/api/debug.md
Normal file
105
docs/api/debug.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# API для отладки
|
||||
|
||||
**Важно:** Эндпоинт `/api/v1/debug/dump` скрыт из Swagger UI для безопасности, но остается доступным для прямых запросов. Используйте его только для отладки.
|
||||
|
||||
## Сохранение JSON данных для отладки
|
||||
|
||||
```bash
|
||||
POST /api/v1/debug/dump
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"test": "data",
|
||||
"timestamp": "2024-01-01T00:00:00Z",
|
||||
"source": "grafana",
|
||||
"alert": {
|
||||
"title": "Test alert",
|
||||
"state": "alerting"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Данные сохранены в dump.json",
|
||||
"data": {
|
||||
"test": "data",
|
||||
"timestamp": "2024-01-01T00:00:00Z",
|
||||
"source": "grafana",
|
||||
"alert": {
|
||||
"title": "Test alert",
|
||||
"state": "alerting"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Примечания
|
||||
|
||||
- Используется для отладки входящих webhook запросов
|
||||
- Данные сохраняются в файл `/app/app/dump.json` в контейнере
|
||||
- Файл можно просмотреть через `make shell` или `make docker shell`
|
||||
- Полезно для анализа формата данных от различных источников
|
||||
- **Эндпоинт скрыт из Swagger UI** с помощью декоратора `@hide_from_api` для безопасности
|
||||
- Эндпоинт не требует авторизации (API ключ не нужен)
|
||||
- Используется только для внутренней отладки
|
||||
|
||||
## Примеры использования
|
||||
|
||||
### Сохранение данных из Grafana
|
||||
|
||||
```bash
|
||||
curl -X POST "http://your-gateway-url/api/v1/debug/dump" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"source": "grafana",
|
||||
"alert": {
|
||||
"title": "Test alert",
|
||||
"state": "alerting"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Сохранение данных из Zabbix
|
||||
|
||||
```bash
|
||||
curl -X POST "http://your-gateway-url/api/v1/debug/dump" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"source": "zabbix",
|
||||
"event": {
|
||||
"event-id": "8819711",
|
||||
"event-name": "High CPU utilization",
|
||||
"status": "PROBLEM"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Сохранение данных из AlertManager
|
||||
|
||||
```bash
|
||||
curl -X POST "http://your-gateway-url/api/v1/debug/dump" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"source": "alertmanager",
|
||||
"status": "firing",
|
||||
"commonLabels": {
|
||||
"alertname": "HighCPUUsage",
|
||||
"severity": "critical"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Просмотр сохраненных данных
|
||||
|
||||
```bash
|
||||
# Через make shell
|
||||
make shell
|
||||
cat /app/app/dump.json
|
||||
|
||||
# Или напрямую через docker
|
||||
docker exec -it message-gateway cat /app/app/dump.json
|
||||
```
|
||||
|
||||
128
docs/api/decorators.md
Normal file
128
docs/api/decorators.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Декораторы API
|
||||
|
||||
В проекте Message Gateway используются декораторы для упрощения работы с API и обеспечения безопасности.
|
||||
|
||||
## Декораторы
|
||||
|
||||
### `@require_api_key`
|
||||
|
||||
Декоратор для пометки эндпоинта как требующего API ключ для авторизации.
|
||||
|
||||
**Использование:**
|
||||
```python
|
||||
from app.core.auth import require_api_key, require_api_key_dependency
|
||||
|
||||
@require_api_key
|
||||
@router.post("/endpoint", dependencies=[require_api_key_dependency])
|
||||
async def my_endpoint(request: Request, ...):
|
||||
...
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Декоратор используется только для пометки функции
|
||||
- Фактическая проверка API ключа выполняется через `dependencies=[require_api_key_dependency]`
|
||||
- Это обеспечивает отображение замочка в Swagger UI
|
||||
- API ключ настраивается в переменной окружения `API_KEY` в файле `.env`
|
||||
- API ключ передается в заголовке `X-API-Key`
|
||||
|
||||
**Пример:**
|
||||
```python
|
||||
from app.core.auth import require_api_key, require_api_key_dependency
|
||||
from fastapi import APIRouter, Request, Body
|
||||
|
||||
router = APIRouter(prefix="/api/v1/groups", tags=["groups"])
|
||||
|
||||
@require_api_key
|
||||
@router.post(
|
||||
"",
|
||||
name="Создать группу",
|
||||
dependencies=[require_api_key_dependency]
|
||||
)
|
||||
async def create_group(
|
||||
request: Request,
|
||||
body: CreateGroupRequest = Body(...)
|
||||
) -> Dict[str, Any]:
|
||||
...
|
||||
```
|
||||
|
||||
### `@hide_from_api`
|
||||
|
||||
Декоратор для скрытия эндпоинта из API документации (Swagger UI).
|
||||
|
||||
**Использование:**
|
||||
```python
|
||||
from app.core.auth import hide_from_api
|
||||
|
||||
@hide_from_api
|
||||
@router.post("/debug/dump", include_in_schema=False)
|
||||
async def debug_endpoint(...):
|
||||
...
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Декоратор помечает функцию как скрытую от API
|
||||
- Эндпоинт все еще будет работать, но не будет отображаться в Swagger UI
|
||||
- Рекомендуется использовать вместе с параметром `include_in_schema=False` в декораторе route для надежного скрытия
|
||||
- Используется для скрытия внутренних эндпоинтов от публичной документации
|
||||
- Полезно для отладочных эндпоинтов и административных функций
|
||||
|
||||
**Пример:**
|
||||
```python
|
||||
from app.core.auth import hide_from_api
|
||||
from fastapi import APIRouter, Body
|
||||
|
||||
router = APIRouter(prefix="/api/v1/debug", tags=["debug"])
|
||||
|
||||
@hide_from_api
|
||||
@router.post(
|
||||
"/dump",
|
||||
name="JSON Debug dump",
|
||||
include_in_schema=False, # Скрываем эндпоинт из Swagger UI
|
||||
response_model=Dict[str, Any]
|
||||
)
|
||||
async def dump_request(
|
||||
dump: Dict[str, Any] = Body(...)
|
||||
) -> Dict[str, Any]:
|
||||
...
|
||||
```
|
||||
|
||||
## Комбинирование декораторов
|
||||
|
||||
Декораторы можно комбинировать для более сложных сценариев:
|
||||
|
||||
```python
|
||||
from app.core.auth import require_api_key, require_api_key_dependency, hide_from_api
|
||||
|
||||
@require_api_key
|
||||
@hide_from_api
|
||||
@router.post(
|
||||
"/internal/admin",
|
||||
dependencies=[require_api_key_dependency],
|
||||
include_in_schema=False
|
||||
)
|
||||
async def internal_admin_endpoint(request: Request, ...):
|
||||
...
|
||||
```
|
||||
|
||||
В этом примере:
|
||||
- Эндпоинт требует API ключ для доступа
|
||||
- Эндпоинт скрыт из Swagger UI
|
||||
- Эндпоинт доступен только для администраторов с правильным API ключом
|
||||
|
||||
## Примечания
|
||||
|
||||
- Декораторы применяются снизу вверх (от функции к верхнему декоратору)
|
||||
- Порядок декораторов важен: сначала применяется декоратор route (`@router.post`), затем декораторы авторизации и скрытия
|
||||
- Декораторы не изменяют функциональность эндпоинта, они только добавляют метаданные или проверки
|
||||
- Все декораторы определены в модуле `app.core.auth`
|
||||
|
||||
## Дополнительная информация
|
||||
|
||||
- Подробная документация по API ключам: см. [API для управления группами](groups.md)
|
||||
- Подробная документация по отладочным эндпоинтам: см. [API для отладки](debug.md)
|
||||
|
||||
---
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
|
||||
164
docs/api/groups.md
Normal file
164
docs/api/groups.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# API для управления группами
|
||||
|
||||
## Получение списка поддерживаемых мессенджеров
|
||||
|
||||
```bash
|
||||
GET /api/v1/groups/messengers
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"messengers": [
|
||||
{
|
||||
"type": "telegram",
|
||||
"name": "Telegram",
|
||||
"supports_threads": true,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"type": "max",
|
||||
"name": "MAX/VK",
|
||||
"supports_threads": false,
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Получение списка групп
|
||||
|
||||
```bash
|
||||
# Без API ключа (только названия)
|
||||
GET /api/v1/groups
|
||||
|
||||
# С API ключом (полная информация)
|
||||
GET /api/v1/groups
|
||||
Headers: X-API-Key: your_api_key_here
|
||||
```
|
||||
|
||||
**Пример ответа (без API ключа):**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"groups": [
|
||||
{"name": "monitoring", "chat_id": null},
|
||||
{"name": "alerts", "chat_id": null}
|
||||
],
|
||||
"count": 2
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа (с API ключом):**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"groups": [
|
||||
{
|
||||
"name": "monitoring",
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567890,
|
||||
"thread_id": 0
|
||||
},
|
||||
{
|
||||
"name": "alerts_max",
|
||||
"messenger": "max",
|
||||
"chat_id": "123456789",
|
||||
"thread_id": null
|
||||
}
|
||||
],
|
||||
"count": 2
|
||||
}
|
||||
```
|
||||
|
||||
## Создание группы
|
||||
|
||||
```bash
|
||||
POST /api/v1/groups
|
||||
Headers:
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"group_name": "monitoring",
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567890,
|
||||
"thread_id": 0
|
||||
}
|
||||
```
|
||||
|
||||
**Пример запроса для MAX/VK:**
|
||||
```bash
|
||||
POST /api/v1/groups
|
||||
Headers:
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"group_name": "max_alerts",
|
||||
"messenger": "max",
|
||||
"chat_id": "123456789",
|
||||
"thread_id": 0,
|
||||
"config": {
|
||||
"access_token": "your_max_access_token"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Группа 'monitoring' создана с мессенджером 'telegram' и ID -1001234567890"
|
||||
}
|
||||
```
|
||||
|
||||
## Обновление группы
|
||||
|
||||
```bash
|
||||
PUT /api/v1/groups/{group_name}
|
||||
Headers:
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567891,
|
||||
"thread_id": 0
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Группа 'monitoring' обновлена"
|
||||
}
|
||||
```
|
||||
|
||||
## Удаление группы
|
||||
|
||||
```bash
|
||||
DELETE /api/v1/groups/{group_name}
|
||||
Headers: X-API-Key: your_api_key_here
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Группа 'monitoring' удалена"
|
||||
}
|
||||
```
|
||||
|
||||
## Примечания
|
||||
|
||||
- Требуется API ключ в заголовке X-API-Key для всех операций, кроме получения списка групп (без API ключа возвращаются только названия)
|
||||
- Группы сохраняются в `config/groups.json`
|
||||
- Chat ID можно получить, добавив бота в группу и отправив сообщение
|
||||
- Используйте `@userinfobot` в Telegram для получения Chat ID группы
|
||||
- Для MAX/VK используйте peer_id (может быть строкой или числом)
|
||||
- Thread ID поддерживается только для Telegram (для MAX/VK игнорируется)
|
||||
- Дополнительная конфигурация (config) может содержать параметры для конкретного мессенджера (например, access_token для MAX/VK)
|
||||
|
||||
63
docs/api/health.md
Normal file
63
docs/api/health.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# API для проверки здоровья
|
||||
|
||||
## Проверка здоровья и готовности приложения
|
||||
|
||||
```bash
|
||||
GET /api/v1/health
|
||||
```
|
||||
|
||||
**Пример ответа (здорово):**
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"state": "online",
|
||||
"telegram_bot_configured": true,
|
||||
"groups_config_available": true
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа (не готово):**
|
||||
```json
|
||||
{
|
||||
"status": "not_ready",
|
||||
"state": "online",
|
||||
"checks": {
|
||||
"telegram_bot_configured": false,
|
||||
"groups_config_available": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Примечания
|
||||
|
||||
- Не требует аутентификации
|
||||
- Возвращает 503 если приложение не готово
|
||||
- Используется Kubernetes для liveness и readiness probes
|
||||
- Настройте liveness и readiness probes в kubernetes.yaml
|
||||
- Приложение считается готовым, если все проверки пройдены
|
||||
|
||||
## Проверки
|
||||
|
||||
- `telegram_bot_configured` - наличие токена Telegram (TELEGRAM_BOT_TOKEN)
|
||||
- `groups_config_available` - доступность файла конфигурации групп (config/groups.json)
|
||||
|
||||
## Использование в Kubernetes
|
||||
|
||||
Настройте liveness и readiness probes в `kubernetes.yaml`:
|
||||
|
||||
```yaml
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: 8000
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: 8000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
```
|
||||
|
||||
188
docs/api/message.md
Normal file
188
docs/api/message.md
Normal file
@@ -0,0 +1,188 @@
|
||||
# API для отправки сообщений
|
||||
|
||||
**Важно:** Все эндпоинты для отправки сообщений требуют API ключ в заголовке `X-API-Key`.
|
||||
|
||||
## Аутентификация
|
||||
|
||||
Все эндпоинты требуют API ключ в заголовке запроса:
|
||||
|
||||
```bash
|
||||
X-API-Key: your_api_key_here
|
||||
```
|
||||
|
||||
API ключ настраивается в переменной окружения `API_KEY` в файле `.env`.
|
||||
|
||||
## Отправка текстового сообщения
|
||||
|
||||
```bash
|
||||
POST /api/v1/message/text
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"tg_group": "monitoring",
|
||||
"tg_thread_id": 0,
|
||||
"text": "<b>Критическое уведомление</b>\n\nСистема недоступна!\n\n<i>Время: 2024-02-08 16:49:44</i>",
|
||||
"parse_mode": "HTML",
|
||||
"disable_web_page_preview": false
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Сообщение отправлено в чат monitoring, тред 0"
|
||||
}
|
||||
```
|
||||
|
||||
**Поддерживаемые режимы парсинга:**
|
||||
- `HTML` - HTML форматирование (рекомендуется)
|
||||
- `Markdown` - Markdown форматирование
|
||||
- `MarkdownV2` - Markdown V2 форматирование
|
||||
|
||||
**Примеры форматирования:**
|
||||
- HTML: `<b>жирный</b>`, `<i>курсив</i>`, `<code>код</code>`
|
||||
- Markdown: `**жирный**`, `*курсив*`, `` `код` ``
|
||||
|
||||
## Отправка фото
|
||||
|
||||
```bash
|
||||
POST /api/v1/message/photo
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"tg_group": "monitoring",
|
||||
"tg_thread_id": 0,
|
||||
"photo": "https://grafana.example.com/render/dashboard-solo?panelId=1&width=1000&height=500",
|
||||
"caption": "<b>График CPU</b>\n\n<i>Время: 2024-02-08 16:49:44</i>",
|
||||
"parse_mode": "HTML"
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Фото отправлено в чат monitoring, тред 0"
|
||||
}
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Фото может быть передано через URL (автоматически загрузится) или как файл
|
||||
- Поддерживаются форматы: JPG, PNG, GIF, WebP
|
||||
- Максимальный размер файла: 10 МБ (Telegram), зависит от мессенджера
|
||||
- Для отправки графиков из Grafana используйте URL рендеринга дашбордов
|
||||
|
||||
## Отправка видео
|
||||
|
||||
```bash
|
||||
POST /api/v1/message/video
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"tg_group": "monitoring",
|
||||
"tg_thread_id": 0,
|
||||
"video": "https://example.com/recording.webm",
|
||||
"caption": "<b>Запись работы системы</b>\n\n<i>Длительность: 60 сек</i>",
|
||||
"parse_mode": "HTML",
|
||||
"duration": 60,
|
||||
"width": 1920,
|
||||
"height": 1080
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Видео отправлено в чат monitoring, тред 0"
|
||||
}
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Видео может быть передано через URL (автоматически загрузится) или как файл
|
||||
- Поддерживаются форматы: MP4, WebM, MOV (зависит от мессенджера)
|
||||
- Максимальный размер файла: 50 МБ (Telegram), зависит от мессенджера
|
||||
- Длительность, ширина и высота опциональны, но рекомендуются для лучшего отображения
|
||||
|
||||
## Отправка аудио
|
||||
|
||||
```bash
|
||||
POST /api/v1/message/audio
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"tg_group": "monitoring",
|
||||
"tg_thread_id": 0,
|
||||
"audio": "https://example.com/notification.ogg",
|
||||
"caption": "<b>Аудио уведомление</b>\n\n<i>Система работает нормально</i>",
|
||||
"parse_mode": "HTML",
|
||||
"duration": 30,
|
||||
"performer": "System Notification",
|
||||
"title": "Alert Notification"
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Аудио отправлено в чат monitoring, тред 0"
|
||||
}
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Аудио может быть передано через URL (автоматически загрузится) или как файл
|
||||
- Поддерживаются форматы: MP3, OGG, WAV, M4A (зависит от мессенджера)
|
||||
- Максимальный размер файла: 50 МБ (Telegram), зависит от мессенджера
|
||||
- Исполнитель и название опциональны, но улучшают отображение в Telegram
|
||||
|
||||
## Отправка документа
|
||||
|
||||
```bash
|
||||
POST /api/v1/message/document
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"tg_group": "monitoring",
|
||||
"tg_thread_id": 0,
|
||||
"document": "https://example.com/report.xlsx",
|
||||
"caption": "<b>Отчет за неделю</b>\n\n<i>Дата: 2024-02-08</i>",
|
||||
"parse_mode": "HTML",
|
||||
"filename": "report_2024-02-08.xlsx"
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Документ отправлен в чат monitoring, тред 0"
|
||||
}
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Документ может быть передан через URL (автоматически загрузится) или как файл
|
||||
- Поддерживаются все форматы файлов (PDF, DOCX, XLSX, TXT, и т.д.)
|
||||
- Максимальный размер файла: 50 МБ (Telegram), зависит от мессенджера
|
||||
- Имя файла опционально, если не указано - используется имя из URL
|
||||
- Для отправки отчетов используйте прямые ссылки на файлы
|
||||
|
||||
## Параметры запроса
|
||||
|
||||
Все endpoints поддерживают параметр `messenger` (опционально):
|
||||
- `?messenger=telegram` - использовать Telegram
|
||||
- `?messenger=max` - использовать MAX/VK
|
||||
- Если не указан, используется мессенджер из конфигурации группы
|
||||
|
||||
## Общие параметры
|
||||
|
||||
- `tg_group` - имя группы из конфигурации (config/groups.json)
|
||||
- `tg_thread_id` - ID треда в группе (0 для основной группы, поддерживается только для Telegram)
|
||||
- `messenger` - тип мессенджера (опционально, `telegram`, `max`, по умолчанию используется из конфигурации группы)
|
||||
|
||||
91
docs/bots.md
Normal file
91
docs/bots.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Настройка ботов
|
||||
|
||||
## Создание бота в Telegram
|
||||
|
||||
1. **Создание бота через BotFather:**
|
||||
- Откройте Telegram и найдите бота [@BotFather](https://t.me/BotFather)
|
||||
- Отправьте команду `/newbot`
|
||||
- Следуйте инструкциям BotFather:
|
||||
- Введите имя бота (например, "My Monitoring Bot")
|
||||
- Введите username бота (должен заканчиваться на `bot`, например, "my_monitoring_bot")
|
||||
- BotFather предоставит вам **токен бота** (например, `123456789:ABCdefGHIjklMNOpqrsTUVwxyz`)
|
||||
|
||||
2. **Настройка бота:**
|
||||
- Сохраните токен бота в переменную окружения `TELEGRAM_BOT_TOKEN`
|
||||
- Добавьте бота в группу Telegram, куда нужно отправлять сообщения
|
||||
- Сделайте бота администратором группы (опционально, но рекомендуется для полной функциональности)
|
||||
|
||||
3. **Получение Chat ID группы:**
|
||||
- Добавьте бота [@userinfobot](https://t.me/userinfobot) в группу
|
||||
- Отправьте любое сообщение в группе
|
||||
- @userinfobot покажет Chat ID группы (например, `-1001234567890`)
|
||||
- Сохраните Chat ID в конфигурацию групп (`config/groups.json`)
|
||||
|
||||
4. **Получение Thread ID (для тредов):**
|
||||
- Создайте тред в группе Telegram
|
||||
- Используйте бота [@userinfobot](https://t.me/userinfobot) или API Telegram для получения Thread ID
|
||||
- Thread ID можно получить через API Telegram: `getUpdates` или `getChat`
|
||||
|
||||
**Пример конфигурации для Telegram:**
|
||||
```json
|
||||
{
|
||||
"monitoring": {
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567890,
|
||||
"thread_id": 0,
|
||||
"config": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Создание бота в MAX/VK
|
||||
|
||||
1. **Создание приложения в VK:**
|
||||
- Перейдите на [VK Developers](https://dev.vk.com/)
|
||||
- Создайте новое приложение:
|
||||
- Нажмите "Создать приложение"
|
||||
- Выберите тип приложения: "Веб-сайт" или "Standalone"
|
||||
- Введите название приложения
|
||||
- Подтвердите создание
|
||||
|
||||
2. **Получение Access Token:**
|
||||
- В настройках приложения найдите раздел "Токены"
|
||||
- Создайте новый токен:
|
||||
- Выберите права доступа (scope):
|
||||
- `messages` - для отправки сообщений
|
||||
- `photos` - для отправки фотографий
|
||||
- `docs` - для отправки документов
|
||||
- Скопируйте полученный токен
|
||||
- Сохраните токен в переменную окружения `MAX_ACCESS_TOKEN`
|
||||
|
||||
3. **Получение Peer ID (ID чата):**
|
||||
- Peer ID можно получить через API VK: `messages.getConversations`
|
||||
- Для группы: Peer ID = `2000000000 + group_id`
|
||||
- Для беседы: Peer ID можно получить через `messages.getChat`
|
||||
|
||||
4. **Настройка приложения:**
|
||||
- Установите переменные окружения:
|
||||
- `MAX_ACCESS_TOKEN` - токен доступа
|
||||
- `MAX_API_VERSION` - версия API (по умолчанию `5.131`)
|
||||
- `MAX_ENABLED=true` - включить поддержку MAX/VK
|
||||
|
||||
**Пример конфигурации для MAX/VK:**
|
||||
```json
|
||||
{
|
||||
"max_alerts": {
|
||||
"messenger": "max",
|
||||
"chat_id": "123456789",
|
||||
"thread_id": null,
|
||||
"config": {
|
||||
"access_token": "your_access_token_here",
|
||||
"api_version": "5.131"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- MAX/VK не поддерживает треды (thread_id всегда `null`)
|
||||
- Peer ID может быть как числом, так и строкой
|
||||
- Для работы с группами VK требуется, чтобы бот был добавлен в группу и имел права администратора
|
||||
|
||||
195
docs/groups.md
Normal file
195
docs/groups.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# Конфигурация групп
|
||||
|
||||
## Формат конфигурации
|
||||
|
||||
Конфигурация групп хранится в файле `config/groups.json`.
|
||||
|
||||
**Пример конфигурации:**
|
||||
```json
|
||||
{
|
||||
"monitoring": {
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567890,
|
||||
"thread_id": 0,
|
||||
"config": {}
|
||||
},
|
||||
"alerts_max": {
|
||||
"messenger": "max",
|
||||
"chat_id": "123456789",
|
||||
"thread_id": null,
|
||||
"config": {
|
||||
"access_token": "optional_override_max_token",
|
||||
"api_version": "5.131"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Поля конфигурации:**
|
||||
- `messenger` - тип мессенджера (`telegram`, `max`)
|
||||
- `chat_id` - ID чата (может быть числом для Telegram или строкой для MAX/VK)
|
||||
- `thread_id` - ID треда в группе (только для Telegram, `0` для основной группы, `null` для MAX/VK)
|
||||
- `config` - дополнительная конфигурация для мессенджера (например, `access_token` для MAX/VK)
|
||||
|
||||
## Управление группами через API
|
||||
|
||||
Управление группами доступно через REST API с защитой API ключом.
|
||||
|
||||
### Получение списка поддерживаемых мессенджеров
|
||||
|
||||
```bash
|
||||
GET /api/v1/groups/messengers
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"messengers": [
|
||||
{
|
||||
"type": "telegram",
|
||||
"name": "Telegram",
|
||||
"supports_threads": true,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"type": "max",
|
||||
"name": "MAX/VK",
|
||||
"supports_threads": false,
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Получение списка групп
|
||||
|
||||
```bash
|
||||
# Без API ключа (только названия)
|
||||
GET /api/v1/groups
|
||||
|
||||
# С API ключом (полная информация)
|
||||
GET /api/v1/groups
|
||||
Headers: X-API-Key: your_api_key_here
|
||||
```
|
||||
|
||||
**Пример ответа (без API ключа):**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"groups": [
|
||||
{"name": "monitoring", "chat_id": null},
|
||||
{"name": "alerts", "chat_id": null}
|
||||
],
|
||||
"count": 2
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа (с API ключом):**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"groups": [
|
||||
{
|
||||
"name": "monitoring",
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567890,
|
||||
"thread_id": 0
|
||||
},
|
||||
{
|
||||
"name": "alerts_max",
|
||||
"messenger": "max",
|
||||
"chat_id": "123456789",
|
||||
"thread_id": null
|
||||
}
|
||||
],
|
||||
"count": 2
|
||||
}
|
||||
```
|
||||
|
||||
### Создание группы
|
||||
|
||||
```bash
|
||||
POST /api/v1/groups
|
||||
Headers:
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"group_name": "monitoring",
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567890,
|
||||
"thread_id": 0
|
||||
}
|
||||
```
|
||||
|
||||
**Пример запроса для MAX/VK:**
|
||||
```bash
|
||||
POST /api/v1/groups
|
||||
Headers:
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"group_name": "max_alerts",
|
||||
"messenger": "max",
|
||||
"chat_id": "123456789",
|
||||
"thread_id": 0,
|
||||
"config": {
|
||||
"access_token": "your_max_access_token"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Группа 'monitoring' создана с мессенджером 'telegram' и ID -1001234567890"
|
||||
}
|
||||
```
|
||||
|
||||
### Обновление группы
|
||||
|
||||
```bash
|
||||
PUT /api/v1/groups/{group_name}
|
||||
Headers:
|
||||
Content-Type: application/json
|
||||
X-API-Key: your_api_key_here
|
||||
|
||||
{
|
||||
"messenger": "telegram",
|
||||
"chat_id": -1001234567891,
|
||||
"thread_id": 0
|
||||
}
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Группа 'monitoring' обновлена"
|
||||
}
|
||||
```
|
||||
|
||||
### Удаление группы
|
||||
|
||||
```bash
|
||||
DELETE /api/v1/groups/{group_name}
|
||||
Headers: X-API-Key: your_api_key_here
|
||||
```
|
||||
|
||||
**Пример ответа:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "Группа 'monitoring' удалена"
|
||||
}
|
||||
```
|
||||
|
||||
**API ключ для управления группами:**
|
||||
- Настраивается в переменной окружения `API_KEY`
|
||||
- Без API ключа можно только просматривать названия групп
|
||||
- С API ключом доступны все операции (создание, обновление, удаление)
|
||||
- API ключ передается в заголовке: `X-API-Key: your_api_key_here`
|
||||
|
||||
113
docs/jira-mapping.md
Normal file
113
docs/jira-mapping.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Конфигурация Jira Mapping
|
||||
|
||||
## Формат конфигурации
|
||||
|
||||
Конфигурация маппинга Jira хранится в файле `config/jira_mapping.json`. Она определяет, какие тикеты создавать в Jira на основе алертов.
|
||||
|
||||
**Пример конфигурации:**
|
||||
```json
|
||||
{
|
||||
"alertmanager": {
|
||||
"default_project": "MON",
|
||||
"default_assignee": null,
|
||||
"default_issue_type": "Bug",
|
||||
"default_priority": "High",
|
||||
"mappings": [
|
||||
{
|
||||
"conditions": {
|
||||
"severity": "critical",
|
||||
"namespace": "production"
|
||||
},
|
||||
"project": "MON",
|
||||
"assignee": "devops-team@example.com",
|
||||
"issue_type": "Bug",
|
||||
"priority": "Highest",
|
||||
"labels": ["critical", "production", "alertmanager"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"grafana": {
|
||||
"default_project": "MON",
|
||||
"default_assignee": null,
|
||||
"default_issue_type": "Bug",
|
||||
"default_priority": "High",
|
||||
"mappings": []
|
||||
},
|
||||
"zabbix": {
|
||||
"default_project": "MON",
|
||||
"default_assignee": null,
|
||||
"default_issue_type": "Bug",
|
||||
"default_priority": "High",
|
||||
"mappings": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Условия маппинга
|
||||
|
||||
Условия маппинга определяют, когда использовать конкретный маппинг. Поддерживаются следующие условия:
|
||||
|
||||
### Для AlertManager:
|
||||
- `status` - статус алерта (firing, resolved)
|
||||
- `severity` - критичность (critical, warning, info)
|
||||
- `namespace` - namespace Kubernetes
|
||||
- `alertname` - название алерта
|
||||
- Любые другие метки из `commonLabels`
|
||||
|
||||
### Для Grafana:
|
||||
- `state` - состояние алерта (alerting, ok, paused, pending, no_data)
|
||||
- `ruleName` - название правила
|
||||
- `tags` - теги алерта (объект с ключами и значениями)
|
||||
|
||||
### Для Zabbix:
|
||||
- `status` - статус (PROBLEM, OK)
|
||||
- `event-severity` - серьезность события
|
||||
- `event-name` - название события
|
||||
- `host-name` - имя хоста
|
||||
|
||||
**Примеры условий:**
|
||||
```json
|
||||
{
|
||||
"conditions": {
|
||||
"severity": "critical",
|
||||
"namespace": "production"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"conditions": {
|
||||
"state": "alerting",
|
||||
"tags": {
|
||||
"environment": "production"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Приоритет маппингов:**
|
||||
1. Проверяются все маппинги в порядке их определения
|
||||
2. Используется первый маппинг, условия которого совпадают с данными алерта
|
||||
3. Если маппинг не найден, используются значения по умолчанию
|
||||
|
||||
## Автоматическое создание тикетов
|
||||
|
||||
При получении алерта, если интеграция с Jira включена и выполнены условия для создания тикета:
|
||||
|
||||
1. Приложение проверяет конфигурацию маппинга
|
||||
2. Находит подходящий маппинг на основе условий алерта
|
||||
3. Создает тикет в Jira с указанными параметрами
|
||||
4. Добавляет кнопку в Telegram сообщение со ссылкой на созданный тикет
|
||||
|
||||
**Настройка переменных окружения:**
|
||||
- `JIRA_ENABLED=true` - включить интеграцию с Jira
|
||||
- `JIRA_URL=https://jira.example.com` - URL Jira сервера
|
||||
- `JIRA_EMAIL=user@example.com` - Email пользователя Jira
|
||||
- `JIRA_API_TOKEN=your_jira_api_token_here` - API токен Jira
|
||||
- `JIRA_PROJECT_KEY=MON` - Ключ проекта Jira по умолчанию
|
||||
- `JIRA_DEFAULT_ASSIGNEE=user@example.com` - Исполнитель по умолчанию
|
||||
- `JIRA_DEFAULT_ISSUE_TYPE=Bug` - Тип задачи по умолчанию
|
||||
- `JIRA_CREATE_ON_ALERT=true` - Создавать тикет при алерте
|
||||
- `JIRA_CREATE_ON_RESOLVED=false` - Создавать тикет при resolved
|
||||
|
||||
54
docs/messaging.md
Normal file
54
docs/messaging.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Отправка сообщений
|
||||
|
||||
## Как работает отправка
|
||||
|
||||
1. **Получение алерта:**
|
||||
- Система мониторинга (Grafana, Zabbix, AlertManager) отправляет webhook на эндпоинт Message Gateway
|
||||
- Message Gateway валидирует данные алерта через Pydantic модели
|
||||
- Увеличивается счетчик полученных сообщений
|
||||
|
||||
2. **Обработка алерта:**
|
||||
- Проверяются стоп-слова (если алерт заблокирован, сообщение не отправляется)
|
||||
- Загружается конфигурация группы из `config/groups.json`
|
||||
- Определяется мессенджер (Telegram, MAX/VK) из конфигурации группы или параметра запроса
|
||||
|
||||
3. **Формирование сообщения:**
|
||||
- Загружается шаблон сообщения из `templates/`
|
||||
- Шаблон рендерится с данными алерта через Jinja2
|
||||
- Формируются кнопки для перехода к Grafana/Prometheus/Jira
|
||||
|
||||
4. **Создание Jira тикета (опционально):**
|
||||
- Если Jira включена и выполнены условия, создается тикет в Jira
|
||||
- Загружается маппинг из `config/jira_mapping.json`
|
||||
- Находится подходящий маппинг на основе условий алерта
|
||||
- Создается тикет с описанием из шаблона `jira_common.tmpl`
|
||||
- Добавляется кнопка для перехода к тикету в Jira
|
||||
|
||||
5. **Отправка в мессенджер:**
|
||||
- Создается клиент мессенджера через `MessengerFactory`
|
||||
- Проверяется поддержка тредов (для MAX/VK треды не поддерживаются)
|
||||
- Сообщение отправляется в мессенджер через клиент
|
||||
- Увеличивается счетчик отправленных сообщений
|
||||
|
||||
## Поддержка мессенджеров
|
||||
|
||||
### Telegram
|
||||
- ✅ Полная поддержка текстовых сообщений
|
||||
- ✅ Поддержка медиа (фото, видео, аудио, документы)
|
||||
- ✅ Поддержка тредов (threads)
|
||||
- ✅ Поддержка кнопок (InlineKeyboardMarkup)
|
||||
- ✅ Поддержка HTML и Markdown форматирования
|
||||
|
||||
### MAX/VK
|
||||
- ✅ Поддержка текстовых сообщений
|
||||
- ✅ Поддержка медиа (фото, видео, аудио, документы)
|
||||
- ❌ Треды не поддерживаются (thread_id игнорируется)
|
||||
- ✅ Поддержка кнопок (в формате VK API)
|
||||
- ✅ Конвертация HTML в формат VK
|
||||
|
||||
**Различия в отправке:**
|
||||
- Telegram использует Bot API, MAX/VK использует VK API
|
||||
- Telegram поддерживает треды, MAX/VK - нет
|
||||
- Формат кнопок различается (Telegram - InlineKeyboardMarkup, MAX/VK - JSON)
|
||||
- HTML форматирование конвертируется в формат VK для MAX/VK
|
||||
|
||||
121
docs/monitoring/alertmanager.md
Normal file
121
docs/monitoring/alertmanager.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Настройка AlertManager
|
||||
|
||||
## Создание конфигурации AlertManager
|
||||
|
||||
1. **Открытие конфигурации:**
|
||||
- Откройте файл конфигурации AlertManager (обычно `alertmanager.yml`)
|
||||
- Добавьте webhook receiver:
|
||||
|
||||
```yaml
|
||||
receivers:
|
||||
- name: 'message-gateway'
|
||||
webhook_configs:
|
||||
- url: 'http://your-gateway-url/api/v1/alertmanager/{k8s_cluster}/{group_name}/{thread_id}'
|
||||
send_resolved: true
|
||||
http_config:
|
||||
bearer_token: 'optional-bearer-token'
|
||||
```
|
||||
|
||||
2. **Настройка Route:**
|
||||
- В конфигурации AlertManager добавьте route:
|
||||
|
||||
```yaml
|
||||
route:
|
||||
group_by: ['alertname', 'cluster', 'service']
|
||||
group_wait: 10s
|
||||
group_interval: 10s
|
||||
repeat_interval: 12h
|
||||
receiver: 'message-gateway'
|
||||
routes:
|
||||
- match:
|
||||
severity: critical
|
||||
receiver: 'message-gateway'
|
||||
continue: true
|
||||
- match:
|
||||
severity: warning
|
||||
receiver: 'message-gateway'
|
||||
```
|
||||
|
||||
3. **Применение конфигурации:**
|
||||
- Сохраните файл конфигурации
|
||||
- Перезапустите AlertManager или перезагрузите конфигурацию:
|
||||
```bash
|
||||
curl -X POST http://alertmanager:9093/-/reload
|
||||
```
|
||||
|
||||
## Пример конфигурации
|
||||
|
||||
**Полный пример `alertmanager.yml`:**
|
||||
```yaml
|
||||
global:
|
||||
resolve_timeout: 5m
|
||||
|
||||
route:
|
||||
group_by: ['alertname', 'cluster', 'service']
|
||||
group_wait: 10s
|
||||
group_interval: 10s
|
||||
repeat_interval: 12h
|
||||
receiver: 'message-gateway'
|
||||
routes:
|
||||
- match:
|
||||
severity: critical
|
||||
receiver: 'message-gateway'
|
||||
continue: true
|
||||
- match:
|
||||
severity: warning
|
||||
receiver: 'message-gateway'
|
||||
|
||||
receivers:
|
||||
- name: 'message-gateway'
|
||||
webhook_configs:
|
||||
- url: 'http://message-gateway.example.com/api/v1/alertmanager/production/monitoring/0'
|
||||
send_resolved: true
|
||||
```
|
||||
|
||||
**Пример URL для webhook:**
|
||||
```
|
||||
http://message-gateway.example.com/api/v1/alertmanager/production/monitoring/0
|
||||
```
|
||||
|
||||
Где:
|
||||
- `production` - имя Kubernetes кластера (используется для формирования URL к Grafana/Prometheus)
|
||||
- `monitoring` - имя группы из `config/groups.json`
|
||||
- `0` - ID треда (0 для основной группы, поддерживается только для Telegram)
|
||||
|
||||
## Формат данных
|
||||
|
||||
AlertManager отправляет данные в следующем формате:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "firing",
|
||||
"externalURL": "http://alertmanager.example.com",
|
||||
"commonLabels": {
|
||||
"alertname": "HighCPUUsage",
|
||||
"severity": "critical",
|
||||
"namespace": "production",
|
||||
"pod": "app-deployment-7d8f9b4c5-abc123",
|
||||
"container": "app-container"
|
||||
},
|
||||
"commonAnnotations": {
|
||||
"summary": "High CPU usage detected in production namespace",
|
||||
"description": "CPU usage is above 90% for 5 minutes on pod app-deployment-7d8f9b4c5-abc123",
|
||||
"runbook_url": "https://wiki.example.com/runbooks/high-cpu-usage"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Поддерживаемые статусы
|
||||
|
||||
- `firing` - алерт сработал
|
||||
- `resolved` - алерт разрешен
|
||||
|
||||
## Примечания
|
||||
|
||||
- Не требует авторизации (API ключ не нужен)
|
||||
- Если Jira включена, будет автоматически создан тикет в Jira (внутренний процесс)
|
||||
- В сообщении будет добавлена кнопка для перехода к тикету в Jira (если поддерживается мессенджером)
|
||||
- Алерты могут быть заблокированы стоп-словами (настройка в config/stop_words.txt)
|
||||
- URL к Grafana/Prometheus/AlertManager формируется на основе имени кластера
|
||||
- Thread ID поддерживается только для Telegram (для MAX/VK игнорируется)
|
||||
|
||||
91
docs/monitoring/grafana.md
Normal file
91
docs/monitoring/grafana.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Настройка Grafana
|
||||
|
||||
## Создание Webhook Notification Channel
|
||||
|
||||
1. **Открытие настроек:**
|
||||
- Откройте Grafana и перейдите в раздел "Alerting" → "Notification channels"
|
||||
- Нажмите "New channel"
|
||||
|
||||
2. **Настройка webhook:**
|
||||
- Выберите тип "Webhook"
|
||||
- Заполните форму:
|
||||
- **Name:** Message Gateway
|
||||
- **Type:** webhook
|
||||
- **URL:** `http://your-gateway-url/api/v1/grafana/{group_name}/{thread_id}`
|
||||
- Где `{group_name}` - имя группы из `config/groups.json` (например, "monitoring")
|
||||
- Где `{thread_id}` - ID треда (0 для основной группы, поддерживается только для Telegram)
|
||||
- **HTTP Method:** POST
|
||||
- **Send on all alerts:** включено
|
||||
- **Include image:** опционально
|
||||
- Сохраните настройки
|
||||
|
||||
3. **Настройка Alert Rule:**
|
||||
- Создайте или откройте существующее правило алерта
|
||||
- В разделе "Notifications" выберите созданный канал "Message Gateway"
|
||||
- Сохраните правило
|
||||
|
||||
4. **Тестирование:**
|
||||
- Создайте тестовый алерт в Grafana
|
||||
- Проверьте, что сообщение пришло в Telegram/MAX
|
||||
|
||||
**Пример URL для webhook:**
|
||||
```
|
||||
http://message-gateway.example.com/api/v1/grafana/monitoring/0
|
||||
```
|
||||
|
||||
## Пример конфигурации
|
||||
|
||||
**Notification Channel в Grafana:**
|
||||
- **Name:** Message Gateway
|
||||
- **Type:** Webhook
|
||||
- **URL:** `http://message-gateway.example.com/api/v1/grafana/monitoring/0`
|
||||
- **HTTP Method:** POST
|
||||
- **Send on all alerts:** Yes
|
||||
- **Include image:** No
|
||||
|
||||
**Alert Rule:**
|
||||
- В разделе "Notifications" выберите "Message Gateway"
|
||||
- Сохраните правило
|
||||
|
||||
## Формат данных
|
||||
|
||||
Grafana отправляет данные в следующем формате:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "[Alerting] High CPU Usage",
|
||||
"ruleId": 674180201771804383,
|
||||
"ruleName": "High CPU Usage Alert",
|
||||
"state": "alerting",
|
||||
"evalMatches": [
|
||||
{
|
||||
"value": 95.5,
|
||||
"metric": "cpu_usage_percent",
|
||||
"tags": {"host": "server01", "instance": "production"}
|
||||
}
|
||||
],
|
||||
"orgId": 1,
|
||||
"dashboardId": 123,
|
||||
"panelId": 456,
|
||||
"tags": {"severity": "critical", "environment": "production"},
|
||||
"ruleUrl": "http://grafana.cism-ms.ru/alerting/list",
|
||||
"message": "CPU usage is above 90% threshold for more than 5 minutes"
|
||||
}
|
||||
```
|
||||
|
||||
## Поддерживаемые состояния
|
||||
|
||||
- `alerting` - алерт сработал
|
||||
- `ok` - алерт разрешен
|
||||
- `paused` - алерт приостановлен
|
||||
- `pending` - алерт в ожидании
|
||||
- `no_data` - нет данных
|
||||
|
||||
## Примечания
|
||||
|
||||
- Не требует авторизации (API ключ не нужен)
|
||||
- Если Jira включена, будет автоматически создан тикет в Jira (внутренний процесс)
|
||||
- В сообщении будет добавлена кнопка для перехода к тикету в Jira (если поддерживается мессенджером)
|
||||
- URL правила алерта будет добавлен в сообщение
|
||||
- Thread ID поддерживается только для Telegram (для MAX/VK игнорируется)
|
||||
|
||||
107
docs/monitoring/zabbix.md
Normal file
107
docs/monitoring/zabbix.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# Настройка Zabbix
|
||||
|
||||
## Создание Media Type
|
||||
|
||||
1. **Открытие настроек:**
|
||||
- Откройте Zabbix и перейдите в раздел "Administration" → "Media types"
|
||||
- Нажмите "Create media type"
|
||||
|
||||
2. **Настройка Media Type:**
|
||||
- Заполните форму:
|
||||
- **Name:** Message Gateway
|
||||
- **Type:** Webhook
|
||||
- **Script name:** message-gateway
|
||||
- **Script parameters:**
|
||||
```
|
||||
{ALERT.SENDTO}
|
||||
{ALERT.SUBJECT}
|
||||
{ALERT.MESSAGE}
|
||||
```
|
||||
- Сохраните настройки
|
||||
|
||||
3. **Создание Action:**
|
||||
- Перейдите в раздел "Configuration" → "Actions" → "Trigger actions"
|
||||
- Нажмите "Create action"
|
||||
- Заполните форму:
|
||||
- **Name:** Send to Message Gateway
|
||||
- **Conditions:** выберите условия (например, "Trigger severity" = "High")
|
||||
- **Operations:** добавьте операцию "Send to Message Gateway"
|
||||
- **Recovery operations:** добавьте операцию "Send to Message Gateway"
|
||||
- Сохраните настройки
|
||||
|
||||
4. **Настройка User Media:**
|
||||
- Откройте пользователя в Zabbix
|
||||
- В разделе "Media" добавьте новый media:
|
||||
- **Type:** Message Gateway
|
||||
- **Send to:** `monitoring/0` (формат: `{group_name}/{thread_id}`)
|
||||
- **When active:** 1-7,00:00-24:00
|
||||
- Сохраните настройки
|
||||
|
||||
## Пример конфигурации
|
||||
|
||||
**Media Type в Zabbix:**
|
||||
- **Name:** Message Gateway
|
||||
- **Type:** Webhook
|
||||
- **Script name:** message-gateway
|
||||
- **Script parameters:**
|
||||
```
|
||||
{ALERT.SENDTO}
|
||||
{ALERT.SUBJECT}
|
||||
{ALERT.MESSAGE}
|
||||
```
|
||||
|
||||
**Action:**
|
||||
- **Name:** Send to Message Gateway
|
||||
- **Conditions:** Trigger severity = High
|
||||
- **Operations:** Send to Message Gateway
|
||||
- **Recovery operations:** Send to Message Gateway
|
||||
|
||||
**User Media:**
|
||||
- **Type:** Message Gateway
|
||||
- **Send to:** `monitoring/0`
|
||||
- **When active:** 1-7,00:00-24:00
|
||||
|
||||
## Формат данных
|
||||
|
||||
Zabbix отправляет данные в следующем формате:
|
||||
|
||||
```json
|
||||
{
|
||||
"link": "https://zabbix.example.com/tr_events.php?triggerid=42667&eventid=8819711",
|
||||
"status": "PROBLEM",
|
||||
"action-id": "7",
|
||||
"alert-subject": "Problem: High CPU utilization (over 90% for 5m)",
|
||||
"alert-message": "Problem started at 16:48:44 on 2024.02.08",
|
||||
"event-id": "8819711",
|
||||
"event-name": "High CPU utilization (over 90% for 5m)",
|
||||
"event-nseverity": "2",
|
||||
"event-opdata": "Current utilization: 95.2 %",
|
||||
"event-severity": "Warning",
|
||||
"host-name": "pnode28",
|
||||
"host-ip": "10.14.253.38",
|
||||
"host-port": "10050"
|
||||
}
|
||||
```
|
||||
|
||||
## Поддерживаемые статусы
|
||||
|
||||
- `PROBLEM` - проблема обнаружена
|
||||
- `OK` - проблема разрешена
|
||||
|
||||
## Уровни серьезности
|
||||
|
||||
- `Disaster` - катастрофа
|
||||
- `High` - высокая
|
||||
- `Warning` - предупреждение
|
||||
- `Average` - средняя
|
||||
- `Information` - информация
|
||||
|
||||
## Примечания
|
||||
|
||||
- Не требует авторизации (API ключ не нужен)
|
||||
- Если Jira включена, будет автоматически создан тикет в Jira (внутренний процесс)
|
||||
- В сообщении будет добавлена кнопка для перехода к тикету в Jira (если поддерживается мессенджером)
|
||||
- Ссылка на событие Zabbix будет добавлена в сообщение
|
||||
- Thread ID поддерживается только для Telegram (для MAX/VK игнорируется)
|
||||
- Можно настроить фильтрацию по серьезности события
|
||||
|
||||
226
docs/templates.md
Normal file
226
docs/templates.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# Шаблоны сообщений
|
||||
|
||||
## Структура шаблонов
|
||||
|
||||
Шаблоны сообщений находятся в папке `templates/` и используют синтаксис Jinja2. Шаблоны разделены на две категории:
|
||||
|
||||
1. **Шаблоны для мессенджеров** - форматирование сообщений для отправки в Telegram, MAX/VK
|
||||
2. **Шаблоны для Jira** - форматирование описания тикетов в Jira
|
||||
|
||||
## Шаблоны для мессенджеров
|
||||
|
||||
### Grafana (`templates/grafana.tmpl`)
|
||||
|
||||
Шаблон для форматирования алертов из Grafana:
|
||||
|
||||
```jinja2
|
||||
{{ alert_icon }} <b>{{ title }}</b>
|
||||
|
||||
{% if status_name is defined %}{{ status_icon }} <b>Критичность</b>: {{ status_name }}{% endif %}
|
||||
|
||||
<b>Подробнее:</b>
|
||||
{{ message }}
|
||||
{% if labels %}
|
||||
👉 <b>Переменные:</b>
|
||||
|
||||
{{ labels }}{% endif %}
|
||||
{% if tags and state !='ok' %}💻 <b>Ответственные:</b>
|
||||
|
||||
{{ tags }}{% endif %}
|
||||
```
|
||||
|
||||
**Доступные переменные:**
|
||||
- `alert_icon` - иконка алерта (🔴, 🟢, 🟡, 🟠, 🔵)
|
||||
- `status_icon` - иконка статуса (💀, ✅, 🐢, 🤷, 🥴)
|
||||
- `status_name` - название статуса
|
||||
- `title` - заголовок алерта
|
||||
- `message` - сообщение алерта
|
||||
- `state` - состояние алерта (alerting, ok, paused, pending, no_data)
|
||||
- `labels` - метрики (evalMatches)
|
||||
- `tags` - теги алерта
|
||||
|
||||
### Zabbix (`templates/zabbix.tmpl`)
|
||||
|
||||
Шаблон для форматирования алертов из Zabbix:
|
||||
|
||||
```jinja2
|
||||
{{ alert_icon }} <b>{{ title }}</b>
|
||||
|
||||
{% if status_name is defined %}{{ status_icon }} <b>Критичность</b>: {{ status_name }} ({{ state }}){% endif %}
|
||||
|
||||
<b>Кратко:</b>
|
||||
{{ subject }}
|
||||
|
||||
<b>Подробнее:</b>
|
||||
{{ message }}
|
||||
👉 <b>Значение:</b>
|
||||
{{ message_data }}
|
||||
|
||||
🌐 <b>Сеть:</b>
|
||||
Хост: {{ label_host }}
|
||||
IP: {{ label_ip }}
|
||||
Порт: {{ label_port }}
|
||||
```
|
||||
|
||||
**Доступные переменные:**
|
||||
- `alert_icon` - иконка алерта
|
||||
- `status_icon` - иконка статуса
|
||||
- `status_name` - название статуса
|
||||
- `title` - название события
|
||||
- `subject` - тема алерта
|
||||
- `message` - сообщение алерта
|
||||
- `message_data` - дополнительные данные события
|
||||
- `label_host` - имя хоста
|
||||
- `label_ip` - IP адрес хоста
|
||||
- `label_port` - порт хоста
|
||||
|
||||
### AlertManager (`templates/alertmanager.tmpl`)
|
||||
|
||||
Шаблон для форматирования алертов из AlertManager:
|
||||
|
||||
```jinja2
|
||||
{{ alert_icon }} <b>{{ alertname }}</b>
|
||||
|
||||
{% if summary is defined %}{{ summary }}{% endif %}
|
||||
|
||||
{% if status_name is defined %}{{ status_icon }} <b>Критичность</b>: {{ status_name }}{% endif %}{% if description is defined %}
|
||||
|
||||
<b>Подробнее:</b>
|
||||
{{ description }}{% endif %}{% if another_annotations != "" %}
|
||||
{{ another_annotations }}{% endif %}
|
||||
|
||||
{% if clustername is defined %}👉 <b>Kubernetes:</b>
|
||||
|
||||
<b>Кластер</b>: {{ clustername }}{% if node is defined %}
|
||||
<b>Нода</b>: {{ node }}{% endif %}{% if ns is defined %}
|
||||
<b>Неймспейс</b>: {{ ns }}{% endif %}{% if deployment is defined %}
|
||||
<b>Деплоймент</b>: {{ deployment }}{% endif %}{% if daemonset is defined %}
|
||||
<b>Демонсет</b>: {{ daemonset }}{% endif %}{% if replicaset is defined %}
|
||||
<b>Репликасет</b>: {{ replicaset }}{% endif %}{% if statefulset is defined %}
|
||||
<b>Стейтфулсет</b>: {{ statefulset }}{% endif %}{% if container is defined %}
|
||||
<b>Контейнер</b>: {{ container }}{% endif %}{% if pod is defined %}
|
||||
<b>Под</b>: {{ pod }}{% endif %}{% if persistentvolumeclaim is defined %}
|
||||
<b>PVC</b>: {{ persistentvolumeclaim }}{% endif %}{% if job_name is defined %}
|
||||
<b>Имя джобы</b>: {{ job_name }}{% endif %}{% if job is defined %}
|
||||
<b>Джоба</b>: {{ job }}{% endif %}{% if reason is defined %}
|
||||
<b>Причина</b>: {{ reason }}{% endif %}{% if endpoint is defined %}
|
||||
<b>Эндпоинт</b>: {{ endpoint }}{% endif %}{% if instance is defined %}
|
||||
<b>Инстанс</b>: {{ instance }}{% endif %}{% if condition is defined %}
|
||||
<b>Состояние</b>: {{ condition }}{% endif %}{% if reason is defined %}
|
||||
<b>Причина</b>: {{ reason }}{% endif %}{% endif %}
|
||||
|
||||
{% if prometheus is defined %}🔍 <b>Прометей:</b>
|
||||
|
||||
<b>Сервер</b>: {{ prometheus }}{% if service is defined %}
|
||||
<b>Сервис</b>: {{ service }}{% endif %}{% if metrics_path is defined %}
|
||||
<b>Метрики</b>: {{ metrics_path }}{% endif %}{% if uid is defined %}
|
||||
<b>UID</b>: {{ uid }}{% endif %}{% if integration is defined %}
|
||||
<b>Integration</b>: {{ integration }}{% endif %}{% if To is defined %}
|
||||
<b>To</b>: {{ integration }}{% endif %}{% endif %}
|
||||
|
||||
{% if another_labels != "" %}
|
||||
🤷 <b>Разное</b>:
|
||||
|
||||
{{ another_labels }}{% endif %}
|
||||
```
|
||||
|
||||
**Доступные переменные:**
|
||||
- `alert_icon` - иконка алерта
|
||||
- `status_icon` - иконка статуса
|
||||
- `status_name` - название статуса
|
||||
- `alertname` - название алерта
|
||||
- `summary` - краткое описание
|
||||
- `description` - подробное описание
|
||||
- `another_annotations` - дополнительные аннотации
|
||||
- `clustername` - имя кластера Kubernetes
|
||||
- `node` - имя ноды
|
||||
- `ns` - namespace
|
||||
- `deployment` - имя deployment
|
||||
- `pod` - имя pod
|
||||
- `container` - имя контейнера
|
||||
- И другие метки из `commonLabels`
|
||||
|
||||
## Шаблоны для Jira
|
||||
|
||||
### Общий шаблон (`templates/jira_common.tmpl`)
|
||||
|
||||
Шаблон для форматирования описания тикетов в Jira:
|
||||
|
||||
```jinja2
|
||||
**Источник:** {{ source }}
|
||||
|
||||
{% if k8s_cluster %}**Kubernetes кластер:** {{ k8s_cluster }}{% endif %}
|
||||
|
||||
---
|
||||
|
||||
## Детали алерта
|
||||
|
||||
{% if source == "alertmanager" %}
|
||||
**Статус:** {{ status }}
|
||||
**Название:** {{ alertname }}
|
||||
**Критичность:** {{ severity }}
|
||||
|
||||
{% if summary %}**Краткое описание:**
|
||||
{{ summary }}
|
||||
{% endif %}
|
||||
|
||||
{% if description %}**Подробное описание:**
|
||||
{{ description }}
|
||||
{% endif %}
|
||||
|
||||
**Метки:**
|
||||
{% for key, value in common_labels.items() %}
|
||||
- *{{ key }}*: {{ value }}
|
||||
{% endfor %}
|
||||
|
||||
**Аннотации:**
|
||||
{% for key, value in common_annotations.items() %}
|
||||
- *{{ key }}*: {{ value }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if source == "grafana" %}
|
||||
**Состояние:** {{ state }}
|
||||
**Правило:** {{ ruleName }}
|
||||
**Заголовок:** {{ title }}
|
||||
|
||||
{% if message %}**Сообщение:**
|
||||
{{ message }}
|
||||
{% endif %}
|
||||
|
||||
{% if tags %}**Теги:**
|
||||
{% for key, value in tags.items() %}
|
||||
- *{{ key }}*: {{ value }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if evalMatches %}**Метрики:**
|
||||
{% for match in evalMatches %}
|
||||
- *{{ match.metric }}*: {{ match.value }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if source == "zabbix" %}
|
||||
**Статус:** {{ status }}
|
||||
**Серьезность:** {{ event_severity }}
|
||||
**Событие:** {{ event_name }}
|
||||
**Хост:** {{ host_name }} ({{ host_ip }}:{{ host_port }})
|
||||
|
||||
**Тема:**
|
||||
{{ alert_subject }}
|
||||
|
||||
**Сообщение:**
|
||||
{{ alert_message }}
|
||||
{% endif %}
|
||||
|
||||
---
|
||||
|
||||
*Тикет создан автоматически системой мониторинга*
|
||||
```
|
||||
|
||||
**Примечания:**
|
||||
- Шаблон поддерживает условное форматирование в зависимости от источника алерта
|
||||
- Для каждого источника доступны свои переменные
|
||||
- Можно создать отдельные шаблоны для каждого источника: `jira_alertmanager.tmpl`, `jira_grafana.tmpl`, `jira_zabbix.tmpl`
|
||||
|
||||
Reference in New Issue
Block a user