@@ -1,93 +1,25 @@
# Мониторинг: из чего собран и что скребёт
# Дашборд «Данные»
Документ описывает зону мониторинга: какие сервисы в неё входят, что собирает
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` заходить не нужно, ради
этого каталог и заведён заранее.
Файлы каталога разбирает `make config-test` , рядом с файлами дагов и по тому же
доводу ([testing.md ](testing.md )).
## Дашборд «Данные»
`infra/grafana/provisioning/dashboards/data.json` — шесть панелей на один
`infra/grafana/provisioning/dashboards/data.json` — шесть панелей на один
экран. Вопрос у экрана один: с потоком всё в порядке? Состав панелей и довод за
экран. Вопрос у экрана один: с потоком всё в порядке? Состав панелей и довод за
каждую — [ADR 0002 ](../adr/0002-monitoring-scope.md ).
каждую — [ADR 0002 ](../../ adr/0002-monitoring-scope.md ).
Порогов и цветовых вердиктов на панелях нет: на дашборд смотрят глазами,
Порогов и цветовых вердиктов на панелях нет: на дашборд смотрят глазами,
красное и зелёное живёт в проверках и дагах DQ.
красное и зелёное живёт в проверках и дагах 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.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. Это слой, который читают, и у заказов дорога до него
длиннее: сырьё привозит забор, а типизированную строку кладёт разбор. Встань
длиннее: сырьё привозит забор, а типизированную строку кладёт разбор. Встань
@@ -95,7 +27,7 @@ Grafana ходит пользователем `grafana` с ролью `monitorin
Читает свежесть физическую `_dist` , а не каноническое `ods.*_v` . Представление
Читает свежесть физическую `_dist` , а не каноническое `ods.*_v` . Представление
прячет за собой `FINAL` и отвечает про текущее состояние сущностей, а вопрос
прячет за собой `FINAL` и отвечает про текущее состояние сущностей, а вопрос
здесь про доставку: м естом диагностики доставленных версий физическая таблица
здесь про доставку. М естом диагностики доставленных версий физическая таблица
названа там же, где заведено представление (`sql/ddl/30-ods-views.sql` ).
названа там же, где заведено представление (`sql/ddl/30-ods-views.sql` ).
Поток и брак считаются по слою сырья. Сырьё записывает каждую доставку и ничего
Поток и брак считаются по слою сырья. Сырьё записывает каждую доставку и ничего
@@ -117,25 +49,25 @@ Grafana ходит пользователем `grafana` с ролью `monitorin
пропуск. Реальное «вчера» на стенде чаще всего приходится на время, когда
пропуск. Реальное «вчера» на стенде чаще всего приходится на время, когда
стенда ещё не было. А сдвинуть ряд на модельные сутки значит записать в JSON
стенда ещё не было. А сдвинуть ряд на модельные сутки значит записать в JSON
дашборда ускорение мира — ровно ту пометку про тик, которую [ADR
дашборда ускорение мира — ровно ту пометку про тик, которую [ADR
0002](../adr/0002-monitoring-scope.md) в дашборде держать не велит: поменяют
0002](../../ adr/0002-monitoring-scope.md) в дашборде держать не велит: поменяют
ускорение, и панель молча соврёт. Сравнение остаётся глазу: модельные сутки
ускорение, и панель молча соврёт. Сравнение остаётся глазу: модельные сутки
укладываются в минуты реального времени, и соседние дни мира помещаются в одно
укладываются в минуты реального времени, и соседние дни мира помещаются в одно
окно панели сами.
окно панели сами.
### Чтецов Kafka панели не читают
## Приземлившееся считают по слою сырья
`stg.hits_raw_kafka` и `stg.orders_raw_kafka` — таблицы движка Kafka, а не
Приземлившееся панели считают по `stg.*_raw_dist` , произведённое — по метрикам
хранилище: запрос из панели у второго забрал бы слепок себе и сдвинул офсеты
экспортёра. Таблицы движка Kafka `stg.hits_raw_kafka` и `stg.orders_raw_kafka`
(`kafka_commit_on_select` , см. `sql/ddl/10-stg-tables.sql` ), а даг приёма
хранилищем не работают: у второго стоит `kafka_commit_on_select`
приехал бы к пустому топику. Приземлившееся панели считают по `stg.*_raw_dist` ,
( `sql/ddl/10-stg-tables.sql` ), и запрос из панели забрал бы слепок себе ,
произведённое — по метрикам экспортёра .
сдвинул офсеты, а даг приёма приехал бы к пустому топику .
### Как считается сходимость
## Как считается сходимость
Произведённое живёт в Kafka, приземлившееся — в ClickHouse, и со своей стороны
Произведённое живёт в Kafka, приземлившееся — в ClickHouse, и со своей стороны
ни одна из них не видит другую. Поэтому панель смешанная: ряд «произведено в
ни одна из них не видит другую. Поэтому панель смешанная: ряд «произведено в
Kafka» приходит из Prometheus, ряд «приземлилось в ClickHouse» — из ClickHouse.
Kafka» приходит из Prometheus, ряд «приземлилось в ClickHouse» — из ClickHouse.
Единицы общие — сообщений за интервал панели. Со стороны Kafka это разность
Единицы общие: сообщения за интервал панели. Со стороны Kafka это разность
офсетов топика, «сейчас минус интервал назад», с суммой по обеим партициям; со
офсетов топика, «сейчас минус интервал назад», с суммой по обеим партициям; со
стороны ClickHouse — `count()` строк сырья по тому же интервалу.
стороны ClickHouse — `count()` строк сырья по тому же интервалу.
@@ -155,8 +87,8 @@ Kafka» приходит из Prometheus, ряд «приземлилось в C
Точка в точку ряды всё равно не совпадут, и ждать этого не надо: опрос
Точка в точку ряды всё равно не совпадут, и ждать этого не надо: опрос
экспортёра не попадает на границы столбцов, поэтому на разгоне потока линия
экспортёра не попадает на границы столбцов, поэтому на разгоне потока линия
Kafka идёт чуть выше. Читается устойчивый разрыв между линиями, а не разница в
Kafka идёт чуть выше. Читать надо устойчивый разрыв между линиями; разница в
один столбец.
один столбец не значит ничего .
Панель смотрит на топик событий. У него приём непрерывный, и разрыв виден
Панель смотрит на топик событий. У него приём непрерывный, и разрыв виден
сразу. Слепок заказов уезжает пачкой раз в модельные сутки, и вопрос к нему
сразу. Слепок заказов уезжает пачкой раз в модельные сутки, и вопрос к нему
@@ -166,22 +98,7 @@ Kafka идёт чуть выше. Читается устойчивый разр
## Что проверено
## Что проверено
Права роли `monitoring_reader` сверены 21 августа 2026 года по документации
Дашборд проверен на живом стенде 21 августа 2026 года, `world_live` снят с
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.
Дашборд «Данные» проверен на живом стенде в тот же день, `world_live` снят с
паузы.
паузы.
- Дашборд поднимается из каталога сам: файл положен, панели появились без
- Дашборд поднимается из каталога сам: файл положен, панели появились без
@@ -196,8 +113,6 @@ ClickHouse через MCP Context7; разбор — в
`stg.hits_raw_rep` и `ods.event_errors_rep` , обе таблицы вернулись к нулю.
`stg.hits_raw_rep` и `ods.event_errors_rep` , обе таблицы вернулись к нулю.
- Сходимость: на живом потоке за двадцать пять минут медиана расхождения между
- Сходимость: на живом потоке за двадцать пять минут медиана расхождения между
рядами 3 %, худший столбец 11 % — на переломе потока, как и описано выше.
рядами 3 %, худший столбец 11 % — на переломе потока, как и описано выше.
Отказы тоже по замеру: `increase` расходился сильнее, а накопленный итог
пропадал целиком, стоило окну начаться раньше экспортёра.
- Свежесть реагирует на остановленный поток и возвращается. Через пять минут
- Свежесть реагирует на остановленный поток и возвращается. Через пять минут
после конца модельного дня панель показала 305 с у событий и 288 с у
после конца модельного дня панель показала 305 с у событий и 288 с у
заказов; стоило пустить следующий день, события вернулись к секунде.
заказов; стоило пустить следующий день, события вернулись к секунде.