Files
AWatch-rus/docs/GRAFANA_DASHBOARDS_RU.md
T

187 lines
8.7 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 dashboard'ы AW-rus
Документ описывает воспроизводимый импорт Grafana dashboard'ов из репозитория через Ansible и HTTP API Grafana.
## Что лежит в git
Version-controlled dashboard JSON находятся в каталоге `grafana/`:
- `grafana/detmir-rdp-user-activity-dashboard.json`
- `grafana/detmir-dlp-security-dashboard.json`
- `grafana/detmir-dlp-management-dashboard.json`
- `grafana/dlp-dashboard.json`
Их импортирует playbook:
- `ansible/deploy_grafana_dashboards.yml`
## Что импортируется
1. `AWatch-rus: Работа пользователей в RDP`
2. `AWatch-rus: DLP и ИБ обзор`
3. `AWatch-rus: ИБ сводка для руководства`
4. `AW-rus: DLP обзор`
По умолчанию playbook складывает их в folder `AWatch-rus` с `uid=awatch-rus`.
## Worktime panels и canonical users
Worktime dashboard'ы читают InfluxDB measurement
`aw_rdp_worktime_daily`/`aw_rdp_worktime_hourly` и группируют данные по user
label. Старые exporter versions писали raw `username`/`userId`, поэтому в
Influx могли остаться отдельные series для `USER5/user5`,
`Администратор/администратор`, machine account `SHARKON2025$` и битых строк с
Unicode replacement char ``.
Version-controlled dashboard JSON должны сохранять защиту от старых series:
- `grafana/detmir-rdp-user-activity-dashboard.json`;
- `grafana/detmir-aw-main-dashboard.json`.
Для affected Flux queries обязательны правила:
- фильтровать `user_id !~ /\$$/` и `user_id !~ //`;
- мапить текущие DetMir accounts в canonical labels:
`user1`, `user4`, `user5`, `Администратор`;
- grouping делать по `report_date,user` или `_time,user`;
- использовать `max(column: "_value")` после grouping, чтобы схлопнуть
duplicate series без удвоения часов.
После импорта проверять панель `Вчера: активность по сотрудникам`. Ожидаемые
labels: `user1`, `user4`, `user5`, `Администратор`. Bad labels list должен быть
пустым для `USER*`, `SHARKON2025$`, `администратор`, `` и labels, начинающихся
с `\`.
Owner-facing aggregate panel должен называться явно:
- title: `Все сотрудники: активное время по дням`;
- legend: `Все сотрудники`;
- field label: `Все сотрудники, ч`.
Не используйте `Команда` для этой панели: для владельца это выглядит как имя
отдельного пользователя или непонятной группы.
## Доступ владельца из портала
На production-контуре DetMir переход из `/portal` к Grafana dashboard'ам
выполняется без второго логина Grafana. Внешняя защита при этом остается на
gateway:
- `/portal/`, `/d/...`, `/dashboards` и `/r/grafana/` закрыты nginx Basic Auth;
- nginx после успешной gateway-авторизации передает в Grafana auth-proxy
заголовки:
- `X-WEBAUTH-USER: detmir-owner`;
- `X-WEBAUTH-NAME: AWatch-rus Owner`;
- `X-WEBAUTH-EMAIL: owner@awatch-rus.local`;
- Grafana принимает auth-proxy только от gateway `10.10.10.2`;
- созданный пользователь `detmir-owner` не является Grafana admin и получает
viewer-доступ.
Основной dashboard для владельца:
```text
/d/detmir-rdp-user-activity/detmir3a-rabota-pol-zovatelej-v-rdp?orgId=1&from=now-7d&to=now&timezone=browser&var-host=SHARKON2025&refresh=5m
```
В портале он доступен как кнопка `Графики сотрудников`.
Не включайте `[auth.anonymous]` для решения этой задачи: это откроет Grafana на
внутреннем адресе `10.10.10.11:3000` без пользовательского контекста. Для
production используется только auth-proxy с whitelist gateway.
## Быстрый запуск
1. Подготовьте inventory и vars:
```bash
cd <PROJECT_ROOT>
cp ansible/inventory.example.ini ansible/inventory.ini
cp ansible/group_vars/grafana.example.yml ansible/group_vars/grafana.yml
```
2. Укажите `grafana_url` и заполните группу `[grafana]` в `ansible/inventory.ini`.
3. Перед запуском задайте пароль Grafana через переменную окружения:
```bash
export GRAFANA_ADMIN_PASSWORD='...'
```
4. Запустите импорт:
```bash
cd ansible
ansible-playbook -i inventory.ini deploy_grafana_dashboards.yml
```
## Что делает playbook
- проверяет `GET /api/health`;
- создает или обновляет folder `AWatch-rus`;
- импортирует dashboard JSON из репозитория;
- перезаписывает существующие dashboard'ы при `overwrite=true`;
- верифицирует каждый dashboard по `uid` через `GET /api/dashboards/uid/<uid>`.
## Production fallback при 403
Если Grafana API import запрещен (`403`) или provisioning не перезаписывает уже
существующую DB-запись dashboard, не правьте JSON только в UI. Сначала
обновите version-controlled dashboard JSON в git, затем примените один из
fallback paths.
Provisioning push:
```bash
scp grafana/detmir-aw-main-dashboard.json grafana/detmir-rdp-user-activity-dashboard.json igor@10.10.10.2:~/codex-dashboard-import/
ssh igor@10.10.10.2 'sudo pct push 201 /home/igor/codex-dashboard-import/detmir-aw-main-dashboard.json /etc/grafana/provisioning/dashboards/aw/detmir-aw-main.json --perms 0644'
ssh igor@10.10.10.2 'sudo pct push 201 /home/igor/codex-dashboard-import/detmir-rdp-user-activity-dashboard.json /etc/grafana/provisioning/dashboards/aw/detmir-rdp-user-activity.json --perms 0644'
ssh igor@10.10.10.2 'sudo pct exec 201 -- bash -lc "cp -a /var/lib/grafana/grafana.db /var/lib/grafana/grafana.db.bak.$(date -u +%Y%m%dT%H%M%SZ); systemctl restart grafana-server"'
```
DB fallback: после backup `/var/lib/grafana/grafana.db` заменить только
`dashboard.data` rows по uid нужных dashboard'ов и перезапустить
`grafana-server`. Для исправления worktime-дублей production backup был:
```text
/var/lib/grafana/grafana.db.bak.20260609T013605Z
```
Для production rename `Команда` -> `Все сотрудники` на `2026-06-09` были
обновлены DB-записи:
- `detmir-rdp-user-activity`;
- `detmir-aw-main`.
Backup перед изменением:
```text
/var/lib/grafana/grafana.db.bak.20260609T020225Z
```
Контроль через gateway Grafana API:
- старый title count: `0`;
- новый title count: `1`;
- старая legend count: `0`;
- новая legend count: `1`;
- dashboard page: HTTP `200`, title `Grafana`.
Если после этого в уже открытой вкладке всё ещё видно `Команда`, сначала
сделайте hard refresh: это старое состояние браузера, а не старая DB-запись.
## Переменные
- `grafana_url` — base URL Grafana, например `http://10.20.30.11:3000`
- `grafana_admin_user` — Grafana admin/API user
- `grafana_admin_password` — пароль, рекомендуется через `GRAFANA_ADMIN_PASSWORD`
- `grafana_validate_tls` — включать ли проверку TLS-сертификата
- `grafana_folder_uid` — UID целевого folder
- `grafana_folder_title` — отображаемое имя folder
- `grafana_dashboards_import_overwrite` — перезаписывать ли dashboard'ы при повторном импорте
## Рекомендуемый эксплуатационный режим
- редактировать dashboard JSON в `grafana/`, а не править production только руками в UI;
- после изменений прогонять `deploy_grafana_dashboards.yml`, чтобы Grafana вернулась к version-controlled состоянию;
- для презентации использовать [docs/PRESENTATION_RU.md](PRESENTATION_RU.md), где уже лежат скриншоты ключевых экранов.