Привет, Хабр!

Меня зовут Елизавета Добрянская и я фронтенд-разработчица в компании Домклик.

Я хочу рассказать, как мы танцевали с бубном при настройке алертов на клиентские метрики. Как, зачем и с чем мы столкнулись в этой задаче — читайте дальше ????

О чём эта статья

Несколько слов про Clickhouse и Grafana, чтобы было понятно, о чём дальнейший разговор.

Clickhouse — столбцовая система управления базами данных (СУБД) для онлайн-обработки аналитических запросов. Мы используем её для сохранения метрик о пользовательских действиях на сайте (клики по ключевым кнопкам, открытие экспериментальных страниц и т.п.). Она предоставляет удобный интерфейс для отправки данных прямо из нашего клиентского кода, что нас более чем устраивает.

Grafana — платформа для визуализации, мониторинга и анализа данных. Она позволяет строить графики по собранным метрикам, реагировать на внештатные ситуации, визуально проверять гипотезы и многое другое. Одной из весомых функций этой платформы является автоматическая рассылка алертов. Во многом из-за неё появилась эта статья.

Зачем нам такие специфичные алерты

Кажется, обработка метрик — это исключительно бизнес-история и она не должна напрямую затрагивать разработчиков. К сожалению, всё не так просто. Продукт — это полноценная машина, в которой всё взаимосвязано. Разработчики влияют на сбор метрик так же сильно, как на выкатку новой фичи. Почему? Потому что и новая функциональность, и отправка метрик работают через один и тот же программный код. И если мы катим новый релиз, нам важно проверить не только работоспособность нашего проекта, но и корректную отправку метрик. Думая над решением этой проблемы, мы пришли к выводу, что наконец-то настал тот день, когда мы сделаем алерты на метрики.

Мы решили обеспечить бесперебойную доставку метрик с фронта в Clickhouse. Для проверки этой доставки наиболее удобным инструментом для нас стала Grafana, потому что у нас уже есть графики по метрикам, плагин для работы с Clickhouse и чатик алертов в Telegram. Звёзды сошлись ????

Механизм работы алертов

Как определить «потерю метрик»? Очень просто: потерянные метрики перестают сохраняться в Clickhouse, а значит график их отображения в единицу времени стремительно приближается к нулю.

То есть достаточно собирать метрики за единицу времени и слать алерт, если они равны нулю? Не совсем так. Сбор количества, к примеру, за час может привести к тому, что алерты стрельнут ночью (потому что ночью трафик очень близок к нулю), а это некорректный результат. Поэтому механизм был переделан на более динамичный и менее привязанный к времени суток.

Мы решили проверять резкие изменения графика. В текущий момент времени смотрим, насколько изменилось количество метрик сейчас относительно количества 10 минут назад. Берём это изменение в процентах. Если этот процент больше 10% (какое количество метрик было, такое и осталось, 100% никогда не будет), то считаем, что всё хорошо. А если меньше 10% (количество метрик резко упало) — шлём алерт.

Для проектов, которые обычно редко открывают, оцениваем изменение за более длинный период (например, за час). Получается более сглаженная метрика, к тому же после выкатки проекта можно быстро заметить, если метрики «отвалились».

Еще нюанс. «Количество в текущий момент времени» — это не в текущую минуту. Прямо в текущую минуту метрики не успевают дойти до Clickhouse. Поэтому для чистоты сбора считаем «текущим временем» момент минуту назад (или час назад для редких метрик).

Базовая настройка алертов в связке Grafana + Clickhouse

Теперь разберём подробнее, куда нажимать и что за что отвечает.

Шаг 0. Настроить окружение в Grafana

У нас этот шаг был выполнен ещё админами, поэтому нам не пришлось. Но если вы настраиваете с нуля, то придётся это сделать:

  • создать пространство команды;

  • создать новый дашборд;

  • добавить новый ресурс данных для Clickhouse (Configuration → Data Sources → Add data source);

  • добавить пользователя для подключения к Clickhouse из Grafana;

  • добавить новый канал для отправки алертов (Alerting → Notification channels → New channel).

