Grafana — вытаскиваем графики в другую систему

Posted: 2017-05-04 in IT, Networks, Software
Метки:,

Если у вас так или иначе реализован мониторинг, то в какой-то момент возникнет разделение событий и сведений мониторинга по степени важности. И почти наверняка вам потребуется отобразить данные из одной системы в другой системе. Суть данной статьи — как вытащить интересующие графики нагрузки, созданные системой Grafana, во внешнюю самописную систему максимально простым способом, например, для отображения на публичном сайте или в любой другой системе.

Графана, как и какти, да и многие другие подобные системы, предоставляют доступ к данным только авторизованным пользователям.

Поэтому некоторые программисты иногда действуют «в лоб» — заводят readonly-аккаунт в мониторинге, расковыривают процедуру авторизации, потом начинают с помощью curl и магии нецензурных регулярных выражений пытаться повторить в минимальном объёме работу браузера. Получается минимум три запроса — дернуть первый раз страницу, получить кукисы, потом с этими кукисами отправить логин/пароль и авторизоваться, возможно получить ещё кукисы, и только третьим запросом получить нужный график. Дело может заметно осложниться использованием CSRF-токенов в теле страницы (иногда зашифрованных и привязанных ко всяким заголовочным данным), кодом на JS, обфусцированными именами полей и прочей жестью, да и обновление системы мониторинга ломает такую «интригацию» на раз-два, что в нашем продакшене собственно и случилось 😀 . Так вот — этот путь мерзок и неправилен, и использовать его можно только от тоски и безысходности, когда все иные пути труднореализуемы. В этом случае у вас будет целая страница кода на php / perl (упаси вас боже делать это на си), а ковыряние в месиве из HTML/JS в отладчике браузера и дампах траффика ради раскуривания тонкостей авторизации — плохое времяпровождение.

Правильный путь — чтение документации и использование всяких веб-API, которые а) не меняются столь динамично, как веб-морды б) гораздо проще в понимании и отладке.
У графаны для этого есть прекрасный метод авторизации с использованием API-ключа, передаваемого в HTTP-заголовке. Он позволяет получить любой график за любой период времени ровно одним HTTP-запросом и очень прост в реализации.

Сперва настраиваем графану. Тут нужно сделать ровно две вещи:
1). Завести API-ключ:

Сперва вводим понятное НАМ имя ключа, его лучше сделать таким, чтобы было понятно, нафиг он нужен и случайно его потом не грохнуть =), роль оставляем Viewer, чтобы этим ключом нельзя было ничего испортить. Название ключа чисто справочное, на доступы не влияет.

А вот на появившемся окне мы уже увидим собственно сам ключ и даже готовый пример команды для выкачки данных:

Вот эту самую верхнюю строчку [ey…многа-буков…F9] надо сразу же, прямо с этого окна, скопировать и разместить в файле настроек нашей сторонней системы, именно это и есть наш ключ доступа. Потом его просто так будет не посмотреть, внутри системы он в открытом виде скорее всего не хранится, потребуется его генерация и перепрописывание заново.

2). Получить URL до уже отрендеренной PNG-картинки.

Сперва для этого находим нужный нам график на любой из панелек и щелкаем по его заголовку:

Нажимаем View, чтобы получить этот же график отдельно от остальных (графана умеет рендерить и панельки целиком с несколькими графиками сразу, если это требуется). На открывшемся во всю страницу графике снова щелкаем по заголовку и нажимаем Share:

В появившемся окне щелкаем во вкладке [Link] ссылочку [Direct Link rendered Image]:

и получаем чистый PNG в браузере:

Файл получается простым и легковесным. Путь копируем из адресной строки браузера. То, какой именно PNG будет выдан, определяется параметрами запроса. Ключевые данные вот такие:

* Путь «/render/dashboard-solo/db», указывает, что будет отдана PNG, а не HTML+JS апплет со свистелками типа зума/измерителя пиков и прочего, причем отдан будет только один график.
* «/juniper-mx960?&panelId=4» — имя панели и номер конкретного графика с этой панели.
* «&width=1000&height=500» — размеры файла. Нефиг заниматься расайзом в сторонней системе, графана это сделает сама, быстрее и лучше. Она же может быть источником картинок разного размера. Нефиг ставить всякие GD и ImageMagick-и там, где без них можно и нужно обойтись.
* «&from=1493921296652&to=1493932096652» — задают начальные и конечные интервалы времени. Это по сути UnixTime-ы, выраженные в миллисекундах, так что не забываем перед вызовом умножать на тысячу, иначе графики будут пустые.

Ну а теперь немного покодим, совсем чуть-чуть. Мы же не всякие упоротые маньяки, нам нужно меньше кода, больше кофе.

Если у вас скрипт получения на баше — пример прямо на скриншоте. Консольная утилита curl умеет посылать заголовки, просто вызываем её, как показано в примере:

curl -H "Authorization: Beaver ey...F9" http://grafana.my-network.local/render/dashboard-solo/db/juniper-mx960?panelId=4&from=1493921296652&to=1493932096652&width=1000&height=500

и получаем PNG прямо на стандартный вывод. Опция -o для записи в файл, если так удобнее.

На php тоже не сложнее, там curl есть, всё просто:

<?php

$grafana_srv_path = ‘http://grafana.my-network.local&#8217;;
$grafana_api_key = ‘ey…F9’;

$ch = curl_init(«$grafana_srv_path»);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_HTTPHEADER, array(«Authorization: Bearer $grafana_api_key»));

$img1_url = $grafana_srv_path.»/render/dashboard-solo/db/juniper-mx960?panelId=4&width=1000&height=500&from=».(time()-24*60*60).’000&to=’.time().’000′;

curl_setopt($ch, CURLOPT_URL, $img1_url);
$png1 = curl_exec($ch); // выполняем запрос curl для получения картинки

$handle = fopen(«/var/www/html/images/includes-rw/grafik1.png», ‘w’);
fwrite($handle, $png1); # и нагло перезаписываем файл картинки прямо на сайте
fclose($handle);

?>

Выполняем этот скрипт любым удобным нам способом. Собственно это всё — для получения картинки с графиком достаточно уметь отправлять GET-запрос с параметрами и одним дополнительным заголовком. Такую штуку несложно сделать на любом языке программирования, где есть более-менее нормальная работа с http. В принципе, поскольку протокол HTTP-текстовый, не сильно сложнее сделать оное и там, где есть только работа с сетевыми сокетами или команда nc (первую проверку я делал именно ей). И никаких шаманств с кукисами, джава-скритами, фреймворками, сторонними кривыми компонентами и непотребными регулярными выражениями!

Надеюсь, эта заметка была вам полезной. Вообще для визуализации всяких мониторингов и построения красивых дашбордов графана очень симпатична, и имеет смысл рассмотреть её поближе: https://grafana.com/

Даже демка у них прикольная: http://play.grafana.org/dashboard/db/grafana-play-home?orgId=1

Обсуждение закрыто.