- PVSM.RU - https://www.pvsm.ru -
У Grafana есть возможность показывать статус, у Grafana есть возможность показывать данные во времени. Однако, как это ни парадоксально, у Grafana до настоящего момента не было удобного способа показывать статус во времени!
Мы представляем свой плагин — Statusmap panel [1]. Он позволяет наглядно отобразить состояния набора объектов за выбранный промежуток времени. В качестве примера, демонстрирующего работу плагина, представим себе множество локаций, в которых для кого-то готовят кофе:
Можно увидеть, как Никки экономит электроэнергию, Герри быстро пополняет запасы воды, кофемашина Валеры частенько барахлит, а на Бифросте Wi-Fi явно лучше, чем на лунной станции, где, похоже, с водой совсем туго.
Выглядит интересно? Но начнём с того, как мы вообще к этому пришли.
Для лучшей визуализации данных мы поставили перед собой простую задачу: отобразить состояния набора timeseries за промежуток времени. Под набором объектов подразумеваются разные timeseries: они могут отличаться набором лейблов и именем. При этом значения timeseries должны удобно, т.е. без костылей, отображаться в текст и цвет.
Актуальные для нашего бизнеса примеры использования такой визуализации — это здоровье серверов или подов Kubernetes, результаты проверки HTTP-сервисов. Так в компании «Флант» и родился плагин к Grafana под названием Statusmap. Размышляя над великим множеством возможностей его применения и для других задач, мы быстро приняли на себя обязательство поделиться кодом с мировым сообществом. Но неужели никто до нас не решал эту задачу?
Задача в действительности популярная, так что первопроходцами мы в ней не стали. Началось всё с того, что у нас было несколько дашбордов с крутыми плагинами Status Panel [2] и Status Dot [3]. Эти плагины позволяют отобразить текущее состояние набора объектов, например, хостов или подов… или кофемашин в разных частях света.
Всё шло хорошо, пока нам не захотелось видеть статусы этих объектов во времени. Первым, самым простым решением было добавить обычный граф с галочкой stacked.
По задумке Status Panel + stacked Graph позволили бы видеть состояние объектов «на сейчас» и развитие ситуации во времени. Однако stacked Graph не очень нагляден:
null
, то графики проваливаются.Попробовали приспособить стандартный Heatmap [4] — не получилось: плагин работает с осью Y только на уровне значений и не умеет выводить там лейблы. Тогда мы попробовали следующие плагины для Grafana:
По результатам всех проведённых исследований мы сформулировали следующие требования к плагину:
Позвольте теперь сделать небольшое отступление про графики Heatmap, Prometheus и дискретные статусы…
Классический heatmap — это 3-мерный график:
Стандартный плагин Heatmap отображает ось Z цветом — например, от белого до красного или через градиент зелёный-жёлтый-красный. Это очень хорошо работает для непрерывных значений: времени отклика, длины очереди, количества запросов к серверу… В случае дискретных статусов для набора объектов нужно следующее: по оси Y отобразить имена объектов, которые мы мониторим, а по оси Z — показать для каждого объекта наблюдаемые в данный момент времени статусы… Но стойте! Что значит множество статусов объекта в момент времени? Попробую описать.
Те, кто использует Prometheus с Grafana, знают про step
или interval
— настройку на закладке Query. Если там указать 1m
, а данные вы собираете с интервалом в 5s
, то при выполнении простого запроса метрики coffee_maker_status
Prometheus вернёт каждое 12-ое значение, а 11 значений на графике уже никак не увидеть. Как улучшить ситуацию?
Первым, что приходит в голову, — воспользоваться функциями агрегации — например, *_over_time(coffee_maker_status[1m])
. Какую именно функцию взять? Время разобраться с тем, как представляется статус в метриках Prometheus. В большинстве случаев статус обозначается неким набором значений. Например, для coffee_maker_status
могут быть такие значения статуса:
Далее казалось бы всё просто: взять количество нулей, единиц, двоек и т.д. в течение одной минуты… и мы имеем отличные данные для отображения на графике! Но у Prometheus свой взгляд на это: coffee_maker_status[1m]
— это range vector, а потому выражения вроде max_over_time(coffee_maker_status[1m]==2)
или count_values_over_time(coffee_maker_status[1m], 3)
, которые очень бы подошли, невозможны.
Всё отлично работает, если в метрике есть два значения: 0
(статус не наблюдался) и 1
(статус наблюдался), — а сам статус хранится в лейбле. Тогда можно составлять такие запросы: (max_over_time(coffee_maker_status{status="3"}[1m]) == 1) *3
Что же делать с метрикой, у которой несколько значений? Заметка «Composing range vector functions in PromQL [8]» дала идею превратить метрику с дискретными значениями в метрики с лейблами. Это можно сделать с помощью такого recording rule:
- record: coffee_maker_status:discrete
expr: |
count_values("status", coffee_maker_status)
Это правило трансформирует метрику coffee_maker_status
так: если пришло значение 3
, то Prometheus создаёт метрику coffee_maker_status:discrete{status="3"}
со значением 1. И так — для каждого наблюдаемого значения.
Обычно статусы определены заранее, поэтому можно составить набор запросов, чтобы не пропускать нужные значения. Легенда у всех запросов должна совпадать, чтобы можно было сгруппировать значения:
Теперь, если в течение минуты кофемашина была выключена 30 секунд (статус off — 1
), а остальное время работала (статус ok — 0
), то у нас будет информация о выключении, т.к. плагин получит два значения с одной легендой за один момент во времени: 0
от query A и 1
от query B.
Хорошо: мы придумали, как агрегировать данные о дискретных статусах и при этом не терять информацию. Осталось придумать, как объединять данные на основе легенды и отрисовывать их на панели.
К тому, что описано выше мы, конечно же, пришли не сразу, но когда всё это сложилось воедино, стало понятно, что по сути не хватает механизма отрисовки. Теперь такой механизм есть — Statusmap panel plugin [1], который умеет следующее:
0
:
interval
для запроса к Prometheus, чтобы корзины не превращались в пиксельные линии.В итоге получается очень удобное представление статуса нескольких объектов. Причем можно посмотреть как текущий статус (это самые правые корзины), так и статус объекта во времени.
Исходный код Grafana Statusmap plugin распространяется под свободной лицензией MIT (по аналогии с другими плагинами для Grafana). На данный момент он доступен в нашем GitHub [1]. И мы искренне надеемся, что в ближайшее время он попадёт [9] и в репозиторий плагинов Grafana [10].
И напоследок — иллюстрация, как Statusmap помогает визуализировать данные со статусами подов из production-кластера Kubernetes:
Автор: diafour
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/open-source/293277
Ссылки в тексте:
[1] Statusmap panel: https://github.com/flant/grafana-statusmap
[2] Status Panel: https://grafana.com/plugins/vonage-status-panel
[3] Status Dot: https://grafana.com/plugins/btplc-status-dot-panel
[4] Heatmap: https://grafana.com/plugins/heatmap
[5] Carpet plot: https://grafana.com/plugins/petrslavotinek-carpetplot-panel
[6] Discrete Panel: https://grafana.com/plugins/natel-discrete-panel
[7] Status By Group Panel: https://grafana.com/plugins/blackmirror1-statusbygroup-panel
[8] Composing range vector functions in PromQL: https://www.robustperception.io/composing-range-vector-functions-in-promql
[9] попадёт: https://github.com/grafana/grafana-plugin-repository/pull/307
[10] репозиторий плагинов Grafana: https://grafana.com/plugins
[11] Источник: https://habr.com/post/423851/?utm_source=habrahabr&utm_medium=rss&utm_campaign=423851
Нажмите здесь для печати.