Шаг 1. Настраиваем график метрик

Мы прописывали два разных запроса (Query). Один строит график, который мы можем проверить «глазами» на дашборде, а второй высчитывает необходимое значение для генерирования алертов.

В этом шаге разберём первый запрос. Выбираем нужные нам базу данных, таблицу и формат (здесь важно, чтобы был Time Series, иначе график не построится), а затем пишем само тело запроса. «По-старинке» на SQL:

SELECT 
  toStartOfMinute(created_at) as time,
  uniqIf(user_id, event_type = 'page_view') as show_metric
FROM $table
WHERE app_id = 999 AND $timeFilter
GROUP BY time
ORDER BY time
LIMIT 15

Небольшие пояснения по коду.

Это не чистый SQL, а с примесями Clickhouse. Об этом вы можете почитать в документации, ссылка прикреплена внизу. В качестве примесей здесь выступают:

  • переменные (макросы) $table и $timeFilter, которые позволяют обратиться к данным из текущей страницы Grafana. $table — это наша таблица, которую мы указали при создании запроса, а $timeFilter — временной интервал, который мы выбрали в выпадающем меню интерфейса Grafana (правый верхний угол детализации графика).

  • функции агрегации. toStartOfMinute — группируем таймстемпы, произошедшие в одну и ту же минуту, uniqIf — берём количество уникальных пользователей, увидевших нашу метрику

Не забываем указывать фильтрацию $timeFilter, чтобы не нагружать Clickhouse лишними запросами.

После этих нехитрых манипуляций у нас должен построиться график получения метрики page_view в минуту. Круто! Пошли настраивать алерты.

Шаг 2. Настраиваем запрос для алертов

Для алертов пишем второй запрос, который не будет отображаться на графике, а будет использоваться только для проверки алертов. Запрос возвращает число — это процент, на который изменился график за последние 10 минут. Он очень похож на предыдущий запрос, но немного сложнее, потому что нам нужно взять процентную разницу между двумя временными точками.

Заметка: на самом деле этот запрос должен вернуть временной интервал (Time Series), иначе алерты работать не будут. Поэтому к нашему результату мы подмешиваем текущую временную метку.

Итак, код этого безобразия выглядит как-то так (слабонервным не смотреть):

SELECT
  now(),
  ROUND(count_current / count_10m_ago * 100, 2) as diff_in_percent
FROM (
	SELECT
  	uniqIf(user_id, event_type = 'page_view') as count_current
	FROM $table
	WHERE app_id = 999
		AND toStartOfMinute(created_at) = toStartOfMinute(
      dateadd(minute, -1, now())
    )
	LIMIT 60
) current, (
	SELECT
  	uniqIf(user_id, event_type = 'page_view') as count_10m_ago
	FROM $table
	WHERE app_id = 999
		AND toStartOfMinute(created_at) = toStartOfMinute(
      	dateadd(minute, -11, now())
    )
	LIMIT 60
) old

Как и было сказано выше, он состоит из трёх частей:

  • получение текущего количества метрик (первый подзапрос SELECT);

  • получение количества метрик 10 минут назад (второй подзапрос SELECT);

  • подсчёт изменения количества метрик, перевод в проценты (верхний SELECT).

Круто, запрос есть. Можем перейти к самой настройке.

Шаг 3. Настройка алертов в Telegram-канал

Дальнейшая настройка сводится к простым манипуляциям с Grafana и выбору правильных настроек под конкретный случай. У нас это выглядит так:

