![](https://habrastorage.org/webt/bb/rv/vx/bbrvvxc7nl8bdqb9u4oblwcictc.jpeg)
Flowers and butterflies by marijeberting
С помощью визуализации данных проще понять и осмыслить собранную информацию, использовать ее на практике. При этом работа с дашбордами должна быть простой для нетехнических пользователей — хорошо, если они смогут получать нужные данные без помощи инженеров.
Команда Mail.ru Cloud Solutions перевела статью, которая поможет добавить в Grafana функции, позволяющие пользователям создавать собственные интерактивные дашборды, чтобы углубиться в конкретные детали.
Общая проблема — унылые статические дашборды
Те, кто работает с данными, часто хотят создать полезные дашборды, которые облегчили бы им самим и другим людям в команде понимание и осмысление собираемых данных.
Распространенная проблема, с которой я столкнулся (как при создании дашбордов, так и при их использовании в качестве пользователя), в том, что многие дашборды недостаточно интерактивны для нетехнических пользователей. В итоге они не могут получить ответы на свои вопросы, не прося инженеров написать новый код, или изменить запросы, выводящие результаты на дашборд. Либо, что еще хуже, пользователи пытаются сами копаться в коде и случайно все ломают.
Решение: сделайте свои дашборды интерактивными (и удобными для пользователей)
К счастью, многие инструменты визуализации содержат функции, позволяющие сделать ваши графики, карты, таблицы и другие визуализации интерактивными с помощью собственного UI. Это беспроигрышная ситуация: удобство использования для пользователей, которые полагаются на ваши дашборды, и меньше времени, которое вам нужно для незначительного изменения настроек.
Вот пример в Grafana — инструменте визуализации с открытым исходным кодом, где я создал «средства выбора» (фильтры), которые позволяют мне и другим пользователям дашборда выбирать значения из выпадающего меню и сразу же видеть изменения на экране, без необходимости копаться в SQL-запросах.
![](https://habrastorage.org/webt/js/kh/73/jskh73tczjpuwq8cmrtjyxxejic.jpeg)
Переменные Grafana позволяют вам использовать выпадающее меню для выбора различных опций, никаких изменений кода не требуется
Однако включить такие опции, как средства выбора, в пользовательском интерфейсе Grafana может оказаться непросто.
В оставшейся части поста я покажу, как вы сможете использовать функцию переменных Grafana для создания собственных интерактивных дашбордов. Я проиллюстрирую этот процесс на примере мониторинга местоположения автобусов, следующих по разным маршрутам в Нью-Йорке, но шаги, которые я выполняю, будут работать для любого сценария.
Попробуйте сами: реализация интерактивных дашбордов в Grafana
Готовы научиться использовать переменные в дашбордах Grafana для модификации запросов PostgreSQL?
Что нам нужно:
- инстанс Grafana;
- PostgreSQL с включенным движком TimescaleDB, подключенный к Grafana как источник данных; (Прим. переводчика: также можно использовать базы данных вроде InfluxDB.)
- дашборд, использующий PostgreSQL в качестве источника данных.
Я собираюсь использовать пример визуализации местоположения в реальном времени в Нью-Йорке, используя данные столичного транспортного управления.
У меня есть существующая настройка дашборда Grafana World Map, изображенная ниже. Чтобы скопировать мою первоначальную настройку, вы можете клонировать этот репозиторий GitHub и выполнить шаги, описанные в нем.
Вот как выглядел мой дашборд, прежде чем мы сделаем его интерактивным (вы можете скачать JSON дашборда в этом репозитории GitHub).
![](https://habrastorage.org/webt/5v/ht/as/5vhtasjzqjp3i0kx07ky37qcpk8.jpeg)
Дашборд «Первоначальная карта», показывающая местоположение автобусов в Нью-Йорке в реальном времени, без каких-либо интерактивных элементов
Вот SQL-запрос, который используется для получения данных для этого дашборда:
SELECT
max(time) as "time",
vid AS "vehicle_id",
route_id,
CASE WHEN route_id LIKE 'M%' THEN 1
WHEN route_id LIKE 'B%' THEN 2
WHEN route_id LIKE 'Q%' THEN 3
WHEN route_id LIKE 'S%' THEN 4
ELSE 0
END AS "color",
ST_X(geom) AS "longitude",
ST_Y(geom) AS "latitude"
FROM mta WHERE time > now()-interval '1.5 minutes'
GROUP BY vid, route_id, geom
ORDER BY 1;
В приведенном выше запросе обратите внимание, что я использую переменную цвета, чтобы различать разные типы автобусов в зависимости от их маршрута. Существует четыре типа автобусных маршрутов: M, B, S и Q — в соответствии с районами Нью-Йорка: Манхеттен (M), Бронкс и Бруклин (B), Стейтен Айленд (S) и Куинс (Q).
Затем я использую настройки Grafana, чтобы назначить цвет каждому маршруту:
![](https://habrastorage.org/webt/ez/sg/rm/ezsgrm4fnlfmerosr8tvgmomvkk.jpeg)
Обратите внимание, что используется пять цветов — один для каждого автобусного маршрута M, B, Q и S, а также один для маршрутов, которые не попадают в эти категории.
Стандартный дашборд сообщает нам о местонахождении автобусов в реальном времени. Мы мало что можем сделать, чтобы лучше исследовать данные, кроме увеличения и уменьшения числа маршрутов.
Давайте создадим переменную, которая определяет, какие автобусные маршруты мы отображаем на карте.
Шаг 1. Создаем переменную как запрос
Наша цель — создать переменную, которая управляет автобусами, отображаемыми в дашборде, на основе маршрута автобуса.
Для простоты давайте определим четыре типа автобусных маршрутов: M, B, Q и S.
Grafana включает в себя множество типов переменных, и переменные в Grafana работают так же, как переменные в языках программирования. Мы определяем переменную, а затем, когда мы ссылаемся на нее, ссылаемся на то, как мы определили переменную.
Чтобы создать новую переменную, зайдите в настройки панели инструментов Grafana, перейдите к параметру «Переменная» в боковом меню и нажмите кнопку «Добавить переменную».
В этом случае мы используем тип
Query
, где наша переменная будет определена как результат запроса SQL.![](https://habrastorage.org/webt/s2/zy/y_/s2zyy_cwjoy3wv_wfu1obpvrfca.jpeg)
Как создать переменную типа Query
В разделе General мы назовем нашу переменную
route
. Затем мы присвоим ей метку MTA Bus Route.![](https://habrastorage.org/webt/r3/uv/of/r3uvofo5ieluzg4-jzyzj-aj9ho.jpeg)
Имя, метка и тип нашей переменной
route
Метки в Grafana — это удобочитаемые дескрипторы, которые отображаются рядом с выпадающим меню в дашборде:
![](https://habrastorage.org/webt/nl/gm/x5/nlgmx59nhpoaso-zhbvyj-nc1eu.jpeg)
Метки переменных отображаются в дашборде, а имя переменной используется для ссылки на переменную в запросах, используемых в дашбордах.
Затем напишем запрос, который определяет значение переменной, в разделе
Query options
.![](https://habrastorage.org/webt/gm/to/xl/gmtoxld8phppoe0sm340zgiowsu.jpeg)
Настройки для создания переменной route
Нам нужно выбрать источник данных для нашей переменной — им будет база данных, в которой будет выполняться запрос. В этом случае мы используем MTA Bus DB, базу данных PostgreSQL, в которой хранятся наши данные MTA Bus.
Теперь мы определим SQL-запрос, результаты которого будут определять нашу переменную
route
:SELECT * from (values ('M'),('B'),('Q'),('S')) v;
Этот запрос возвращает буквы M, B, Q, S — которые являются типами маршрутов на основе их
route_id
(для понимания см. запрос SQL в разделе предварительных требований).Можно использовать более продвинутый запрос, который дает дополнительное преимущество в виде удобочитаемых имен, а не использование символов или аббревиатур:
SELECT k AS "__text", v AS "__value" FROM (VALUES ('Manhattan', 'M'),('Bronx/Brooklyn', 'B'), ('Queens', 'Q'), ('Staten Island', 'S')) v(k, v);
Мы определяем четыре пары ключ-значение как набор возможных значений для нашей переменной маршрута, где ключ — это читабельное имя маршрута, а значение — буква, соответствующая типу маршрута:
- Напомним, что эта переменная также могла иметь тип
Custom
, поскольку у нас есть статический список значений, который никогда не изменяется, что позволяет задавать значения напрямую, без необходимости указывать их через SQL. - Однако если нужно отображение ключ/значение, чтобы отображать как символы, так и понятные человеку имена, требуется запрос SQL. Я использовал SQL-запрос, поскольку на практике часто нужно, чтобы переменные принимали значения, которые не жестко запрограммированы, а изменяются в зависимости от данных в базе данных, таких как имена клиентов, имена кластеров и так далее.
Теперь давайте определим, как использовать нашу переменную.
Поскольку нужна возможность видеть несколько разных маршрутов одновременно, мы включим опцию множественного выбора. Нам также нужна опция «Все», которая выбирала бы все типы маршрутов одновременно:
- Иногда не нужно выбирать несколько вариантов — например, если вы выбираете метрики из разных баз данных.
- Но в этом случае я считаю нужным видеть данные с нескольких автобусных маршрутов одновременно.
Внизу, в разделе «Предварительный запрос», можно увидеть предварительный набор результирующих значений. В нашем случае у нас есть «Все», «M», «B», «Q», «S» (то есть, наши четыре отдельных автобусных маршрута и опция «Выбрать все»).
![](https://habrastorage.org/webt/1p/aq/0d/1paq0dchep3nt3--kkqnxettgl8.jpeg)
В Grafana удобный предварительный просмотр того, какие значения маршрута будут в выпадающем меню
Шаг 2: Измените запрос для построения графиков с учетом новой переменной
В этом пункте мы модифицируем запрос, чтобы использовать переменную из первого шага.
Для запроса SQL мы изменим предложение
WHERE
, чтобы отфильтровать нежелательные результаты. В нашем случае мы хотим показать только те типы маршрутов, которые выбраны в выпадающем меню в пользовательском интерфейсе дашборда.Вот модифицированный запрос:
SELECT
max(time) as "time",
vid AS "vehicle_id",
route_id,
CASE WHEN route_id LIKE 'M%' THEN 1
WHEN route_id LIKE 'B%' THEN 2
WHEN route_id LIKE 'Q%' THEN 3
WHEN route_id LIKE 'S%' THEN 4
ELSE 0
END AS "color",
ST_X(geom) AS "longitude",
ST_Y(geom) AS "latitude"
FROM mta WHERE time > now()-interval '1.5 minutes'
AND substring(route_id,1,1) IN ($route)
GROUP BY vid, route_id, geom
ORDER BY 1;
Соответствующая часть запроса, где мы ссылаемся на нашу новую переменную по имени, которое мы определили на первом шаге, это строки 13 и 14:
SELECT
...
WHERE time > now()-interval '1.5 minutes'
AND substring(route_id,1,1) IN ($route)
Эти строки говорят, что наша визуализация отображается только, если первая буква ее
route_id
находится в наборе разрешенных маршрутов (выбирается пользователем с помощью раскрывающегося списка, определяемого переменной маршрута). Значения, выбранные в списке, будут определять нашу переменную $route
.Например:
- Если пользователь выбирает все маршруты, то route = (M, B, S, Q), набор всех возможных типов маршрутов.
- Если пользователь выбирает только маршруты M и B, то route = (M, B). Мы автоматически отфильтровываем маршруты S и Q и отображаем только автобусы с
route_id
, начинающимся с M и B.
После того как мы изменили запрос, сохраняем наши изменения и проверяем, работает ли наша переменная так, как ожидалось.
Для этого выбираем различные маршруты в выпадающем списке и проверяем, что отображаются только нужные маршруты.
![](https://habrastorage.org/webt/bt/um/dq/btumdq83krpfjsiofvfx-8634r0.gif)
Наш новый интерактивный дашборд, где карта обновляется на основе маршрутов, которые мы выбираем в выпадающем меню
Как вы можете видеть, карта автоматически меняет типы автобусов, отображаемые на экране, в зависимости от выбора, который мы делаем в раскрывающемся списке. Обратите внимание, что изменения происходят в нескольких панелях, поскольку все они используют переменную
$route
в своем запросе.Мы успешно создали интерактивный дашборд Grafana с использованием переменных.
Успехов!
Что еще почитать по теме: