Дашборды
Дашборды позволяют собирать собственные страницы мониторинга из
готовых виджетов: счётчики трафика моков, статистика тест-кейсов, аномалии фаззинга,
статусы хаос-экспериментов, последняя активность аудита и многое другое. Каждый дашборд
— это свободная 12-колоночная сетка: перетаскивайте, меняйте размер и закрепляйте
виджеты, пока страница не покажет ровно то, что нужно вашей команде.

Об URL в примерах: во всех примерах используется
localhost:5770— адрес Mockarty по умолчанию. Если ваш экземпляр работает на удалённом сервере, заменитеlocalhost:5770на его реальный адрес (например,https://mockarty.company.com). Подробнее — в Полезных функциях и советах.
Где найти
Откройте Дашборды в боковом меню или перейдите на /ui/widget-dashboards.
Клик по дашборду открывает его по адресу /ui/widget-dashboards/<id>. Старый
адрес /ui/dashboards перенаправляет сюда.
Пустой namespace предлагает стартовый дашборд в один клик — готовый обзор
(трафик, протоколы, error-rate тест-ранов, топ моков, последняя активность),
который дальше настраивается под команду.
Дашборды привязаны к namespace: каждый дашборд принадлежит одному namespace, а
переключатель namespace вверху страницы меняет, какие дашборды вы видите.
Пока загружается пространство или дашборд, прежние карточки скрыты. Если список
не загрузился, страница показывает Не удалось загрузить дашборды и кнопку
Повторить. Это ошибка загрузки, а не признак удаления ваших дашбордов.
Если не загрузился каталог в окне Добавить виджет, окно остаётся открытым
и тоже предлагает Повторить.
При первом открытии новый namespace получает редактируемые стартовые панели,
в том числе Развёртывания. На ней видны прогоны развёртываний по текущим
состояниям за последние 30 дней, число прогонов, требующих внимания, доступные
раннеры и состояние доставки вебхуков. В счётчик требующих внимания входят и
давно не разрешённые прогоны и откаты, которые ещё не удалось подтвердить
проверкой. Источники данных по развёртываниям доступны
только на панелях своего namespace; общая панель не объединяет эти данные
между пространствами.
В стартовый набор входит и панель Deploys — операторский взгляд на журнал
развёртываний, который ведёт пайплайн автономного кодера: исходы за период
(успех / провал / откат), длительность p50 и p95 и последние развёртывания
с исходом каждого прогона. Как и «Развёртывания», эти источники работают
только внутри своего namespace.
Журнал развёртываний фиксирует деплои автономного кодера. Если этого модуля
нет в лицензии, виджеты Deploys скрываются из пикера, а стартовая панель
создаётся без них.
Кто что может
| Действие | Кто |
|---|---|
| Просмотр дашбордов и данных виджетов | Любой участник namespace |
| Создание / редактирование / удаление дашбордов и виджетов | Owner namespace, либо глобальный admin / support |
| Создание / редактирование / удаление общих (глобальных) дашбордов | Только системный admin / support |
Пользователь с ролью viewer в namespace может открывать и читать все дашборды в нём,
но любая попытка что-то изменить отклоняется с кодом 403.
Создание дашборда
- Откройте
/ui/widget-dashboardsи нажмите New dashboard. - Введите имя (обязательно, до 200 символов, уникально в пределах namespace) и при
необходимости описание. - Пустой дашборд откроется в режиме редактирования — добавьте первый виджет.
Существующий дашборд можно дублировать: копия получает новое имя, которое вы
указываете, и переносит все виджеты вместе с настройками и раскладкой.
Общие (глобальные) дашборды
Обычный дашборд показывает данные одного namespace. Общий дашборд
агрегирует данные по всем namespace инстанса — картина по всей компании:
суммарный трафик моков, тест-кейсы по приоритетам, аномалии фаззинга по
серьёзности, весь парк runner’ов.
Как это работает:
- Общий дашборд живёт в namespace по умолчанию (
sandbox) — его может открыть
каждый пользователь, поэтому дашборд виден всем. На вкладке такого дашборда —
иконка глобуса, а в тулбаре — бейдж Все пространства. - Создавать и изменять общий дашборд может только системный admin или
support. Для остальных он доступен только на чтение: элементы
редактирования скрыты, а прямые API-записи отвечают403. - Чтобы создать общий дашборд, откройте New dashboard в namespace по
умолчанию и отметьте Общий дашборд (по всем пространствам) — чекбокс
виден только админам и саппорту. Через API передайте"scope": "global"в
теле запроса создания; вне namespace по умолчанию запрос отклоняется с400. - Поскольку общий дашборд видят все, на нём доступны только безопасные для
приватности источники данных — агрегаты без имён ресурсов, идентификаторов,
e-mail, названий пространств и произвольных меток. Пикер виджетов скрывает
несовместимые источники, а API отклоняет их с400. В каталоге у каждого
источника есть флагglobalSafe. Уже существующий общий виджет с таким
источником показывает ошибку недоступности данных, пока вы не замените его.
Формула на общем дашборде может использовать только операнды, которые тоже
разрешены для общих дашбордов; старая формула с несовместимым операндом
показывает ошибку недоступности данных.
Существующие дашборды не затрагиваются: всё созданное раньше остаётся в рамках
своего namespace.
# Создать общий дашборд (токен admin/support, namespace по умолчанию)
curl -X POST -H "X-API-Key: $TOKEN" -H "Content-Type: application/json" \
-d '{"name": "Обзор по компании", "scope": "global"}' \
"http://localhost:5770/api/v1/widget-dashboards?namespace=sandbox"
Добавление виджетов
Нажмите Add widget и выберите источник данных из каталога. Каждый виджет сочетает:

- источник данных — что показывать (фиксируется при создании виджета);
- тип виджета — как отрисовать;
- необязательные параметры — например, окно времени или количество записей.
Типы виджетов
| Тип | Отображается как |
|---|---|
stat |
Крупное число |
chart_line |
Линейный график (временной ряд) |
chart_area |
График с заливкой (временной ряд) |
chart_bar |
Столбчатая диаграмма (сравнение категорий) |
chart_pie |
Donut / круговая диаграмма распределения |
top_list |
Ранжированный топ-N список |
table |
Таблица |
activity |
Лента активности (последние события) |
status |
Индикатор состояния с коротким текстом |
breakdown |
Число с разбивкой по под-категориям |
text |
Ваша заметка в Markdown (с Mermaid-диаграммами) |
Источники данных по категориям
| Категория | Источник | Показывает | Параметры |
|---|---|---|---|
| Mocks | mock.total_count |
Общее число моков в namespace | — |
| Mocks | mock.active_count |
Число активных моков на текущий момент | — |
| Mocks | mock.undefined_count |
Запросы, не совпавшие ни с одним моком | period_days (0 = за всё время, 1–365) |
| Mocks | mock.requests_total |
Всего запросов к мокам за окно | period_days |
| Mocks | mock.top |
Самые нагруженные моки | period_days, top_n |
| Mocks | mock.unused |
Активные моки без вызовов N дней (значение = дней простоя) | idle_days (1–365), top_n (1–50) |
| Mocks | mock.distinct_called |
Сколько разных моков получили хотя бы один запрос за окно | period_days (1–365) |
| Mocks | mock.by_tag |
Активные моки по тегам (включая бакет «без тега») | top_n (1–50) |
| Mocks | mock.requests_trend |
Запросы во времени | period_days (1–90), bucket (hour / day) |
| Mocks | mock.requests_by_protocol |
Трафик в разрезе протоколов | period_days |
| Audit | audit.activity |
Последние события аудита (кто что сделал) | limit (1–100) |
| Audit | audit.action_breakdown |
Активность в разрезе типов действий | period_days (1–365), top_n (1–50) |
| Runners | runner.status |
Парк раннеров по статусам (online / offline) | — |
| Test Cases | tcm.summary |
Тест-кейсы по приоритетам | — |
| Test Cases | tcm.cases_by_status |
Тест-кейсы по статусу воркфлоу | folder_id, priority, review_status, severity (все опц.) |
| Test Cases | tcm.cases_by_review_status |
Тест-кейсы по статусу ревью (draft / in review / approved …) | folder_id, priority, severity (опц.) |
| Test Cases | tcm.cases_by_priority |
Тест-кейсы по приоритету | folder_id, review_status, severity (опц.) |
| Test Cases | tcm.cases_by_severity |
Тест-кейсы по серьёзности | folder_id, priority, review_status (опц.) |
| Test Cases | tcm.cases_in_review |
Сколько кейсов сейчас в ревью | folder_id, priority, severity (опц.) |
| Test Cases | tcm.review_age_days |
Средний / максимальный возраст кейсов в ревью (прокси, см. ниже) | folder_id, priority, severity (опц.) |
| Test Cases | tcm.cases_by_tag |
Тест-кейсы по тегам (кейс попадает в бакет каждого своего тега; без тегов — «Untagged») | top_n (1–50), folder_id, priority, review_status, severity |
| Test Cases | tcm.cases_by_custom_field |
Тест-кейсы по значению одного кастом-поля — график «группировка по лейблу» в стиле Allure. Имя поля сравнивается без учёта регистра; если в одном кейсе есть одинаковые имена с разным регистром, учитывается последнее значение. | field (обязателен), top_n (1–50), folder_id, priority, review_status, severity |
| Test Cases | tcm.cases_by_author |
Топ авторов тест-кейсов (по команде) | top_n (1–50), folder_id, priority, review_status, severity |
| Test Cases | tcm.runs_by_executor |
Топ исполнителей прогонов кейсов за период (по команде) | top_n (1–50), period_days (1–365) |
| Test Plans | plans.summary |
Планы, расписания и недавние запуски | — |
| Test Plans | testplan.completions_by_user |
Топ тех, кто прошёл тест-планы за период (по команде) | top_n (1–50), period_days (1–365) |
| Access | users.cases_authored |
Активность по пользователям: создано кейсов за период (по команде) | top_n (1–50), period_days (1–365) |
| API Tester | api_tester.summary |
Счётчики коллекций, тестов и отчётов | — |
| API Tester | api_tester.runs_trend |
Прогоны тест-отчётов во времени (для графиков error-rate и формул) | period_days (1–90), bucket (hour / day), status (all/passed/failed) |
| Fuzzing | fuzz.summary |
Аномалии фаззинга по серьёзности | — |
| Chaos | chaos.summary |
Хаос-эксперименты по статусам | — |
| Chaos | chaos.resilience_avg |
Средняя оценка устойчивости (0–100) по хаос-прогонам за период | period_days |
| AI Agents | agent.tokens_total |
Потреблено LLM-токенов за период | period_days (1–365) |
| AI Agents | agent.tokens_by_namespace |
Потребление токенов по пространствам имён | period_days, top_n (1–50) |
| AI Agents | agent.tokens_trend |
LLM-токены во времени | period_days (1–90), bucket (hour / day) |
| AI Agents | agent.users_top |
Топ пользователей агентов по токенам (по команде) | period_days, top_n |
| AI Agents | agent.subagents_top |
Топ суб-агентов по выполненным задачам | period_days, top_n |
| Автономный кодер | coder.mission_cost |
LLM-токены по миссиям кодера (крупнейшие потребители) | period_days (1–365), limit (1–50) |
| Автономный кодер | coder.hours_saved |
Сэкономленные человеко-часы миссий, завершённых за период (оценка задачи − время до завершения) | period_days (1–365), hours_per_point (1–80) |
| Миссии | missions.by_status |
Автономные миссии по состояниям | period_days (1–365), product_id (необязательно) |
| Миссии | missions.needs_attention |
Миссии, ожидающие человека | product_id (необязательно) |
| Миссии | missions.throughput |
Число завершённых миссий по дню завершения, включая неуспешные и отменённые | period_days (1–180), product_id (необязательно) |
| Миссии | missions.success_rate |
Доля успешных среди завершённых; отменённые не входят в расчёт | period_days (1–365), product_id (необязательно) |
| Миссии | missions.spend_by_product |
Расход токенов миссий по продуктам | period_days (1–365), limit (1–50) |
| Миссии | missions.budget_utilisation |
Использованная доля заданного бюджета токенов миссий | product_id (необязательно) |
| AI Agents | agent.tasks_active |
Задачи агентов, выполняющиеся сейчас | — |
| AI Agents | agent.tasks_by_status |
Задачи агентов по статусам | period_days |
| Mocks | mock.users_top |
Топ авторов моков (по команде) | period_days, top_n |
| Security | security.findings_total |
Аномалии безопасности за период | period_days (1–365) |
| Security | security.findings_by_severity |
Аномалии по критичности | period_days |
| Security | security.findings_trend |
Аномалии во времени | period_days (1–90), bucket, severity (all / critical / high / medium / low / info) |
| Performance | perf.campaigns_active |
Нагрузочные кампании, идущие сейчас | — |
| Performance | perf.campaigns_by_status |
Нагрузочные кампании по статусам | period_days |
| Performance | perf.requests_trend |
Всего перф-запросов выполнено во времени | period_days, bucket |
| Performance | perf.failed_requests_trend |
Неуспешные перф-запросы во времени (в паре с запросами — формула для error-rate) | period_days, bucket |
| Performance | perf.apdex_avg |
Средний APDEX-индекс по прогонам за период | period_days |
| Performance | perf.p95_latency_trend |
Средняя p95-задержка (мс) по бакетам во времени | period_days, bucket |
| Test Runs | test_runs.by_status |
Запуски тестов по статусам | period_days |
| Test Runs | test_runs.trend |
Запуски тестов во времени | period_days (1–90), bucket, status (all / completed / failed / running / pending / interrupted) |
| Webhooks | webhook.deliveries_by_status |
Доставки вебхуков по статусам | period_days |
| Webhooks | webhook.deliveries_trend |
Доставки вебхуков во времени | period_days (1–90), bucket, status (all / delivered / failed / dlq / …) |
| Recorder | recorder.sessions_total |
Сессии рекордера за период | period_days |
| Deploys | deploy.outcomes |
Исходы развёртываний за период: успех / провал / откат / блокировка / отмена / в работе | period_days (1–90), environment (опционально) |
| Deploys | deploy.durations |
Персентили длительности развёртываний (секунды); на карточке — выбранный персентиль | period_days (1–90), percentile (p50 / p95), environment (опционально) |
| Deploys | deploy.runs |
Последние развёртывания с состоянием и длительностью каждого прогона | limit (1–50), period_days (1–90), environment (опционально) |
| Contracts | contract.summary |
Контрактные прогоны по типу отчёта | period_days |
| Access | rbac.namespace_users |
Участники пространства имён по ролям | — |
| Задачи | issuetracker.issues_by_status |
Задачи по статусу воркфлоу | — |
| Задачи | issuetracker.issues_by_priority |
Задачи по приоритету | — |
| Задачи | issuetracker.issues_by_assignee |
Задачи по исполнителю (внутри команды) | — |
| Задачи | issuetracker.open_count |
Открытые (не завершённые) задачи | — |
| Задачи | issuetracker.overdue_count |
Задачи с просроченным дедлайном | — |
| Задачи | issuetracker.created_trend |
Создание задач во времени | period_days (1–90), bucket (hour / day) |
| Мессенджер | chat.messages_by_author_kind |
Сообщения по типу автора (люди / агенты / система) | — |
| Мессенджер | chat.messages_by_thread_kind |
Сообщения по типу треда (обсуждения / личные / каналы) | — |
| Мессенджер | chat.threads_total |
Треды обсуждений (открытые, не в архиве) | — |
| Вики | wiki.pages_total |
Живые страницы вики | — |
| Вики | wiki.pages_created_trend |
Создание страниц вики во времени | period_days (1–90), bucket (hour / day) |
| Вики | wiki.edits_trend |
Правки вики (сохранения) во времени | period_days (1–90), bucket (hour / day) |
| Система | system.resources |
Загрузка CPU / памяти / диска хоста | — |
| Система | system.runtime |
Рантайм серверного процесса (горутины, куча, GC, аптайм) | — |
| Система | system.db_pool |
Соединения, ожидания и время ожидания пула БД на узле, который отдал панель (не сумма по кластеру) | — |
| Formulas | formula.custom |
Ваша собственная метрика, вычисленная из других источников | expression, operands |
| Formulas | formula.timeseries |
Ваш собственный график: формула, вычисляемая по каждому временному бакету над trend-источниками (например, доля ошибок во времени) | expression, operands |
| Прочее | static.text |
Ваша заметка в Markdown (текстовый виджет) | — |
| Прочее | static.html |
Ваш собственный HTML (со скриптами) в песочнице-фрейме | — |
| Прочее | static.embed |
Живая внешняя страница внутри карточки (например, борд Grafana) | — |
Почасовые и суточные интервалы для прогонов тестов, находок безопасности,
расхода токенов ИИ, отчётов API Tester, доставок вебхуков, запросов и задержки
нагрузочных тестов и завершённых миссий считаются по UTC. Поэтому график
показывает одинаковые интервалы на разных узлах даже при разных часовых
поясах сеансов базы данных.
Параметры проверяются по схеме источника при сохранении — неизвестный параметр или
значение вне диапазона отклоняется с понятным сообщением об ошибке, виджет не
создаётся.
Точный, всегда актуальный каталог (включая схему параметров каждого источника)
доступен через API: GET /api/v1/widget-dashboards/catalog.
Командная аналитика
Помимо «как используется инструмент», дашборды отвечают на управленческие вопросы
о людях и процессах: кто написал больше всего тест-кейсов, кто прошёл какие
тест-планы, сколько кейсов лежит в ревью и как долго.
- Источники процесса (
tcm.cases_by_review_status,tcm.cases_by_priority,
tcm.cases_by_severity,tcm.cases_in_review,tcm.review_age_days)
показывают форму бэклога тест-кейсов через фиксированные метки и счётчики.
Их можно вынести на общий глобальный дашборд. Названия статусов воркфлоу,
теги и значения кастом-полей могут содержать данные команды, поэтому их
разрезы доступны только в одном пространстве. - Источники по людям (
tcm.cases_by_author,tcm.runs_by_executor,
testplan.completions_by_user,users.cases_authored) привязывают работу к
конкретному участнику. Поскольку они раскрывают личность человека, они
доступны только в рамках команды: вы видите участников своей команды и никогда —
людей из другой команды; на глобальный дашборд их добавить нельзя.
Все источники процесса и людей принимают опциональные фильтры — можно сузить до одной
папки, приоритета, статуса ревью или серьёзности: выберите значение при добавлении
виджета, и он пересчитается только по подходящим кейсам. Ещё два фильтра по
косвенным признакам — как в Allure: tag (только кейсы с этим тегом) и cf
(только кейсы с кастом-полем, в формате key=value, например component=cart).
Их можно комбинировать — например, «кейсы по приоритету, tag=regression,
cf=team=payments» — чтобы нарезать любую разбивку под реальный процесс команды.
Возраст ревью — это прокси. tcm.review_age_days оценивает, сколько кейсы лежат в
ревью, измеряя время с момента последнего редактирования (сейчас − последнее
изменение). Активно редактируемый кейс показывает меньший возраст; залежавшийся —
реальный возраст бэклога. Виджет честно помечает это как прокси — Mockarty пока не
хранит отдельную метку «переведён в ревью».
Формулы — свои метрики
Источник «Своя формула» (категория Формулы) позволяет построить метрику,
которой нет в каталоге «из коробки», — комбинируя другие источники обычной
арифметикой. Без языка запросов: вы задаёте до 5 операндов (буквы A–E),
привязываете каждый к источнику данных и пишете выражение вида A / B * 100.
В пикере «Добавить виджет» выберите «Своя формула» — вместо обычной формы
параметров появится конструктор формулы:

- Операнды — по строке на букву. Каждая строка выбирает источник данных (любой
источник, отдающий число или распределение; формула не может ссылаться на другую
формулу). Для источников-распределений дополнительно выбирается метрика:
«Сумма (total)» или «Элемент по имени…» — один именованный срез, имя
сравнивается без учёта регистра (например,failed). Если у источника есть
параметры (например,period_days), компактная форма параметров появляется прямо
в строке. - Выражение — арифметика над буквами операндов:
+ - * /, скобки, числа
(десятичные допустимы), унарный минус. Проверяется на лету при вводе; та же
проверка выполняется на сервере при сохранении. - Отображение — знаки после запятой (Авто / 0–3) и произвольный суффикс
(например,%) для отображаемого числа.
Результат — одно число, поэтому подходят типы виджетов Stat и Status,
включая пороги (например, подсветить карточку красным, когда доля ошибок превысит 5).
Пример — stat «процент упавших запусков тестов»:
- Операнд
A: источник Запуски тестов по статусам, метрика «Элемент по
имени…» →failed. - Операнд
B: источник Запуски тестов по статусам, метрика «Сумма (total)». - Выражение:
A / B * 100, суффикс%, один знак после запятой.
Деление на ноль и отсутствующее имя элемента отображаются как ошибка только внутри
этого виджета — остальной дашборд продолжает работать.
Добавить виджет-формулу через API
curl -X POST -H "X-API-Key: $TOKEN" -H "Content-Type: application/json" \
-d '{
"title": "Failed runs %",
"widgetType": "stat",
"dataSourceId": "formula.custom",
"paramsJson": {
"expression": "A / B * 100",
"operands": [
{"ref": "A", "sourceId": "test_runs.by_status", "select": "item:failed"},
{"ref": "B", "sourceId": "test_runs.by_status", "select": "total"}
]
},
"vizOptionsJson": {"decimals": 1, "suffix": "%"},
"gridW": 3, "gridH": 3
}' \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/widgets?namespace=default"
select — это "total" (по умолчанию) или "item:<имя>" для
источников-распределений; числовым источникам select не нужен. Некорректное
выражение, неизвестный источник операнда или буква в выражении без строки операнда
отклоняются с точным сообщением об ошибке.
Свои графики — формула во времени
Источник «Свой график (формула во времени)» (formula.timeseries) — тот же
конструктор, но каждый операнд привязывается к trend-источнику («…во времени»),
а выражение вычисляется для каждого временного бакета — результатом будет ряд,
который рисуют типы виджетов Line и Area.
Конструктор начинается с готовых рецептов — шаблонов в один клик для частых
формул (% ошибок тест-ранов, успешность вебхуков, доля critical-аномалий). Выберите
рецепт и подстройте — или соберите с нуля:
- Задайте ось времени — одно окно (дней) и бакет (
hour/day) на всю
формулу. Все операнды используют эту ось, поэтому ряды всегда выровнены. - Операнд
A: источник Запуски тестов во времени, параметрstatus→failed. - Операнд
B: источник Запуски тестов во времени,status→all. - Выражение:
A / B * 100. Тип виджета: Line.
Бакет, в котором выражение вычислить нельзя (например, деление на ноль в день без
запусков), просто пропускается — на графике будет разрыв, а не фальшивый ноль.
Опции «Отображение» работают и здесь: задайте число знаков и суффикс (например,
%) — ось Y и тултип графика покажут 60.7 % вместо сырого числа. Серия в тултипе
называется по заголовку виджета.
Порог-зоны. Линейные, area- и bar-графики принимают те же пороги, что и
числовые виджеты — и рисуют их цветными зонами: с каждого порога начинается
полупрозрачная полоса с пунктирной границей, так что «выше 5% — плохо» видно с
одного взгляда. Ось Y растягивается так, чтобы самая высокая зона оставалась
видимой, даже если данные до неё ещё не дошли. Пороги задаются в настройках
виджета или через API (vizOptionsJson.thresholds, например
[{"value": 5, "color": "yellow"}, {"value": 10, "color": "red"}]).
Текст и заметки — Markdown-виджеты
Источник «Текст / заметка» (категория Прочее) добавляет на дашборд карточку с
произвольным текстом: фрагмент ранбука, контакты дежурных, легенда к соседним
метрикам, ссылки на документацию. Это единственный виджет, который не запрашивает
данных — содержимое вы пишете сами.
Выберите «Текст / заметка» в окне добавления виджета — на шаге настройки вместо
параметров появится редактор «Содержимое (Markdown)». Поддерживается стандартный
Markdown:
- заголовки, абзацы, жирный / курсив;
- маркированные и нумерованные списки, таблицы, цитаты;
- встроенный
коди блоки кода; - ссылки и изображения.
Сырой HTML вычищается при отображении — скрипты, фреймы и обработчики событий никогда
не рендерятся, поэтому текстовый виджет безопасно размещать и на общем (глобальном)
дашборде.
Свой HTML и живые встраивания
Рядом с «Текст / заметка» (категория Прочее) живут ещё два авторских виджета:
Свой HTML (static.html) рендерит написанный вами HTML — включая скрипты —
внутри песочницы-iframe на карточке. Скрипты могут ходить в API самого приложения
с вашей сессией (fetch('/api/v1/…', {credentials: 'include'})), тянуть данные
откуда угодно и рисовать результат как угодно. Дашборд становится полностью
программируемым: агент (или вы) генерирует нужную визуализацию одним
HTML-сниппетом и кладёт её на борд. Карточка растягивается как любой виджет,
размер сохраняется. Лимит контента: 16 КБ. Поскольку HTML выполняется с сессией зрителя,
авторинг ограничен: создавать и редактировать Custom HTML-виджет может только
владелец пространства (или системный admin / support) — это проверяет сервер.
Модель повторяет admin-only HTML-панели Grafana.
Встраивание / iframe (static.embed) показывает живую внешнюю страницу внутри
карточки: борд Grafana, статус-страницу, любой дашборд, доступный из браузера
зрителя. Укажите URL — целевой сайт должен разрешать встраивание (не отдавать
X-Frame-Options: DENY / ограничивающий frame-ancestors). Авторизация —
браузерная: войдите на встраиваемый сайт в этом же браузере, и его cookie
действуют внутри фрейма (для cross-site конфигураций целевой сайт должен выдавать
сессионную cookie с SameSite=None; Secure). Подсказка для Grafana: добавьте
?kiosk, чтобы скрыть её интерфейс, и включите allow_embedding = true в
grafana.ini.
Диаграммы Mermaid
Блок кода с языком mermaid рендерится как диаграмма прямо на карточке — блок-схемы,
диаграммы последовательностей, машины состояний:
# Процесс релиза
```mermaid
graph LR
Build --> Test --> Deploy
```
Диаграммы автоматически следуют светлой/тёмной теме. Если в диаграмме синтаксическая
ошибка, на её месте появится аккуратная заметка об ошибке — остальная карточка
продолжит отображаться.
Чтобы изменить текст позже, откройте настройки виджета (иконка шестерёнки) — появится
тот же редактор с текущим содержимым.
Добавить текстовый виджет через API
Содержимое передаётся в vizOptionsJson.markdown (до 16 КБ); paramsJson для этого
источника остаётся пустым:
curl -X POST -H "X-API-Key: $TOKEN" -H "Content-Type: application/json" \
-d '{
"title": "Ранбук команды",
"widgetType": "text",
"dataSourceId": "static.text",
"vizOptionsJson": {"markdown": "# Дежурство\n\n- Сначала смотрим виджет error-rate\n\n```mermaid\ngraph LR\n Alert --> Triage --> Fix\n```"},
"gridW": 4, "gridH": 4
}' \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/widgets?namespace=default"
Раскладка: перетаскивание, размер, закрепление
Сетка состоит из 12 колонок. В режиме редактирования:
- Перетаскивайте виджет за заголовок; соседние виджеты автоматически
раздвигаются. - Меняйте размер за правый нижний угол. У каждого виджета есть минимальный размер.
- Закрепляйте виджет, чтобы другие виджеты не сдвигали его при перетаскивании.
Раскладка сохраняется автоматически после сессии перетаскивания/изменения размера и
переживает обновление страницы для всех участников namespace.
Живые обновления
Открытый дашборд обновляется сам — нажимать Обновить не нужно. Маленькая
точка рядом с кнопкой Обновить показывает состояние соединения:
- Зелёная, пульсирует — живые обновления активны. Дашборд проверяет
новые значения виджетов и перерисовывает их при изменении. - Серая — соединение прервалось, страница переподключается; восстановление
происходит само за несколько секунд.
После изменения тест-кейсов связанные показатели дашборда обновляются и в
том случае, если кейс изменили через другой admin-узел Mockarty. Небольшая
задержка при доставке изменения до дашборда нормальна.
Пока вы редактируете раскладку, живые перерисовки придерживаются, чтобы сетка
не двигалась под курсором; свежие данные появятся сразу после сохранения или
отмены редактирования.
Селект интервала автообновления в тулбаре остаётся как резервный режим
опроса (например, если корпоративный прокси блокирует потоковые соединения).
Когда живые обновления работают, правильный выбор — оставить его Выкл.
Экспорт и печать
Откройте меню ⋮ дашборда (справа в тулбаре), чтобы поделиться дашбордом за
пределами Mockarty:
- Экспорт HTML — скачивает один полностью автономный
.html-файл: дашборд
ровно таким, каким вы его видите (сетка, карточки, графики как статичные
изображения), без внешних ресурсов — открывается где угодно, в том числе в
закрытом контуре и как вложение в письме. Файл несёт машиночитаемые атрибуты
(data-widget-id,data-widget-type,data-source-id,data-params,
data-gridна каждой карточке;data-valueна числовых значениях), так что
скрипты и BI-инструменты разбирают снапшот без скрейпинга картинки. - Экспорт JSON — скачивает конфигурацию дашборда плюс свежевычисленные
данные виджетов с сервера:{dashboard, widgets, data}. Каждый виджет несёт
type,dataSourceId,params, позициюgridиthresholds;data
содержит те же послотовые данные, что и живой рендер. - Экспорт CSV — скачивает плоскую таблицу метрик для Excel / Google Sheets /
BI-инструментов:widget_id, widget_title, widget_type, data_source_id, metric, value, по строке на значение (круговая диаграмма даёт строку на
сегмент, временной ряд — строку на точку). Файл начинается с UTF-8 BOM, чтобы
Excel корректно определил кодировку. - Экспорт конфигурации — скачивает только конфигурацию дашборда (без
данных, без внутренних идентификаторов, без пространства имён) как переносимый
JSON-файл. Используйте его, чтобы передать дашборд другой команде — см.
следующий раздел. - Импортировать дашборд — создаёт новый дашборд из такого файла
конфигурации. Доступен и на пустом состоянии, когда в пространстве имён ещё нет
дашбордов. - Печать / PDF — открывает диалог печати браузера. Выберите Сохранить как
PDF. Интерфейс приложения (сайдбар, вкладки, тулбар) скрывается
автоматически; сетка виджетов печатается в светлой палитре, каждая карточка
остаётся на одной странице.
Экспорт JSON и CSV вычисляется на сервере, поэтому отражает актуальные данные, а
не кеш браузера. Каждый экспорт фиксируется в журнале аудита.
Перенос дашборда между командами
Если одна команда собрала удачный дашборд, экспортируйте его конфигурацию и
передайте файл — принимающая команда импортирует его в своё пространство имён, и виджеты
посчитаются уже по их данным:
- На исходном дашборде откройте меню ⋮ → Экспорт конфигурации. Вы
получите файл<имя>-config.json, содержащий только имя дашборда, описание и
конфигурацию виджетов (тип, источник данных, параметры, пороги, раскладку
сетки). Ничего специфичного для пространства имён в файл не попадает. - Принимающая команда открывает Пользовательские дашборды в своём
пространстве имён и выбирает меню ⋮ → Импортировать дашборд (или «Импортировать
дашборд» на пустом состоянии), затем указывает файл. Новый дашборд появится и
станет активным.
Правила импорта:
- Для импорта нужны права на запись (владелец пространства имён, администратор или
поддержка). - Файл проверяется строго: типы виджетов и источники данных должны существовать
на принимающем сервере, параметры виджетов перепроверяются по схеме каждого
источника. Неизвестные источники перечисляются в сообщении об ошибке. - Если дашборд с таким именем уже существует, импорт получит имя
<имя> (imported)(затем<имя> (imported 2)и так далее). - Ограничения в 30 виджетов и 200 символов действуют и для импорта.
Ограничения
- 30 виджетов на дашборд — добавление 31-го отклоняется, в том числе когда несколько пользователей добавляют виджеты одновременно.
- Если старый дашборд уже содержит более 30 виджетов, запросы дашборда, данных и экспорта возвращают HTTP 409. Попросите администратора исправить сохранённую конфигурацию; сервер не скрывает часть виджетов.
- Имена дашбордов и заголовки виджетов: до 200 символов.
- Данные виджетов кратковременно кешируются на сервере (от нескольких секунд до
нескольких минут в зависимости от источника), поэтому даже загруженный дашборд с
множеством зрителей остаётся дешёвым. - Если один источник данных упал, ошибку показывает только его виджет — остальной
дашборд отрисовывается нормально.
Примеры API
Все эндпоинты живут под /api/v1/widget-dashboards. Namespace передаётся в query-параметре
?namespace= (по умолчанию default). Аутентификация — API-токен в заголовке
X-API-Key.
Список дашбордов
curl -H "X-API-Key: $TOKEN" \
"http://localhost:5770/api/v1/widget-dashboards?namespace=default"
Создать дашборд
curl -X POST -H "X-API-Key: $TOKEN" -H "Content-Type: application/json" \
-d '{"name": "Обзор QA-команды", "description": "Моки + здоровье тестов"}' \
"http://localhost:5770/api/v1/widget-dashboards?namespace=default"
Посмотреть каталог источников данных
curl -H "X-API-Key: $TOKEN" \
"http://localhost:5770/api/v1/widget-dashboards/catalog"
Добавить виджет
curl -X POST -H "X-API-Key: $TOKEN" -H "Content-Type: application/json" \
-d '{
"title": "Запросы во времени",
"widgetType": "chart_line",
"dataSourceId": "mock.requests_trend",
"paramsJson": {"period_days": 7, "bucket": "day"},
"gridX": 0, "gridY": 0, "gridW": 6, "gridH": 4
}' \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/widgets?namespace=default"
Получить дашборд с его виджетами
curl -H "X-API-Key: $TOKEN" \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>?namespace=default"
Получить «живые» данные виджетов
curl -H "X-API-Key: $TOKEN" \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/data?namespace=default"
Каждый элемент в ответе несёт либо data (вычисленное значение), либо error
(почему именно этот виджет не смог посчитаться) — упавший источник никогда не ломает
весь ответ.
Когда узел занят вычислением других дашбордов, /data возвращает HTTP 429 с
Retry-After: 1. Повторяйте запрос после этого интервала, без множества
параллельных попыток. В кластере лимит действует отдельно на каждом узле.
Поток живых данных виджетов (SSE)
curl -N -H "X-API-Key: $TOKEN" \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/stream?namespace=default"
Сервер держит соединение открытым и присылает фрейм event: widgets с тем же
форматом items, что и эндпоинт /data, — но только когда значения
действительно изменились. Между изменениями соединение поддерживают
комментарии-heartbeat’ы. Веб-интерфейс использует этот поток для живых
обновлений; его можно потреблять и из скриптов или внешних дашбордов.
Когда вычислительные ресурсы заняты, поток сохраняет последний фрейм и
повторяет попытку при следующем обновлении; неизменившийся фрейм не отправляется.
Экспорт дашборда (JSON / CSV)
# Конфигурация + свежевычисленные данные как JSON
curl -OJ -H "X-API-Key: $TOKEN" \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/export?namespace=default&format=json"
# Плоская таблица метрик для Excel / BI-инструментов
curl -OJ -H "X-API-Key: $TOKEN" \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/export?namespace=default&format=csv"
-OJ сохраняет файл под именем, которое предлагает сервер
(<имя-дашборда>-<дата>.json / .csv).
Экспорт JSON и CSV может вернуть HTTP 429 с Retry-After: 1, когда вычисление
данных занято. Экспорт одной конфигурации не вычисляет данные виджетов и
остаётся доступен.
Перенести дашборд другой команде (экспорт конфигурации + импорт)
# 1. Экспортировать переносимую конфигурацию (без данных, ids и пространства имён)
curl -OJ -H "X-API-Key: $TOKEN" \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/export?namespace=team-a&format=config"
# 2. Импортировать её в другое пространство имён (файл из шага 1 как тело запроса)
curl -X POST -H "X-API-Key: $TOKEN" -H "Content-Type: application/json" \
--data @overview-config.json \
"http://localhost:5770/api/v1/widget-dashboards/import?namespace=team-b"
Импорт отвечает 201 с созданным дашбордом. 400 перечисляет ровно то, что
принимающий сервер не принял (например, неизвестные источники данных).
Изменить имя / описание дашборда
curl -X PATCH -H "X-API-Key: $TOKEN" -H "Content-Type: application/json" \
-d '{"name": "Обзор QA-команды v2"}' \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>?namespace=default"
Изменить виджет
curl -X PATCH -H "X-API-Key: $TOKEN" -H "Content-Type: application/json" \
-d '{"title": "Трафик моков (14д)", "paramsJson": {"period_days": 14}}' \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/widgets/<widgetId>?namespace=default"
Массово сохранить раскладку
curl -X PUT -H "X-API-Key: $TOKEN" -H "Content-Type: application/json" \
-d '{"items": [{"id": "<widgetId>", "gridX": 6, "gridY": 0, "gridW": 6, "gridH": 4}]}' \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/layout?namespace=default"
Дублировать дашборд
curl -X POST -H "X-API-Key: $TOKEN" -H "Content-Type: application/json" \
-d '{"name": "Обзор QA-команды (копия)"}' \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/duplicate?namespace=default"
Удалить виджет / дашборд
curl -X DELETE -H "X-API-Key: $TOKEN" \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>/widgets/<widgetId>?namespace=default"
curl -X DELETE -H "X-API-Key: $TOKEN" \
"http://localhost:5770/api/v1/widget-dashboards/<dashboardId>?namespace=default"
После удаления дашборда чтение по его id отвечает 404.