Настройка алерта.
Настройка алерта.
  • Name — название алерта, которое будет фигурировать в сообщении в канале.

  • Evaluate every — интервал оценки (с какой частотой проверяется правило алерта).

  • For — время, в течение которого мы считаем ситуацию неизменной.

  • WHEN — выбираем агрегирующую функцию.

  • OF - query (B, 10m, now) — проверяем запрос B в диапазоне [сейчас, 10 минут назад].

  • IS BELOW — выбираем функцию сравнения («меньше») и указываем число 10 (10 процентов).

Из интересного ещё можно настроить ситуации с ошибками и восстановлением. Мы оба поля ставим в Keep Last State, чтобы не получать алерты в этих случаях.

После всех настроек проверяем работу алерта. Нажимаем кнопку Test rule. Появляется модалка, где важно проверить, что нет ошибок. Если всё верно настроено, будет показана ситуация:

Проверка работы алерта.
Проверка работы алерта.

Ура, у нас есть алерты на метрики!

Что пошло не так?

Вся вышеописанная история выглядит очень красиво и просто, да? На самом деле процесс был не таким радужным. Поэтому теперь пришло время «жаришки» — поговорим о том, на что стоит обратить внимание при настройке похожих алертов и что мы хотели бы знать, прежде чем лезть в это.

1. Чувствительная Grafana

Работу с Grafana можно сравнить с походом в дорогой ресторан: ожидаешь попробовать нечто изысканное, а по итогу высокая кухня оказывается «на любителя», и мамины котлеты всё равно вкуснее. Ты пытаешься работать с дашбордами аккуратно и планомерно, а ошибки стреляют в тысяче разных мест просто так.

Итак, чеклист по «нежной» работе с Grafana:

  • Параллельная работа здесь невозможна. Над панелью (или даже над всей бордой) лучше работать только одному человеку и только в одной вкладке. Иначе что-то где-то не сохранится и придётся заново настраивать.

  • Постоянно надо сохранять. Каждое своё изменение на борде. Представьте, что вы работаете в старом Microsoft Office.

  • Постоянно надо перепроверять. После сохранения лучше зайти и проверить, что всё действительно сохранилось

  • Непонятные логи. Готовьтесь к тому, что вы не поймёте логи ошибок с первого раза и будете чинить их наугад. Grafana выдаёт лог ошибки напрямую из Clickhouse, причём он обернут в JSON с дополнительной информацией. Чтобы это всё обуздать, надо быть мастером Шифу, но это не точно.

2. Нестабильность Clickhouse

Это касается не столько разработки, сколько администрирования Clickhouse в компании. К сожалению, профилактические работы могут очень сильно повлиять на наши алерты. Любые накатывания обновлений или просто приостановка сервиса вызывает падение метрик в ноль из-за недоступности. И мы получаем алерты. Не смертельно, но грустно. И повод задуматься: а надо ли вам вообще всё это?

3. Нехватка информации о настройке стека

Этот пункт, пожалуй, мой любимый. Готовьтесь к тому, что загуглить ошибки не получится, и заложите х3 времени на задачу. Во Всемирной паутине очень мало информации о работе связки Grafana + Clickhouse. Пожалуй, наиболее достоверными источниками здесь остаются только документации сервисов и плагина. Если недостаточно этого, то issues и networking.

4. «У вас не последняя версия!»

Продолжение пункта 2. Время историй. Прежде, чем я взялась за задачу в эксплуатации, я подумала, что вполне хорошей идеей будет разобраться с алертами на локальной машине. Скачала Grafana, поигралась с настройками, написала скрипты и даже настроила какие-то алерты, порадовалась. Потом с огромным энтузиазмом и ощущением, что задача успешно выполнена, я пошла в прод. И оказалось, что версии Grafana в нашем проде и на моей локалке разные. И это колоссально, потому что никакие мои скрипты не заработали, и по сути пришлось делать задачу с нуля.

Мораль: тестируйтесь в том же окружении, в котором будете работать.

Мораль 2: будьте готовы, что когда-нибудь версии обновят, и вы об этом узнаете, когда у вас отвалятся метрики.

5. Разница в версиях. Продолжение

