Представляем новый плагин для Grafana — Statusmap panel

в 10:38, , рубрики: Grafana, open source, prometheus, Блог компании Флант, визуализация данных, системное администрирование

У Grafana есть возможность показывать статус, у Grafana есть возможность показывать данные во времени. Однако, как это ни парадоксально, у Grafana до настоящего момента не было удобного способа показывать статус во времени!

Мы представляем свой плагин — Statusmap panel. Он позволяет наглядно отобразить состояния набора объектов за выбранный промежуток времени. В качестве примера, демонстрирующего работу плагина, представим себе множество локаций, в которых для кого-то готовят кофе:

Представляем новый плагин для Grafana — Statusmap panel - 1
Можно увидеть, как Никки экономит электроэнергию, Герри быстро пополняет запасы воды, кофемашина Валеры частенько барахлит, а на Бифросте Wi-Fi явно лучше, чем на лунной станции, где, похоже, с водой совсем туго.

Выглядит интересно? Но начнём с того, как мы вообще к этому пришли.

Зачем?

Для лучшей визуализации данных мы поставили перед собой простую задачу: отобразить состояния набора timeseries за промежуток времени. Под набором объектов подразумеваются разные timeseries: они могут отличаться набором лейблов и именем. При этом значения timeseries должны удобно, т.е. без костылей, отображаться в текст и цвет.

Актуальные для нашего бизнеса примеры использования такой визуализации — это здоровье серверов или подов Kubernetes, результаты проверки HTTP-сервисов. Так в компании «Флант» и родился плагин к Grafana под названием Statusmap. Размышляя над великим множеством возможностей его применения и для других задач, мы быстро приняли на себя обязательство поделиться кодом с мировым сообществом. Но неужели никто до нас не решал эту задачу?

Почему не готовое?

Задача в действительности популярная, так что первопроходцами мы в ней не стали. Началось всё с того, что у нас было несколько дашбордов с крутыми плагинами Status Panel и Status Dot. Эти плагины позволяют отобразить текущее состояние набора объектов, например, хостов или подов… или кофемашин в разных частях света.

Представляем новый плагин для Grafana — Statusmap panel - 2

Представляем новый плагин для Grafana — Statusmap panel - 3

Всё шло хорошо, пока нам не захотелось видеть статусы этих объектов во времени. Первым, самым простым решением было добавить обычный граф с галочкой stacked.

Представляем новый плагин для Grafana — Statusmap panel - 4

По задумке Status Panel + stacked Graph позволили бы видеть состояние объектов «на сейчас» и развитие ситуации во времени. Однако stacked Graph не очень нагляден:

  • цветом отмечаются различные timeseries, а не значения, которые отображаются цветом для Status Dot или Status Panel. То есть цвета для двух графиков не одинаковые и это сбивает с толку;
  • если среди значений появляется null, то графики проваливаются.

Попробовали приспособить стандартный Heatmap — не получилось: плагин работает с осью Y только на уровне значений и не умеет выводить там лейблы. Тогда мы попробовали следующие плагины для Grafana:

  • Carpet plot — группирует значения по дню и по выбранному фрагменту дня;
  • Discrete Panel — хороший плагин, но нам нужно дискретно показывать статусы во времени;
  • Status By Group Panel — хорошее улучшение к Status panel, позволяющее отображать множество статусов, однако всё ещё без нужных нам возможностей.

По результатам всех проведённых исследований мы сформулировали следующие требования к плагину:

  • выделенная чёткая строка графика для каждого объекта;
  • имя объекта отображается по оси Y и задаётся в поле легенды;
  • по одному объекту может быть несколько статусов — в таких случаях самый значимый будет отображаться цветом, а остальные показываться в tooltip’е;
  • корзины (buckets) отображать шириной не менее заданной (5 px), т.к. в однопиксельные неудобно наводить мышкой;
  • ручное управление цветом — возможность задать цвет каждому числовому значению из дискретного набора.

Позвольте теперь сделать небольшое отступление про графики Heatmap, Prometheus и дискретные статусы…

Немного теории

Классический heatmap — это 3-мерный график:

  • по оси X откладывается время,
  • по оси Y — возможные значения некоторой величины,
  • по оси Z — количество наблюдаемых значений в данный момент времени.

Стандартный плагин 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 могут быть такие значения статуса:

  • 0 — ok,
  • 1 — off,
  • 2 — no beans,
  • 3 — no water,
  • 4 — fail.

Далее казалось бы всё просто: взять количество нулей, единиц, двоек и т.д. в течение одной минуты… и мы имеем отличные данные для отображения на графике! Но у 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» дала идею превратить метрику с дискретными значениями в метрики с лейблами. Это можно сделать с помощью такого 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. И так — для каждого наблюдаемого значения.

Обычно статусы определены заранее, поэтому можно составить набор запросов, чтобы не пропускать нужные значения. Легенда у всех запросов должна совпадать, чтобы можно было сгруппировать значения:

Представляем новый плагин для Grafana — Statusmap panel - 5

Теперь, если в течение минуты кофемашина была выключена 30 секунд (статус off — 1), а остальное время работала (статус ok — 0), то у нас будет информация о выключении, т.к. плагин получит два значения с одной легендой за один момент во времени: 0 от query A и 1 от query B.

Хорошо: мы придумали, как агрегировать данные о дискретных статусах и при этом не терять информацию. Осталось придумать, как объединять данные на основе легенды и отрисовывать их на панели.

Плагин Statusmap

К тому, что описано выше мы, конечно же, пришли не сразу, но когда всё это сложилось воедино, стало понятно, что по сути не хватает механизма отрисовки. Теперь такой механизм есть — Statusmap panel plugin, который умеет следующее:

  • значения в каждой точке времени группируются в корзины по совпадению текста легенд, указанных в Query;
  • каждому тексту легенды соответствует своя строка на графике и текст отображается как метка на оси Y, а пустые значения отображаются пробелом или как 0:

    Представляем новый плагин для Grafana — Statusmap panel - 6

  • для любого значения можно задать точный цвет корзины:

    Представляем новый плагин для Grafana — Statusmap panel - 7

  • если в корзину попало несколько значений, то цвет будет взят для того значения, которое определено выше на вкладке Colors, а при наведении на корзину отображаются все значения, которые попали в неё:

    Представляем новый плагин для Grafana — Statusmap panel - 8

  • плагин умеет формировать interval для запроса к Prometheus, чтобы корзины не превращались в пиксельные линии.

В итоге получается очень удобное представление статуса нескольких объектов. Причем можно посмотреть как текущий статус (это самые правые корзины), так и статус объекта во времени.

Где взять?

Исходный код Grafana Statusmap plugin распространяется под свободной лицензией MIT (по аналогии с другими плагинами для Grafana). На данный момент он доступен в нашем GitHub. И мы искренне надеемся, что в ближайшее время он попадёт и в репозиторий плагинов Grafana.

И напоследок — иллюстрация, как Statusmap помогает визуализировать данные со статусами подов из production-кластера Kubernetes:

Представляем новый плагин для Grafana — Statusmap panel - 9

Автор: diafour

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js