Analytics: make the pass, partial and fail indicators clickable
The three verdict cards on /analytics now open the same dialog as the https/ssh
cards, with the addresses of the run that got this verdict (CSV and copy
included). New list kinds verdict_pass, verdict_partial and verdict_fail in
GET /admin/analytics/runs/{id}/lists/{kind}: address, subnet, validator,
egress and ingress "ok of all", checks stored of expected; partial adds the
reason, the same names as the "Why partial" block. Cancelled addresses are not
listed; the row count equals summary.pass/partial/fail. The fail card stays
inert at zero. addr.incomplete() is shared by the list and the report.
Docs, plan and summary in docs/changes/.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e95b5eb7d5
commit
2f038f8362
15 files changed
+294
-14
No files matched your search
+2
-2
@@ -1067,9 +1067,9 @@ curl -s "$BASE/api/v1/admin/ips/203.0.113.10" | python3 -m json.tool
|
||||
### `GET /api/v1/admin/analytics/runs/{id}/lists/{kind}`
|
||||
|
||||
Таблица адресов за показателем или классом ошибки: `{"kind", "class", "columns": [...], "rows": [[...]]}`.
|
||||
`kind`: `egress_https_any`, `egress_https_all`, `ingress_ssh_any`, `ingress_ssh_all` или `error` (с `?class=SSH: таймаут`;
|
||||
`kind`: `verdict_pass`, `verdict_partial`, `verdict_fail`, `egress_https_any`, `egress_https_all`, `ingress_ssh_any`, `ingress_ssh_all` или `error` (с `?class=SSH: таймаут`;
|
||||
без класса и неизвестный `kind` — `404`). С `?format=csv` — файл CSV (UTF-8 с BOM, `Content-Disposition: attachment`,
|
||||
имя вида `ingress_ssh_all_run1.csv`). Для `error` строка — одна проваленная проверка: адрес, подсеть, площадка,
|
||||
имя вида `ingress_ssh_all_run1.csv`). Для `verdict_*` — адреса запуска с этим вердиктом (без `cancelled`, по числовому порядку; число строк равно `summary.pass`/`partial`/`fail`): адрес, подсеть, валидатор (по https-проверкам, «—», если их нет), `Egress` и `Ingress` («успешно из всех», «—» без проверок), «Проверок в цикле» (записано из ожидаемых) и у `partial` ещё «Причина» (как в блоке `reasons`). Для `error` строка — одна проваленная проверка: адрес, подсеть, площадка,
|
||||
валидатор, вердикт адреса, статус («провал, в вердикте» или «провал, после вердикта»).
|
||||
|
||||
### `GET /api/v1/admin/config/subnets`, `PUT /api/v1/admin/config/subnets`
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ admin-dashboard -config /etc/cloud-ip-validator/admin-dashboard.yaml
|
||||
| `/ips/{ip}` | Детали одного адреса, пока он в очереди: все проверки текущей попытки и вся история событий, плюс ссылка на полную историю в реестре (см. ниже). |
|
||||
| `/registry` | **Реестр** — все адреса, когда-либо поставленные на проверку, независимо от того, стоят ли они сейчас в очереди. Переживает удаление адреса из `/ips` и повторное добавление того же адреса позже (см. «Реестр адресов» ниже). Поиск по IP и фильтр по статусу — то же самое, что на `/overview`, плюс отражается в адресной строке (`?q=&status=`), так что отфильтрованную ссылку можно сохранить/переслать. В колонке «Последний результат» под вердиктом — уровни **Egress** и **Ingress** в виде «N из M» с разбивкой по типам проверок (`https`, `icmp`, `ssh`, `tcp`, `tls`…), см. [USAGE.md](USAGE.md#реестр-адресов-и-глубина-истории). |
|
||||
| `/registry/{ip}` | Полная сохранённая история проверок одного адреса по всем циклам (не только текущему) — в отличие от `/ips/{ip}`, которая показывает только текущую попытку. |
|
||||
| `/analytics` | **Аналитика** одного завершённого запуска (`?run=ID`, по умолчанию последний): выбор запуска (идущий виден, но недоступен), показатели, причины `partial`, качество данных, подсети, egress по целям (по типу проверки, тепловая карта «подсеть × цель»), ingress по площадкам, классы ошибок, валидаторы. Карточки провалов `https`/`ssh` и классы ошибок открывают список адресов с выгрузкой в CSV. Подробности — [USAGE.md](USAGE.md#аналитика-запусков). |
|
||||
| `/analytics` | **Аналитика** одного завершённого запуска (`?run=ID`, по умолчанию последний): выбор запуска (идущий виден, но недоступен), показатели, причины `partial`, качество данных, подсети, egress по целям (по типу проверки, тепловая карта «подсеть × цель»), ingress по площадкам, классы ошибок, валидаторы. Карточки `pass`/`partial`/`fail`, карточки провалов `https`/`ssh` и классы ошибок открывают список адресов с выгрузкой в CSV. Подробности — [USAGE.md](USAGE.md#аналитика-запусков). |
|
||||
| `/validators` | Список валидаторов + создание/изменение `os_port_id`/удаление. |
|
||||
| `/sites` | Площадки — число слотов не ограничено, форма сверху добавляет новый слот, назначить/сменить/освободить `site_id` в каждой строке; колонка «Статус» показывает бейдж подключения пробера (`unregistered`/`idle`/`unreachable`, по аналогии с `/validators`), см. [USAGE.md](USAGE.md#состояния-площадки). |
|
||||
| `/targets` | Группы целей для egress-проверок — создание/редактирование/удаление. |
|
||||
|
||||
+1
-1
@@ -440,7 +440,7 @@ curl -s http://<control-api>:8080/api/v1/admin/registry/203.0.113.10 | python3 -
|
||||
(поздние результаты, неполный набор). После изменения «вердикт без опоздавших результатов» поздних результатов в новых
|
||||
запусках быть не должно.
|
||||
|
||||
**Что можно открыть.** Карточки «Egress https: есть провалы / все провалены» и «Ingress ssh: есть провалы / все
|
||||
**Что можно открыть.** Карточки `pass`, `partial` и `fail` (список адресов с этим вердиктом: подсеть, валидатор, Egress и Ingress «успешно из всех», число проверок в цикле, у `partial` ещё причина; `fail` с нулём не кликается), карточки «Egress https: есть провалы / все провалены» и «Ingress ssh: есть провалы / все
|
||||
провалены», а также каждая строка блока «Классы ошибок ingress» открывают окно со списком адресов (для класса ошибок
|
||||
— с распределением по валидаторам и статусом каждой проверки). В окне кнопки «Скачать CSV» (файл от control-api,
|
||||
UTF-8 с BOM, открывается в Excel) и «Копировать». Строка подсети и строка матрицы «подсеть × цель» ведут в «Реестр»
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# План: кликабельные индикаторы PASS, PARTIAL, FAIL в разделе «Аналитика»
|
||||
|
||||
Статус: реализовано, см. [итог](2026-10-04_09-55_analytics-verdict-indicators-summary.md).
|
||||
|
||||
## 1. Что нужно
|
||||
|
||||
Вверху страницы `/analytics` есть ряд индикаторов. Сейчас кликабельны только четыре «прикладных»: «Egress https: есть провалы / все провалены» и «Ingress ssh: есть провалы / все провалены» (открывают окно со списком адресов, есть «Скачать CSV» и «Копировать»). Нужно сделать кликабельными ещё три: **pass**, **partial**, **fail**. По клику открывается тот же диалог со списком адресов с этим вердиктом.
|
||||
|
||||
Остальные индикаторы («Адресов», «Egress OK», «Ingress OK», «Длительность», «Поздние результаты») остаются как есть: в задаче их нет.
|
||||
|
||||
## 2. Решение
|
||||
|
||||
Новые виды списков строятся по тому же механизму, что и существующие: control-api отдаёт таблицу (JSON или CSV), дашборд проксирует, JS открывает диалог. Новых маршрутов, миграций и новых данных не нужно: вердикт, число проверок и причина `partial` уже вычисляются в `analytics.Compute`.
|
||||
|
||||
### 2.1. control-api (`internal/analytics/lists.go`)
|
||||
|
||||
Три новых вида списка (`kind`): `verdict_pass`, `verdict_partial`, `verdict_fail`. В список входят адреса запуска с этим вердиктом; отменённые (`cancelled`) не входят, как и в остальных списках и в числах `summary`. Порядок — по числовому адресу (`an.sorted()`).
|
||||
|
||||
Столбцы:
|
||||
|
||||
| Вид | Столбцы |
|
||||
|---|---|
|
||||
| `verdict_pass` | Адрес, Подсеть, Валидатор, Egress, Ingress, Проверок в цикле |
|
||||
| `verdict_partial` | Адрес, Подсеть, Валидатор, Egress, Ingress, Проверок в цикле, **Причина** |
|
||||
| `verdict_fail` | Адрес, Подсеть, Валидатор, Egress, Ingress, Проверок в цикле |
|
||||
|
||||
- «Валидатор» — тот же, что в списках https (`ShortValidator`); пусто → «—».
|
||||
- «Egress» и «Ingress» — «успешно из всех» по уровню (`8 из 10`); у уровня без проверок — «—».
|
||||
- «Проверок в цикле» — сохранённых из ожидаемых (`stored из ExpectedChecks`; если ожидаемое неизвестно, только сохранённое). Позволяет сразу увидеть «неполный набор».
|
||||
- «Причина» у `partial` — та же формулировка, что в блоке «Почему partial» (`reasonName`), поэтому строки списка совпадают со столбиками блока.
|
||||
|
||||
Название CSV: `verdict_pass_run<N>.csv` и т. д. (по общему правилу). Для остальных видов ничего не меняется. Неизвестный `kind` по-прежнему даёт `404`.
|
||||
|
||||
Инвариант: число строк списка равно числу на карточке (`summary.pass / partial / fail`).
|
||||
|
||||
### 2.2. Дашборд (`internal/dashboard/static/analytics.js`, `analytics.css`)
|
||||
|
||||
- В `renderKpis` у плиток `pass`, `partial`, `fail` в поле списка ставится соответствующий `kind`, плитка становится `<button class="an-kpi" data-list=…>` и получает «список →», как у прикладных. У `fail` при значении 0 плитка остаётся некликабельной (список пуст, сейчас там надпись «ни одной полностью проваленной»).
|
||||
- В `LISTS` добавляются три записи: заголовок («Адреса с вердиктом pass» и т. д.), пояснение («Вердикт адреса за последний цикл запуска, выставленный системой при агрегации…»), подсказки к столбцам (что значит Egress/Ingress, «Проверок в цикле», «Причина»).
|
||||
- Обработчик клика и диалог менять не нужно: `[data-list]` уже подхватывает любую плитку. Стили есть (`button.an-kpi`); `an-go` для плитки без тега «успех/частично/провал» ставится рядом с существующим тегом.
|
||||
- Серверной части дашборда (`handlers_analytics.go`, прокси списка и CSV) менять не нужно: `kind` в пути произвольный.
|
||||
|
||||
### 2.3. Объём списка pass
|
||||
|
||||
В запуске на ~6400 адресов `pass` может быть несколько тысяч строк. Диалог сейчас показывает все строки. Оставляем так (таблица на несколько тысяч строк в браузере открывается нормально) и проверяем на реальном объёме при выкладке; если окно тормозит — отдельным шагом добавим показ первых N строк с пометкой «полный список — в CSV». Выгрузка в CSV и копирование всегда полные.
|
||||
|
||||
## 3. Файлы
|
||||
|
||||
- `internal/analytics/lists.go` — константы, столбцы и строки новых видов.
|
||||
- `internal/analytics/analytics.go` — только если нужна вспомогательная функция для строки «Egress/Ingress» (иначе без изменений).
|
||||
- `internal/httpapi/handlers_analytics.go` — только комментарий с перечнем видов.
|
||||
- `internal/dashboard/static/analytics.js` — плитки и `LISTS`.
|
||||
- Документы: `docs/API.md` (перечень `kind`), `docs/USAGE.md` («Что можно открыть»), `docs/DASHBOARD.md` (строка `/analytics`), `README.md` (веха), итог `docs/changes/…-summary.md`.
|
||||
|
||||
## 4. Тесты
|
||||
|
||||
- `analytics`: для набора с pass, partial, fail и cancelled — число строк каждого списка равно `summary`; отменённые не входят; порядок по адресу; столбцы и значения «Egress/Ingress/Проверок в цикле»; «Причина» совпадает с `reasons`; у неполного набора в «Проверок в цикле» меньше ожидаемого.
|
||||
- `httpapi`: `GET …/lists/verdict_partial` отдаёт JSON, `?format=csv` — файл с именем `verdict_partial_run<N>.csv`; неизвестный вид — `404` (уже есть, расширить).
|
||||
- `dashboard`: прокси списка пропускает новые виды; в отданных данных страницы плитки pass/partial/fail имеют ссылки (если страница это проверяет без JS — иначе проверка вручную, п. 5).
|
||||
- Полный `gofmt -l`, `go build ./... && go vet ./... && go test ./...`.
|
||||
|
||||
## 5. Выкладка и проверка
|
||||
|
||||
Меняются `control-api` (список) и `admin-dashboard` (статика встроена в бинарник); агенты и prober без изменений, миграций нет. Порядок: проверка пустой очереди, тег отката образов, пересборка, перезапуск. Проверка на стенде: на последнем запуске открыть плитки pass, partial, fail, сверить число в заголовке диалога с числом на плитке, скачать CSV, проверить фильтрацию и подсказки; оценить скорость окна на списке pass.
|
||||
|
||||
## 6. Риски
|
||||
|
||||
- Большой список pass: см. 2.3.
|
||||
- Вердикт — оценка системы при агрегации, а не по фактическим проверкам (см. «Качество данных»): у адреса pass могут быть поздние провалы. В пояснении диалога это указывается; столбцы Egress/Ingress показывают фактические проверки.
|
||||
- Числа на плитках и в списках берутся из одного вычисления отчёта, поэтому расходиться не должны (инвариант в тесте).
|
||||
|
||||
## 7. Не входит в доработку
|
||||
|
||||
Кликабельность «Egress OK», «Ingress OK», «Адресов», «Поздних результатов»; фильтры и сортировка внутри диалога; ссылка из строки диалога в «Реестр».
|
||||
|
||||
Открытых вопросов нет. Жду команды начать реализацию.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Итог: кликабельные индикаторы pass, partial, fail в «Аналитике»
|
||||
|
||||
План: [2026-10-04_09-55_analytics-verdict-indicators-plan.md](2026-10-04_09-55_analytics-verdict-indicators-plan.md).
|
||||
Статус: код написан и проверен (gofmt, build, vet, test, синтаксис JS); стенд **не пересобирался**.
|
||||
|
||||
## Что изменено
|
||||
|
||||
- **control-api** (`internal/analytics/lists.go`): виды списков `verdict_pass`, `verdict_partial`, `verdict_fail`. Строки: адреса запуска с этим вердиктом, без `cancelled`, по числовому порядку. Столбцы: Адрес, Подсеть, Валидатор, Egress, Ingress, «Проверок в цикле»; у `partial` ещё «Причина» (та же формула, что в блоке «Почему partial»). Число строк равно `summary.pass/partial/fail`.
|
||||
- Метод `addr.incomplete()` (`analytics.go`): «неполный набор» считается одним кодом для списка и для отчёта; логика отчёта не менялась.
|
||||
- **Дашборд** (`analytics.js`): плитки `pass`, `partial`, `fail` стали кнопками со списком и «список →»; `fail` с нулём остаётся некликабельной. В `LISTS` три записи с пояснением и подсказками к столбцам. Диалог, CSS и прокси дашборда не менялись.
|
||||
- **Документы**: `API.md`, `USAGE.md`, `DASHBOARD.md`, `README.md`.
|
||||
|
||||
## Особенности
|
||||
|
||||
- «Валидатор» берётся по https-проверкам (как в списках https): у адреса без https-проверок он «—».
|
||||
- «Проверок в цикле» при неизвестном ожидаемом числе (`-1`) — только записанное.
|
||||
- Вердикт — оценка системы при агрегации; Egress/Ingress в списке показывают фактические проверки. Пояснение есть в диалоге.
|
||||
|
||||
## Проверки
|
||||
|
||||
- `gofmt -l` пусто (одно выравнивание в тесте поправлено), `go build ./...`, `go vet ./...`, `go test ./...` — все пакеты `ok`; синтаксис `analytics.js` проверен.
|
||||
- Новые тесты: `TestVerdictLists` (инвариант «строк = summary», отмена, порядок, столбцы, «—», неполный набор, причина совпадает с `reasons`); `TestAnalyticsEndpoints` расширен (JSON, CSV `verdict_partial_run<N>.csv`, `404` на неизвестный вид).
|
||||
- Не проверено: открытие диалога в браузере и скорость окна на списке pass (нужна выкладка).
|
||||
|
||||
## Выкладка
|
||||
|
||||
Не выполнена. Нужны пересборка и перезапуск `control-api` и `admin-dashboard` (статика встроена в бинарник); миграций нет.
|
||||
Reference in new issue
Block a user