Что же ломается в проде? Одной из самых значимых проблем стал Time Series, а именно работа с временными метками. В последней версии Grafana весь код, приведённый выше, работает прекрасно. Но в проде у нас (на момент на писания статьи) не последняя версия! Поэтому легким движением руки временная ветка превращается из

toStartOfMinute(created_at) as time

в

toUnixTimestamp(toStartOfMinute(created_at), 'UTC')*1000 as time

Вопрос во Вселенную: как я должна была догадаться до этого преобразования?! ????

6. «Переобувание» алгоритма

Этот пункт про некоторые фантомные проблемы, которые возникали при настройке. Дело в том, что изначально мы задумывали очень простой алгоритм: собирать количество метрик за день и смотреть, опустились они в ноль или нет. Но по какой-то неведомой причине алерта на метрику, собранную за день, не приходило. То есть он просто не присылался и всё. Если у кого-то есть мысли по этому поводу или кто-то с этим сталкивался, пишите в комменты, буду рада услышать ваши истории.

Исходя из того, что алертов мы так и не дождались, пришлось импровизировать и придумывать новый алгоритм. И кажется, это к лучшему ✨

Итоги

Забавно, что современный фронтенд-разработчик сильно выигрывает, если умеет больше, чем просто красить кнопочки. Это открывает перед нами гораздо больше возможностей разрабатывать удобные и полезные продукты. Но прежде, чем внедрять что-то новое, нужно крепко подумать: а нужно ли вам это?

Буду рада, если наш опыт вам полезен. Всем хорошего веба ✌????

Вместо послесловия. Полезные ссылки

