grafana_gen/DATABASE_SCHEMA.md

230 lines
8.9 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.

# grafana_gen — схема базы данных
База данных PostgreSQL `waf_info`. Утилита работает в режиме **только чтение** — данные не изменяются.
---
## Таблицы
### `sp_info`
Автоматически заполняемый список ресурсов из ServicePipe.
| Колонка | Тип | Описание |
|---|---|---|
| `sid` | `text` | Идентификатор ресурса (SID). NULL-записи игнорируются |
| `domain_name` | `text` | Основной домен ресурса |
| `aliases` | `jsonb` | JSON-массив дополнительных доменов |
**Пример:**
```sql
SELECT sid, domain_name, aliases FROM sp_info WHERE sid IS NOT NULL LIMIT 3;
```
```
sid | domain_name | aliases
--------+------------------------+----------------------------------
10307 | nationallottery.ru | ["www.nationallottery.ru"]
11768 | fonbet-adapter.cloud.nationallottery.ru | []
14048 | self.nationallottery.ru | []
```
---
### `manual_info`
Ресурсы добавленные вручную (аналогична по структуре `sp_info`).
| Колонка | Тип | Описание |
|---|---|---|
| `sid` | `text` | Идентификатор ресурса |
| `domain_name` | `text` | Основной домен |
| `aliases` | `jsonb` | JSON-массив дополнительных доменов |
> Обе таблицы объединяются через `UNION` (без дублей). Если SID присутствует в обеих таблицах — берётся одна запись.
---
### `apps_settings`
Маппинг SID ресурса на клиента (тенанта).
| Колонка | Тип | Описание |
|---|---|---|
| `l7resourceid` | `text` | SID ресурса (FK к `sp_info.sid` / `manual_info.sid`) |
| `client_title` | `text` | Название клиента — имя тенанта в дашборде |
**Пример:**
```sql
SELECT l7resourceid, client_title FROM apps_settings LIMIT 5;
```
```
l7resourceid | client_title
--------------+--------------
10307 | nloto
11768 | nloto
14048 | nloto
15363 | gorodpay
12266 | gardia
```
> Один клиент может иметь несколько SID. Все SID одного клиента группируются в одну строку дашборда.
---
### `client_info`
Настройки мониторинга и пороги алертов для каждого клиента.
| Колонка | Тип | По умолчанию | Описание |
|---|---|---|---|
| `client_title` | `text` | — | Название клиента (PK, совпадает с `apps_settings.client_title`) |
| `rps_limit` | `integer` | NULL | Порог RPS для алерта. NULL = алерт не создавать |
| `rps_commercial_limit` | `integer` | NULL | Коммерческий лимит RPS — синяя линия на графике. NULL → 100 |
| `four_hundred` | `integer` | NULL | Порог 4xx ошибок в процентах. NULL = алерт не создавать |
| `five_hundred` | `integer` | NULL | Порог 5xx ошибок в процентах. NULL = алерт не создавать |
**Пример:**
```sql
SELECT client_title, rps_limit, rps_commercial_limit, four_hundred, five_hundred
FROM client_info
ORDER BY client_title;
```
```
client_title | rps_limit | rps_commercial_limit | four_hundred | five_hundred
--------------+-----------+----------------------+--------------+--------------
gardia | 500 | 300 | 20 | 10
gorodpay | 1000 | 800 | 20 | 10
nloto | 7000 | 5000 | 20 | 10
inferit | NULL | NULL | NULL | NULL
```
> Если `rps_limit = NULL` — алерт на RPS не создаётся, но клиент всё равно попадает в дашборд.
> Если `four_hundred = NULL` или `five_hundred = NULL` — соответствующий алерт не создаётся.
---
## Основной запрос
Утилита использует один объединённый запрос для получения всех данных:
```sql
SELECT
s.sid,
s.domain_name,
s.aliases,
a.client_title,
ci.rps_limit,
ci.rps_commercial_limit,
ci.four_hundred,
ci.five_hundred
FROM (
SELECT sid, domain_name, aliases FROM sp_info WHERE sid IS NOT NULL
UNION
SELECT sid, domain_name, aliases FROM manual_info WHERE sid IS NOT NULL
) s
LEFT JOIN apps_settings a ON s.sid = a.l7resourceid
LEFT JOIN client_info ci ON a.client_title = ci.client_title
ORDER BY a.client_title, s.sid;
```
Ресурсы без привязки к клиенту (`client_title IS NULL`) — **пропускаются**.
---
## Управление данными
### Добавление нового клиента
```sql
-- Шаг 1: ресурс появится автоматически из sp_info (если интеграция настроена)
-- Или добавить вручную:
INSERT INTO manual_info (sid, domain_name, aliases)
VALUES ('99999', 'example.com', '["www.example.com"]');
-- Шаг 2: привязать ресурс к клиенту
INSERT INTO apps_settings (l7resourceid, client_title)
VALUES ('99999', 'Название клиента');
-- Шаг 3: задать пороги алертов
INSERT INTO client_info (client_title, rps_limit, rps_commercial_limit, four_hundred, five_hundred)
VALUES ('Название клиента', 1800, 1200, 20, 10);
```
### Добавление нового ресурса к существующему клиенту
```sql
-- Только шаг 1 и 2:
INSERT INTO manual_info (sid, domain_name, aliases)
VALUES ('88888', 'new-domain.example.com', '[]');
INSERT INTO apps_settings (l7resourceid, client_title)
VALUES ('88888', 'Название клиента');
-- Пороги алертов уже есть в client_info — добавлять не нужно
```
### Изменение порогов алертов
```sql
UPDATE client_info
SET rps_limit = 2000, four_hundred = 30
WHERE client_title = 'Название клиента';
```
### Отключение алерта для клиента
```sql
-- Отключить только RPS алерт
UPDATE client_info SET rps_limit = NULL WHERE client_title = 'Название клиента';
-- Отключить все алерты
UPDATE client_info
SET rps_limit = NULL, four_hundred = NULL, five_hundred = NULL
WHERE client_title = 'Название клиента';
```
### Удаление клиента из дашборда
```sql
-- Удалить привязку всех ресурсов клиента
DELETE FROM apps_settings WHERE client_title = 'Название клиента';
-- Удалить пороги (опционально)
DELETE FROM client_info WHERE client_title = 'Название клиента';
```
### Просмотр всех клиентов с их ресурсами
```sql
SELECT
a.client_title,
COUNT(s.sid) AS domain_count,
array_agg(s.sid ORDER BY s.sid) AS sids,
ci.rps_limit,
ci.four_hundred,
ci.five_hundred
FROM (
SELECT sid FROM sp_info WHERE sid IS NOT NULL
UNION
SELECT sid FROM manual_info WHERE sid IS NOT NULL
) s
JOIN apps_settings a ON s.sid = a.l7resourceid
LEFT JOIN client_info ci ON a.client_title = ci.client_title
GROUP BY a.client_title, ci.rps_limit, ci.four_hundred, ci.five_hundred
ORDER BY a.client_title;
```
---
## Влияние данных на генерацию
| Данные | Влияние |
|---|---|
| Новый SID в `sp_info`/`manual_info` + запись в `apps_settings` | Новый домен добавится в строку клиента |
| Новый `client_title` в `apps_settings` | Новая строка клиента в дашборде |
| Изменение `rps_limit` | Пересоздание алерта RPS, обновление красной линии на графике |
| Изменение `rps_commercial_limit` | Обновление синей линии на графике |
| Изменение `four_hundred` / `five_hundred` | Пересоздание алертов 4xx/5xx |
| NULL в `rps_limit` | Алерт RPS удаляется (или не создаётся) |
| Удаление из `apps_settings` | Клиент/домен исчезает из дашборда при следующем запуске |
> Изменения в БД обнаруживаются через хэш (`alerts_hash` в `state.json`). При изменении любого порога — алерты пересоздаются автоматически при следующем запуске.