Sparkline — от curl до графика за один запрос
Представляю вам небольшой сервис, который решает ровно одну задачу — построение графиков. Каких графиков? Да абсолютно любых: от нагрузки на систему до лайков под вашим постом.
Мысль простая: число у вас уже есть. Время сборки печатает CI, глубину очереди знает воркер, количество деплоев за день — скрипт выкатки, а количество лайков — база. Не хватает только места, куда это число отправить, и картинки, на которую потом можно посмотреть. Ни библиотеки в lock-файле, ни демона на машине, ни заголовка с токеном для этого не нужно.
Сам сервис sparkline.ivashkin.dev Три графика по 256 измерений — бесплатно и без карты. Минута на то, чтобы завести, и одна строчка curl, чтобы наполнять.Сначала — минута в мастере
Работает всё максимально просто. Как и в любом сервисе, начинается с регистрации, а дальше мастер из нескольких шагов. Первый — имя графика, и на нём останавливаться не на чем.
Второй — форма, и их пять. Линия — значение во времени, по линии на серию: время ответа, глубина очереди. Площадь — та же линия с залитым объёмом под ней, и несколько серий складываются друг на друга. Столбцы — по столбцу на измерение: деплои за день, ошибки за час. Столбцы с накоплением — сумма за измерение, разложенная на то, сколько внесла каждая серия. И кольцо — что серии показывают прямо сейчас, долями от общей суммы; одна серия в кольце меряется против своей цели.

Третий шаг — серии. Имя серии это то самое имя, по которому потом адресуется измерение: ?cpu=42 находит серию cpu. Здесь можно (но не обязательно) заранее задать, как будут выглядеть разные серии на одном графике — да, на одном графике можно показывать сразу несколько линий. Список можно оставить и пустым: тогда серия заведётся сама от первого же измерения, которое её назовёт, а цвет ей достанется из градиента между двумя выбранными. Отредактировать всё это можно и потом.

Четвёртый шаг — сколько точек график хранит и сколько точек рисует. Это два разных числа, и разница между ними важнее, чем кажется.
Первое — размер окна. Один запрос это одно измерение, и как только приходит новое, самое старое уходит — в той же транзакции, так что график никогда не оказывается даже на мгновение больше своего окна. Это именно окно, а не архив: сервис не хранит историю, он показывает последние N измерений. Второе число — сколько точек попадёт в картинку. Если оно меньше первого, соседние измерения усредняются уже на выходе, а подробность возвращается простым поднятием числа обратно — данные при этом никуда не деваются. В бесплатной версии окно до 256 измерений, в платной — до 4096; платная стоит $3 в месяц, чего как раз хватает на сервер для этого сервиса.

Пятый шаг — что именно видно на картинке. Тумблеров здесь четыре:
- Линии сетки — горизонтали по круглым значениям, с подписями сбоку.
- Временная ось — метки времени вдоль всего нижнего края, а не только под последним измерением.
- Легенда — какая серия каким цветом и что на ней сейчас.
- Начинать ось с нуля.
На последнем стоит остановиться, потому что это единственный тумблер, которым можно испортить себе картину мира. Для счётчиков ноль в основании — единственный честный вариант: столбец, висящий над собственным основанием, врёт о том, во сколько раз он больше соседнего. А ряд, который живёт в узком диапазоне, тот же самый ноль расплющивает: загрузка процессора, гуляющая между 40 и 46 процентами, превратится в прямую линию у самого пола, и вы перестанете видеть на ней ровно то, ради чего её рисовали.
Поэтому по умолчанию он выключен для линий и включён для столбцов.