Комментарии (21)


  1. Sild
    28.10.2021 11:38

    Пробовали ли вы настраивать алерты через holtWintersConfidenceBands, вместо отклонения в 10% от 10 минут назад?

    Это выглядит гораздо более перспективным инструментом, но на текущий момент у меня не получилось корректно выставить нахождение метрики внутри окна


    Параллельная работа здесь невозможна. Над панелью (или даже над всей бордой) лучше работать только одному человеку и только в одной вкладке. Иначе что-то где-то не сохранится и придётся заново настраивать.

    -- это неправда, при конкурентной работе в момент сохранения графана пишет "кто-то что-то еще поменял, точно хотите перезаписать?". На это можно как-то среагировать. Например сохранить себе текущий шаблон дашборда

    Постоянно надо перепроверять. После сохранения лучше зайти и проверить, что всё действительно сохранилось

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


    1. emdobro Автор
      28.10.2021 11:45
      +1

      спасибо за коммент) Нет, не пробовали, отклонение в 10% взято эмпирически, т.к. выглядело наиболее уместным на момент решения задачи, которая и так изменяла свой алгоритм "на ходу". Но holtWintersConfidenceBands точно стоит того, чтобы его изучить, спасибо ????


  1. kotovsky_art
    28.10.2021 11:45
    -7

    Зачем в домклике фронтендеров мучают кликхаусом и графаной? ????‍♂️


    1. emdobro Автор
      28.10.2021 11:48
      +3

      почему же мучают? Сбор метрик - вполне продуктовая история, которая касается всех платформ. Для нас удобен Clickhouse в этом плане. А графана - удобный инструмент визуализации. Так что мучения могут складывать только из задач, которые мы себе ставим. Но как развиваться, если не страдать :)


      1. kotovsky_art
        28.10.2021 12:00
        -8

        Вроде бы звучит уместно, но сбор метрик - это NFR (non functional requirements), а не продуктовая история, тем более, что упомянутые инструменты относятся сбору технических метрик, что там у вас крашнулось, упало, выбросило ошибку и тд. (Тут на хабре написано, в домклике 501 - 1000 сотрудников, но не нашлось профильных спецов?). Угадайте что будет, когда на следующей работе вас просят, чем вы занимались в домклик - красила кнопочки и поднимала кликхаус с графаной.


        1. emdobro Автор
          28.10.2021 12:03
          +6

          ни разу не встречала работодателей, которые говорили бы, что расширение своего круга обязанностей - это плохо. Чем больше ты знаешь в IT, тем ты ценнее. И тем интереснее с тобой пообщаться :)


          1. kotovsky_art
            28.10.2021 12:37
            -4

            Вы молоды и еще много чего не видели ) давать советы неблагодарное дело, но я бы на вашем месте (а я был на вашем месте 12 лет назад) занимался углублением знаний, а не расширением. Широту взглядов легко спутать с очень узкой точкой зрения.


        1. Nastradamus
          28.10.2021 12:44
          +7

          Вы не поверите, но у нас почти все разработчики еще и в DevOps-практики умеют :)


        1. Sild
          28.10.2021 13:05
          +4

          Какая глупость.

          Любой разработчик, умеющий в мониторинги и алерты (и зачем оно нужно) из-коробки ценнее того, кто не умеет. Даже при чуть более слабых тех скилах.


  1. SkryabinD
    28.10.2021 11:59

    В Grafana в алертах есть условие percent_diff. Если такой алерт повесить на ваш первый график, то должен быть тот же результат, но без второго графика.


    1. emdobro Автор
      28.10.2021 12:10
      +1

      не совсем так. У нас первый график - это просто количество метрик в единицу времени, не резкость изменения. Он был добавлен для того, чтобы можно было в ручную посмотреть, как изменились метрики. А второй запрос - как раз про подсчет резкого изменения. Его, кажется, и правда можно оптимизировать с помощью percent_diff. Спасибо за подсказку, подумаем в этом направлении :)


  1. Luchnik22
    28.10.2021 13:20
    +1

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


    1. emdobro Автор
      28.10.2021 14:05
      +1

      отличная мысль! Я встречала такие реализации, и это действительно во многом удобнее, чем всё делать руками. Спасибо ????


  1. vainkop
    28.10.2021 20:40

    Для работы с дэшбордами графаны рекомендую использовать код, git, grafonnet и ci/cd, а не "чеклист по нежной работе". Тогда и (внезапно) над кодом сможет работать несколько человек одновременно и других проблем избежите :)


    1. emdobro Автор
      28.10.2021 21:15
      +2

      хороший совет. Но в статье я описала "чеклист по нежной работе" риалтайм. Работа же с кодом подразумевает его собственно написание, выкатку и т.п. Это не очень быстрый процесс, когда тебе нужно быстро проверить гипотезу в настройке алертов или поменять название переменной. И тут также могут быть коллизии в совместной работе. Хотелось подсветить, на какие именно грабли наступили мы при работе без кода и гита. Спасибо :)


  1. BugM
    28.10.2021 22:19

    Не пробовали алерты делать на diff(now-7d)?

    Это обычно самая показательная метрика что что-то изменилось.


    1. emdobro Автор
      28.10.2021 23:31
      +2

      7 дней для нас слишком много, хочется иметь возможность узнать о потере метрик как можно раньше


      1. BugM
        28.10.2021 23:38

        Так вы узнаете сразу же.

        Вводите новую метрику: Значение любой стабильной метрики сейчас минус такое же значение этой же метрики 7 дней назад. Если изменение больше порога (допустим 10% от значения метрики 7 дней назад) - бьем тревогу.

        На сленге WoW (Week-on-Week) называется. Многогранная аббревиатура оказалась.


        1. emdobro Автор
          29.10.2021 00:38
          +2

          прикольно, не знала. Спасибо, что поделились. Думаю, это будет для нас очень полезно :)


        1. olegborzov
          30.10.2021 09:03

          Если так настроить, графана может заспамить алертами в праздничный день посреди недели.


          1. BugM
            30.10.2021 13:45

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

            Спамить алертами не надо. Да и выключение алертов по кнопке на известные дни стоит предусмотреть. Это в любом случае пригодится в эсплуатации.