# ADR 0002. Что показывает мониторинг стенда Дата: 31 июля 2026 года. Статус: принято. ## Решение Мониторинг стенда — несколько дашбордов Grafana, по одному на вопрос. Дашборд, отвечающий на три вопроса сразу, не отвечает ни на один; отдельных файлов не жалко. **«Данные»** — главный дашборд, вопросы дата-инженера: - свежесть: сколько прошло с момента, когда доехало последнее событие; - поток: строк в час по источникам и как это выглядит против вчерашнего; - брак: сколько записей ушло в таблицы `*_errors` и какая это доля; - сходимость: сколько произвели в Kafka против того, сколько приземлилось в ClickHouse; - отставание чтения из Kafka; - дневной слепок заказов: доехал ли и вовремя ли. Источник большинства этих панелей — не Prometheus, а сам ClickHouse: он подключается в Grafana источником данных, панели пишутся на SQL. Метрики дата-инженера живут в его собственных таблицах, а не в счётчиках сервисов. **«Кластер»** — состояние машины: процессор и память обеих нод, обращения к дискам, части MergeTree и слияния, keeper, очередь распределённых DDL. Дашборд кажется чужим для дата-инженера, но чужой он только на вид: «слишком много частей» — это ошибка того, кто вставляет мелкими пачками слишком часто, а видна она именно здесь. То же с памятью: тяжёлый `GROUP BY` без ограничения — запрос человека, симптом — на графике памяти. Смотреть этот дашборд осмысленно под нагрузкой: видно, как процессор и обращения к дискам лезут вверх на вставке и медленно оседают, когда домержились части. Одно число «жив или нет» этому не учит, форма кривой — учит. **«Запросы»** — `system.query_log` таблицей: что выполнялось, сколько заняло, сколько памяти и строк прочитало. Здесь человек сам отвечает себе на вопрос «почему мой дашборд в Superset тормозит». Системные таблицы у каждой ноды свои, поэтому панели по ним пишутся через `clusterAllReplicas` — иначе видно половину правды. Это отдельный маленький урок, и он нужен. Серверный журнал (`system.text_log`) подключается на этапе 9 вместе с runbook «keeper упал / DDL повис в очереди»: там он и окупается. Довод за него один — общая ось времени: в одной панели оба узла, над ней всплеск процессора, под ней очередь DDL. `docker logs` даёт две отдельные ленты и сопоставление руками. Издержки: журнал выключен по умолчанию, включается настройкой, таблице нужен TTL. Если окажется дороже, чем даёт, — уходит первым. Prometheus остаётся, но сжимается до тонкого пола: живы ли контейнеры, не упёрлись ли ноды в память. Он нужен, чтобы при плохой метрике данных одним взглядом отделить «сломался конвейер» от «сломалась машина». Отдельный сборщик метрик Kafka нужен ради отставания чтения. Сборщик метрик Airflow через StatsD не берём. ## Почему Образцом служил мониторинг предшественника: четыре дашборда, десять правил оповещения, два внешних сборщика и урок курса. Форма там хорошая и берётся целиком — сначала смотрим, потом ломаем одну вещь управляемым образом, видим, как мониторинг это показал, и возвращаем назад. Содержание берётся не целиком. Панелей с запросами в трёх «настоящих» дашбордах предшественника — 28. На вопрос «с данными всё в порядке?» отвечают шесть. Остальное — процессор, память, части и слияния, размер набора DAG-файлов, время их разбора, пульс планировщика, свободные слоты исполнителя. И при этом ни одной панели про свежесть, ни одной про долю брака, ни одной про сходимость Kafka с ClickHouse. То есть три главных вопроса дата-инженера там просто не заданы. Отсюда решение: инфраструктурные панели не убираются, а переносятся на свой дашборд, и рядом появляется тот, которого не было. Три вещи предшественника не повторяем. Правило оповещения `Kafka No Messages Produced` краснеет на здоровом стенде, когда живой поток просто не запущен, и уроку приходится за это извиняться отдельным абзацем. Правило, красное в нормальном состоянии, учит не тому, что задумано: оно учит не смотреть на оповещения. Самый проработанный дашборд предшественника — про генератор, которого в бою не существует: 17 панелей с гистограммами задержек и пульсом против 12 у ClickHouse. Силы ушли туда, где инструментировать было легко, а не туда, где стоит вопрос. Три текстовые панели там хранят команды и пометку «настроено под тик 5 секунд» прямо в JSON дашборда. Поменяется тик — панель молча соврёт. Документация живёт в документации. Сборщик метрик Airflow через StatsD — это отдельный контейнер плюс файл перевода имён, и весь его выход — внутренности планировщика: пульс, слоты, время разбора файлов. Дежурному по платформе это нужно, дата-инженеру — нет. Вопрос «доехал ли вчерашний слепок заказов» дешевле и честнее задать самим данным. ## Что проверено 31 июля 2026 года. Мониторинг предшественника разобран по файлам в `configs/grafana/provisioning/` и `configs/prometheus.yml` репозитория `clickstream-ch-kafka-superset-demo`: 28 панелей с запросами в дашбордах ClickHouse, Kafka и Airflow, 17 — в дашборде генератора, 10 правил оповещения. Источник данных ClickHouse — плагин, в образе Grafana его нет. Проверено запросом к живому стенду (`/api/plugins?type=datasource`): 19 встроенных источников, ClickHouse среди них отсутствует. Плагин ставится сборкой своего образа Grafana, как уже собираются свои образы Airflow и Superset. Установка при старте контейнера отвергнута: она делает `make up` зависимым от сети и от доступности каталога плагинов, то есть стенд перестаёт подниматься по причинам, к нему не относящимся. Версия плагина закрепляется, как закреплены остальные. Состав панелей выбран до этапа 9 намеренно: уроки пишутся отдельной работой (спека, раздел 10), но рассказать урок можно только про то, что дашборд показывает. Скопируй мы состав предшественника — урок неизбежно получился бы про пульс планировщика. 21 августа 2026 года дашборд «Данные» собран. Один пункт решения исполнен не буквально: у панели потока нет ряда «против вчерашнего». Сдвинуть ряд на модельные сутки значит записать ускорение мира в JSON дашборда — ровно ту пометку, от которой этот же ADR отговаривает выше, — а реальные сутки на стенде не с чем сравнивать. Довод целиком и остальное устройство дашборда — [docs/architecture/monitoring/data.md](../architecture/monitoring/data.md). Тогда же собраны «Кластер» и «Запросы». Довод про `clusterAllReplicas` подтвердился с одной поправкой: очередь распределённых DDL лежит не у ноды, а в keeper, и обе ноды читают её целиком — запрос вернул с каждой одни и те же 124 записи. Обёртка там не добавила бы правды, а удвоила бы каждую строку, поэтому единственная панель «Кластера» без неё — эта. Keeper своих системных таблиц не имеет вовсе, и панель по нему приходит из Prometheus. «Запросы» получили на две панели больше, чем сказано выше. Разбор запросов по посетителям продиктован [ADR 0007](0007-clickhouse-access.md): своя учётка Grafana заведена там ровно затем, чтобы её запросы были отличимы от человеческих. Отдельная панель ошибок понадобилась потому, что отказ достаётся шарду: в замере с принудительным пределом памяти каждая нода записала свой, и строка шарда видна только без фильтра по инициатору. Здешний сюжет про тяжёлый `GROUP BY` при этом кончается не отказом, а сбросом на диск ([ADR 0004](0004-resource-limits.md)) — отказ на стенде приходится вызывать настройкой. Устройство обоих дашбордов — [cluster.md](../architecture/monitoring/cluster.md) и [queries.md](../architecture/monitoring/queries.md).