server-monitor-manager/agents/antigravity/inbox/2026-08-20-console-node-metrics.md
Ochenstarik 7fac6d5d22 chore(agents): задание Antigravity по метрикам узлов в консоли
Windows-клиент показывает CPU, память, диск, задержку и здоровье по
каждому серверу, веб-консоль не показывает ничего из этого. Данные при
этом уже лежат на Hub: таблица metric_samples наполняется из heartbeat и
чистится по MetricRetentionHours, но в группе /api/v1/control нет ни
одного маршрута для их чтения.

Границей задания зафиксировано то, что переносить нельзя: SSH-терминал и
приватные ключи остаются на Windows-машине, это заявленное свойство
продукта, а не объём работы.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 17:38:52 +07:00

7.3 KiB
Raw Blame History

Метрики и короткая история узлов в веб-консоли

  • Кому: antigravity
  • Дата: 2026-08-20
  • От кого: главный агент (claude), по задаче владельца «консоль надо сделать так же, как и Windows-программа»
  • Ветка: antigravity/console-node-metrics
  • Файл отчёта: ../done/2026-08-20-console-node-metrics.md

Зачем

Windows-клиент на странице «Серверы» показывает по каждому серверу CPU, память, диск, задержку, состояние здоровья и статус (Pages/ServersPage.xaml: CpuText, MemoryText, DiskText, LatencyText, HealthText, Status). Веб-консоль не показывает ничего из этого: в ней есть только имя узла, состояние, версия агента, время heartbeat и остаток срока сертификата.

Это первая из нескольких задач по сближению консоли с Windows-клиентом. Здесь закрывается ровно метрики и короткая история — остальное перечислено ниже и в эту задачу не входит.

Установленный факт, от которого отталкиваемся

Данные уже есть на Hub, показывать нечем.

ControlStore содержит таблицу (ControlStore.cs:81):

CREATE TABLE IF NOT EXISTS metric_samples (
    sequence     INTEGER PRIMARY KEY AUTOINCREMENT,
    node_id      TEXT NOT NULL REFERENCES agents(node_id) ON DELETE CASCADE,
    recorded_at  TEXT NOT NULL,
    payload_json TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_metric_samples_node_time
    ON metric_samples(node_id, recorded_at DESC);

Наполняется она из heartbeat агента, чистится по MetricRetentionHours (по умолчанию 168 часов). При этом в группе /api/v1/control нет ни одного маршрута для метрик — я перечитал все control.Map* в Program.cs. То есть оператор физически не может их получить.

Что нужно сделать

  1. Добавить в Control чтение метрик под ролью Operator. Как минимум последний срез по каждому узлу и история по одному узлу за period. Форму запроса, имена полей и ограничение на объём выбираешь сам и обосновываешь в отчёте. Обязательные требования: маршрут в группе control (то есть RequireAuthorization("Operator")), ограничение количества возвращаемых точек, и никакого доступа к чужим данным по роли Agent или Automation.
  2. Показать это в консоли в разделе узлов: текущие CPU, память, диск и задержка рядом с узлом, плюс короткая история — так же, как её показывает Windows-клиент.
  3. payload_json — данные из внешнего источника. Он приходит от агента. Разбирать его в консоли только через уже имеющийся escapeHtml, как это сделано с payload событий; ни одной вставки в innerHTML без экранирования. Отсутствующие или битые поля не должны ронять таблицу узлов.

Границы — что переносить нельзя

SSH-терминал и приватные ключи в веб-консоль не переносятся. Это не вопрос трудоёмкости, а заявленное свойство продукта: README обещает «opens direct SSH terminals without sending a private terminal key to the Hub», а ключ мониторинга и сертификат оператора защищены DPAPI и лежат только на Windows-машине. Страница Sessions остаётся у Windows-клиента.

Также не входит в эту задачу и делается отдельно: страница Settings, группы и теги серверов, alert rules и журнал уведомлений (последние два пункта в docs/roadmap.md числятся невыполненными и для Windows-клиента).

Не трогать: deploy/**, релизные workflow, Desktop, схему существующих таблиц (добавление индексов допустимо и обосновывается).

Как проверить результат

  • новый маршрут закрыт ролью: запрос без токена → 401, под ролью Agent и Automation → 403, под Operator → 200. Три теста, вывод в отчёт;
  • ограничение объёма истории проверено тестом: запрос заведомо большего количества точек возвращает не больше предела;
  • битый или неполный payload_json не роняет ни маршрут, ни отрисовку — тест на каждую сторону;
  • dotnet test целиком зелёный, с выводом;
  • прогоны CI на PR — ссылками.

Связь с другими заданиями

Эта задача пересекается с двумя уже выданными и делать её нужно после них, иначе правки лягут друг на друга в одном файле:

  • 2026-08-19-console-behaviour-tests.md — поведенческие тесты консоли. Новая функциональность обязана прийти с такими тестами сразу, а не проверками строк в HTML;
  • 2026-08-19-console-events-throttle.md — троттлинг обновления дашборда. Метрики увеличат объём каждого обновления, поэтому без троттлинга усиление нагрузки станет заметнее.

Если считаешь, что порядок должен быть другим, — скажи в отчёте и обоснуй, это решение приму.

Контекст и ограничения

Проверено чтением кода и запуском Control локально на пустой базе: узлов ноль, метрик ноль. Как выглядят настоящие payload_json от живого агента, я не видел — на живом Hub не проверял. Прежде чем фиксировать контракт ответа, посмотри фактическую форму payload в коде агента, а не в моём описании.