Ещё здесь задаётся целевое значение — оно рисуется пунктиром поперёк графика, и на кольце из одной серии именно оно становится тем, долей от чего эта серия показана, — и тема: под тёмную страницу или под светлую. Меняется от темы только обстановка, то есть сетка, цифры и легенда; цвета серий остаются вашими.
На этом всё, ваш график готов, и вы получите два ID: публичный и приватный. Оба понадобятся чуть позже.
Дальше всё делает одна строчка
А это самый интересный раздел. Данные попадают на график одним запросом. Помните два ID, которые вы получили при создании графика? Вот здесь они и используются.
curl -fsS 'https://sparkline.ivashkin.dev/i/e48z7fg5ke9k3tv5xy3npwz4v5enhwbp?cpu=42&ram=17'
Это всё. e48z7fg5ke9k3tv5xy3npwz4v5enhwbp — тот самый приватный ID, который вы получили после создания графика, cpu=42 кладёт значение 42 в серию cpu, а ram=17 — значение 17 в серию ram. Если серии с таким именем ещё нет, она заведётся сама.
Один запрос — это одно измерение, сколько бы серий оно ни несло: на оси времени появится одна засечка, а не две. Время отправлять не нужно и нельзя, ось времени идёт по часам сервиса — именно это и позволяет запросу состоять из одних только чисел.
Ответ приходит одинаковой формы независимо от того, получилось или нет, так что jq -e .ok — это уже законченная проверка:
{"ok":true,"chart":"Demo","values":{"cpu":42.0,"ram":17.0},"created":["ram"],
"points":256,"capacity":256,"series":["cpu","mem","ram"],
"url":"https://sparkline.ivashkin.dev/g/hvej9gpqjz5u"}
За created стоит приглядывать: это серии, которые изобрёл вот этот конкретный запрос. Строчка выше — настоящая, и в ней видно, как я опечатался в собственном примере: на демо-графике были cpu и mem, а я отправил ram — и график молча оброс третьей дорожкой. Никакой ошибки здесь нет, так и задумано, но узнать об этом лучше из ответа, чем с картинки неделю спустя.
Кроме строки запроса тот же адрес принимает форму и JSON — это на случай, если число берётся не из шелла:
curl -fsS -d cpu=42 -d ram=17 https://sparkline.ivashkin.dev/i/KEY
curl -fsS -H 'content-type: application/json' -d '{"cpu":42,"ram":17}' https://sparkline.ivashkin.dev/i/KEY
Отдельно стоит знать про пропуски. Прочерк или пустое значение — это не ноль, а дырка: линия на этом месте разрывается, а столбец не рисуется вовсе. То есть ?cpu=$CPU с незаданным CPU запишет сам момент, а не пол, которого никто не мерил. Разница между «здесь было нулевое значение» и «здесь мы не знали значения» — единственное, что на графике нельзя восстановить задним числом.
Дальше достаточно повторять этот запрос, как только у вас появляются новые данные, — и они сразу будут показаны на графике. Возьмите ваш любимый язык программирования, или curl и cron, что угодно, — и вы получите мощную систему построения графиков в одну строчку!
Прежде чем это уедет в cron
Приватный ID — это весь пароль целиком. Он лежит в пути, а не в заголовке, и это осознанный размен: строчка влезает в Makefile, а график времени сборки не стоит того, чтобы разводить вокруг него OAuth. Тот, кто держит этот ID, может ровно одно — дописывать измерения в этот один график. Ни прочитать настройки, ни удалить график, ни добраться до остальных. Утёк не в тот канал в Slack — меняется в один клик, и всё, что было встроено по публичному ID, продолжает работать.
Запись через GET — такой же размен. Запрос, который меняет состояние, положено отправлять через POST, и POST здесь есть, тем же адресом. Но в одну строчку Makefile влезает GET, и ради этого правило нарушено сознательно. Помнить стоит об обратной стороне: чужой прокси имеет полное право такой запрос переспросить, а curl --retry — тем более, и лишняя засечка на графике придёт именно оттуда.
Лимит — 120 запросов подряд, дальше 120 в минуту на один ID. Считаются запросы, а не числа: один запрос с шестью сериями стоит ровно столько же, сколько один с единственным значением. За лимитом приходит 429 с заголовком Retry-After и тем же числом в теле ответа, так что backoff пишется одной строчкой и не требует угадывания. Из остальных ответов интересны 404 — нет графика с таким приватным ID, тем же ответом и на ID неправильной формы, — и 422, когда записывать нечего: бесконечность и NaN сервис отказывается хранить.
А DELETE по тому же адресу опустошает график. Не удаляет: остаются оба ID, серии, их цвета и всё, что вы уже успели встроить. Уходят только измерения — это то, что нужно, когда график пережил переезд и старые числа больше не про то же самое.
Картинка живёт по собственному адресу
Помимо дашборда, который показывает все графики разом, вы можете встроить график в вашу страницу, в файл README на GitHub — да куда угодно, что поддерживает вставку SVG-изображений.
Для этого вам потребуется взять ваш публичный ID и использовать его как изображение:
https://sparkline.ivashkin.dev/g/hvej9gpqjz5u.svg
Картинка рисуется в момент, когда её попросили, поэтому вчерашней она не бывает. Размер подгоняется параметрами ?w= и ?h= — они обрезаются до разумного, а не отвергаются, — и примерно ниже 320×120 подписи осей пропадают сами: на такой картинке они крупнее самого графика. Таблице в README и экрану на стене нужны разные размеры, и ради этого не должно заводиться двух графиков.
Помимо этого, вам будет доступно ещё два способа поделиться вашим графиком.
Первый — <script>, который вы встраиваете на свой сайт:
<script src="https://sparkline.ivashkin.dev/g/hvej9gpqjz5u.js"></script>
А вот тот же график, вставленный этим тегом прямо сюда:
Выше была картинка, а это уже график: наведите на него мышкой и получите подробности по каждой серии. ?fill=1 растягивает его на ширину колонки, ?refresh=60 перерисовывает раз в минуту — чаще десяти секунд нельзя, а в фоновой вкладке обновление встаёт на паузу. График встроится синхронно и ровно там, где стоит тег, а сам тег исчезнет. Рисуется он в shadow root, куда стили страницы не дотягиваются, так что чужой CSS ему ничего не сделает — и наоборот. Несколько таких тегов на одной странице друг другу не мешают.
Второй способ — публичная страница, доступная всем без авторизации и использующая только ваш публичный ID: https://sparkline.ivashkin.dev/g/hvej9gpqjz5u. На ней тот же динамический график, и её можно отправить кому угодно.
А если график нужен не человеку, а программе, к тому же адресу приписывается .json, и приходит таблица: серии — это колонки, измерения — строки, null — то, чего в этот момент не мерили. Никакой из трёх адресов не требует авторизации и ни один из них не умеет писать.
Попробуйте прямо отсюда
Sparkline — простой, но мощный сервис для создания и очень простого наполнения графиков. Ссылки, что я оставил в посте, рабочие, и приватный ID тоже настоящий: вы можете сами отправить запрос на тот URL, что указан в статье, и увидеть, как ваше значение появляется на графике. Регистрироваться для этого не нужно.
И да, график в этом посте общий на всех. Дописать в него может кто угодно — собственно, я об этом и прошу. Если вы открыли эту страницу и увидели на картинке чью-то ерунду, значит, всё работает.
Комментарии 0
Комментариев пока нет.