# Мониторинг: из чего собран и что скребёт Документ описывает зону мониторинга: какие сервисы в неё входят, что собирает Prometheus, какие источники данных подготовлены в Grafana, каким пользователем она ходит в ClickHouse и что показывают собранные дашборды. Зачем зоне именно такой состав и какие дашборды на нём задуманы — [ADR 0002](../adr/0002-monitoring-scope.md); устройство доступа — [ADR 0007](../adr/0007-clickhouse-access.md). **Что здесь есть и чего ещё нет.** Собран пол: свой образ Grafana с плагином ClickHouse, два подготовленных источника данных, экспортёр метрик Kafka и цель для него у Prometheus. Поверх пола стоит главный дашборд — «Данные»; «Кластер» и «Запросы» приносят отдельные тикеты. Правил оповещения и серверного журнала `system.text_log` тоже пока нет. ## Состав | Сервис | Образ | Что делает | |---|---|---| | `prometheus` | `prom/prometheus:v3.13.2` | опрашивает цели раз в 15 секунд, порт стенда `29090` | | `grafana` | `clickstream-grafana:local` | интерфейс мониторинга; собирается из `infra/grafana/`, порт стенда `23000` | | `kafka-exporter` | `danielqsj/kafka-exporter:v1.9.0` | переводит состояние брокера в метрики Prometheus, порт `9308` | Плагин ClickHouse 4.20.0 входит в образ Grafana. Фоновая установка плагинов при запуске отключена. ## Что скребёт Prometheus | Цель | Задание | Метка `role` | Откуда метрики | |---|---|---|---| | `clickhouse-01:9363` | `clickhouse` | `server` | встроенный экспортёр ноды | | `clickhouse-02:9363` | `clickhouse` | `server` | встроенный экспортёр ноды | | `clickhouse-keeper:9363` | `clickhouse-keeper` | `keeper` | встроенный экспортёр keeper | | `kafka-exporter:9308` | `kafka` | `exporter` | внешний экспортёр | Ровно эти четыре цели пересчитывает `check_prometheus_targets` в `scripts/stand-smoke.sh` — и по значению `up`, и по списку адресов. Пятая цель красит смоук; это и есть способ заметить, что состав пола поменяли молча. ## Источники данных Grafana Оба источника подготовлены файлами в `infra/grafana/provisioning/datasources/` и объявлены `editable: false`: править их через интерфейс нельзя, источник истины — репозиторий. - `prometheus` — основной по умолчанию, ходит на `http://prometheus:9090`. - `clickhouse` — плагин `grafana-clickhouse-datasource`, нативный протокол, `clickhouse-01:9000`, пользователь `grafana`, пароль из `.env`. Источник ClickHouse смотрит на `clickhouse-01`. Системные таблицы обеих нод панели читают через `clusterAllReplicas`, как принято в ADR 0002. ## Доступ к ClickHouse Grafana ходит пользователем `grafana` с ролью `monitoring_reader`: читает слои, таблицы базы `dic` и системные таблицы. `REMOTE` разрешает `clusterAllReplicas`, `CLUSTER` — запросы `ON CLUSTER`. Решение о своей роли записано в [ADR 0007](../adr/0007-clickhouse-access.md). Пароль задаётся переменной `CLICKHOUSE_GRAFANA_PASSWORD`. ## Куда кладутся дашборды Каталог `infra/grafana/provisioning/dashboards/` смонтирован в контейнер и объявлен провайдером в `provider.yml`: Grafana подхватывает оттуда файлы дашбордов, удалять и править их через интерфейс запрещено. Новый дашборд — это новый файл в каталоге и больше ничего: в `compose.yaml` заходить не нужно, ради этого каталог и заведён заранее. Сломанный JSON Grafana не выносит сообщением: она пишет строку в свой журнал и оставляет прежнюю версию дашборда, то есть правка молча не появляется. Поэтому файлы каталога разбирает `make config-test` — тем же доводом, что и файлы дагов ([testing.md](testing.md)). ## Дашборд «Данные» `infra/grafana/provisioning/dashboards/data.json` — шесть панелей на один экран. Вопрос у экрана один: с потоком всё в порядке? Состав панелей и довод за каждую — [ADR 0002](../adr/0002-monitoring-scope.md). Порогов и цветовых вердиктов на панелях нет: на дашборд смотрят глазами, красное и зелёное живёт в проверках и дагах DQ. | Панель | Откуда берёт | О чём отвечает | |---|---|---| | Свежесть | `ods.event_dist`, `ods.order_dist` | сколько прошло с последней доехавшей строки | | Поток | `stg.hits_raw_dist`, `stg.orders_raw_dist` | сколько строк приезжает в слой сырья | | Брак | те же и `ods.*_errors_dist` | сколько приехавшего не разобралось и какая это доля | | Сходимость | экспортёр Kafka и `stg.hits_raw_dist` | произведённое против приземлившегося | | Отставание | `kafka_consumergroup_lag` | сколько сообщений не прочитано | | Дневной слепок | `stg.orders_raw_dist` | какой слепок доехал и когда | ### Почему слои у панелей разные Свежесть спрашивают у ODS. Это слой, который читают, и у заказов дорога до него длиннее: сырьё привозит забор, а типизированную строку кладёт разбор. Встань разбор — свежесть ODS это покажет, свежесть сырья нет. Поток и брак считаются по слою сырья. Сырьё записывает каждую доставку и ничего не схлопывает, а `ReplacingMergeTree` в ODS схлопнет и повтор доставки события, и все версии одного заказа. Считай мы поток по ODS — он занизился бы, и тем сильнее, чем дольше живёт стенд. Доля брака берётся от приехавшего, а не от суммы «годные плюс брак»: брак не отдельная куча, а часть сырья, которая не прошла разбор. Окно у панели брака — окно дашборда, и это не косметика. У `ods.*_errors_dist` срок жизни месяц, а у `ods.event_dist` его нет вовсе: доля за всё время сравнивала бы разные сроки хранения. Отдельного ряда «против вчерашнего» на панели потока нет. Модельные сутки при ускорении ×60 укладываются примерно в двадцать четыре реальные минуты, так что соседние дни мира и без того помещаются в одно окно панели, — а реальное «вчера» на стенде чаще всего приходится на время, когда стенда не было. ### Чтецов Kafka панели не читают `stg.hits_raw_kafka` и `stg.orders_raw_kafka` — таблицы движка Kafka, а не хранилище. У второго стоит `kafka_commit_on_select = 1`: запрос из панели забрал бы слепок себе и сдвинул офсеты, а даг приёма приехал бы к пустому топику. Приземлившееся панели считают по `stg.*_raw_dist`, произведённое — по метрикам экспортёра. ### Как считается сходимость Произведённое живёт в Kafka, приземлившееся — в ClickHouse, и со своей стороны ни одна из них не видит другую. Поэтому панель смешанная: ряд «произведено в Kafka» приходит из Prometheus, ряд «приземлилось в ClickHouse» — из ClickHouse. Единицы общие — сообщений за интервал панели. Со стороны Kafka это разность офсетов топика, «сейчас минус интервал назад», с суммой по обеим партициям; со стороны ClickHouse — `count()` строк сырья по тому же интервалу. Два соседних способа отвергнуты, и оба по замеру на живом стенде. `increase` растягивает приращение на всё окно и на минутном интервале промахивается на проценты: здоровый стенд выглядел бы расходящимся. Накопленный итог от начала окна точнее их обоих, но отсчитывать его надо от края окна — а на свежем стенде окно начинается раньше, чем появился экспортёр, и ряд пропадает целиком. Столбцы ClickHouse подписаны правым краем, а не левым. Точка Prometheus — это прирост к моменту времени, а `count()` по интервалу — сумма, которая набирается к его концу; подпиши мы её началом, здоровые ряды разъехались бы ровно на один столбец. Шаг панели при этом не мельче минуты: экспортёр опрашивают раз в пятнадцать секунд, и на более мелком шаге ряд Kafka пошёл бы ступеньками там, где ряд ClickHouse идёт гладко. Точка в точку ряды всё равно не совпадут, и ждать этого не надо: опрос экспортёра не попадает на границы столбцов, поэтому на разгоне потока линия Kafka идёт чуть выше. Читается устойчивый разрыв между линиями, а не разница в один столбец. Панель смотрит на топик событий. У него приём непрерывный, и разрыв виден сразу. Слепок заказов уезжает пачкой раз в модельные сутки, и вопрос к нему другой — не «сходится ли поток», а «доехала ли выгрузка и когда». На него отвечает своя панель, и модельный день она берёт из самого сообщения: в сырьё он приезжает полем `snapshot_date`. ## Что проверено Права роли `monitoring_reader` сверены 21 августа 2026 года по документации ClickHouse через MCP Context7; разбор — в [ADR 0007](../adr/0007-clickhouse-access.md), раздел «Что проверено». Сам состав проверен на живом стенде 21 августа 2026 года, собранном заново после `make clean`. - Grafana видит плагин `grafana-clickhouse-datasource` 4.20.0 (`/api/plugins?type=datasource`), оба подготовленных источника здоровы. - Запрос источника ClickHouse к `system.one` через `clusterAllReplicas` вернул 2 — с одной ноды видны обе. - Prometheus видит ровно четыре цели, все со значением `up = 1`; запрос `kafka_consumergroup_lag` вернул ряды по группам `clickstream_*`. - `make smoke` 21/21, `make check-clickhouse` 10/10, `make check-services` 7/7.