Легкая работа со сложными алертами. Или история создания Balerter

    Все любят алерты.

    Конечно, гораздо лучше получить уведомление когда что-то произошло (или починилось), чем сидеть, смотреть на графики и искать аномалии.

    И инструментов для для этого создано немало. Alertmanager из экосистемы Prometheus и vmalert из группы продуктов VictoriaMetrics. Уведомления zabbix и алерты в Grafana. Самописные скрипты на bash и Telegram боты, которые периодически дергают какой-то URL и говорят, если что-то не так. Много всего.

    Мы, в нашей компании, тоже использовали разные решения, пока не уперлись в сложность, или, скорее, невозможность создания сложных, составных алертов. Чего нам хотелось и что в итоге сделали - под катом. TLDR: Так появился open source проект Balerter

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

    Сказать, когда некий график упал/вырос на XX% и находится там уже N минут по сравнению с предыдущим периодом в M часов? Это, кажется, можно попробовать реализовать с Grafana или Alertmanager, но довольно не просто. (А может и нельзя, я сейчас и не скажу)

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

    Проверяем данные из двух баз Clickhouse, далее сравниваем с некоторыми данными из Postgres, и принимаем решение об алерте. Сигнализировать либо отменить

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

    • обращаться к разным источникам данных. Например, Prometheus, Clickhouse, Postgres

    • отправлять алерты в различные каналы - telegram, slack и т.д.

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

    • запуск скриптов по расписанию

    • легкое обновление скриптов без перезапуска сервиса

    • возможность как-то расширять функционал без пересборки сервиса из исходных кодов

    Это список примерный и, скорее всего, не очень точный. Какие-то пункты видоизменялись, какие-то умирали. Все как обычно.

    Собственно, именно так началась история Balerter.

    Попробую описать коротко, что в итоге получилось и как это работает. (Да, конечно, это не финал. Много планов для развития продукта. Я просто остановлюсь на сегодняшнем дне)

    Как это работает?

    Вы пишите скрипт на Lua, где явно отправляете запросы (в Prometheus, Clickhouse и т.д). Получаете ответы и как-то их обрабатываете и сравниваете. После чего включаете/выключаете какой-то алерт. Balerter сам отправит уведомление в каналы, которые вы настроили (Email, telegram, slack и т.д.). Скрипт выполняется с заданной периодичностью. И… в общем-то это все)

    Лучше всего показать на примере:

    -- @interval 10s
    -- @name script1
    
    local minRequestsRPS = 100
    
    local log = require("log")
    local ch1 = require("datasource.clickhouse.ch1")
    
    local res, err = ch1.query("SELECT sum(requests) AS rps FROM some_table WHERE date = now()")
    if err ~= nil then
        log.error("clickhouse 'ch1' query error: " .. err)
        return
    end
    
    local resultRPS = res[1].rps
    
    if resultRPS < minResultRPS then
        alert.error("rps-min-limit", "Requests RPS are very small: " .. tostring(resultRPS))
    else
        alert.success("rps-min-limit", "Requests RPS ok")
    end 

    Что тут происходит:

    • указываем, что данный скрипт должен выполняться каждые 10 секунд

    • указываем имя скрипта (для API, для отображения в логах, для использования в тестах)

    • подключаем модуль для вывода логов

    • подключаем модуль для доступа к кликхаусу с именем ch1 (само подкчлючение настраивается в конфиге)

    • отправляем запрос в кликхаус

    • в случае ошибки - выводим сообщение в лог и выходим

    • сравниваем результат запроса с константой (в живом примере мы могли бы это значение получать, например, из базы Postgres)

    • включаем или выключаем алерт с ID rps-min-limit

    • вы получите уведомление, если статус алерта изменился

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

    Поэтому созрело логичное желание - иметь возможность напистать тесты для своих скриптов. И в версии v0.4.0 это появилось.

    Тестирование скриптов

    Пример теста для нашего скрипта из примера выше:

    -- @test script1
    -- @name script1-test
    
    test = require('test')
    
    local resp = {
        {
            rps = 10
        }
    } 
    
    test.datasource('clickhouse.ch1').on('query', 'SELECT sum(requests) AS rps FROM some_table WHERE date = now()').response(resp)
    
    test.alert().assertCalled('error', 'rps-min-limit', 'Requests RPS are very small: 10')
    test.alert().assertNotCalled('success', 'rps-min-limit', 'Requests RPS ok')

    По шагам:

    • указываем имя скрипта, для которого написан тест

    • имя теста (для логов)

    • подключаем модуль тестирования

    • говорим, какой результат надо вернуть при определенном запросе к кликхаусу ch1

    • проверяем, что был вызван алерт (error) rps-min-limit с указанным сообщением

    • проверяем, что алерт rps-min-limit не был отключен (success)

    Что еще умеет Balerter?

    Я попробую коснуться самых важных, по поему мнению, умениях Balerter. Подробно все посмотреть можно на официальном сайте https://balerter.com

    • получать данные из

      • clickhouse

      • postgres

      • mysql

      • prometheus

      • loki

    • отправлять уведомления к каналы

      • slack

      • telegram

      • syslog

      • notiify (UI уведомления на вашем компьютере)

      • email

      • discord

    • строить графики по вашим данным, загружать изображение в S3 совместимое хранилище и прикреплять к уведомлениям (Пример с картинками)

    • позволяет обмениваться данными между скриптами - глобальное Key/Value хранилище

    • писать свои библитеки на Lua и использовать их в скриптах (по-умолчанию поставляются lua-библиотеки для работы с json, csv)

    • отправлять HTTP запросы из ваших скриптов (ну и получать ответы, разумеется)

    • предоставляет API (пока еще не такое функциональное, как хотелось бы)

    • экспортирует метрики в формате Prometheus

    А что хотелось бы уметь еще?

    Уже понятно, что пользователи и мы хотим возможность управлять запуском скриптов с помощью синтаксиса cron. Это будет сделано до версии v1.0.0

    Хочется поддержать больше источников данных и каналов доставки уведомлений. Например, кому-то точно не будет хватать MongoDB. Кому-то Elastic Search. Отправлять SMS и/или делать дозвон на мобильный. Хотим уметь получать скрипты не только из файлов, но и, например, из базы данных. В конце концов хотим для проекта более удобный сайт и более хорошую документацию.

    Всегда кому-то чего-то не хватает) Здесь мы надеемся на запрос сообщества, чтобы правильно выстроить приоритеты. И на помощь сообщества, чтобы все реализовать

    В заключение

    Мы используем Balerter у себя уже довольно давно. Десятки скриптов стоят на страже нашего спокойствия. Надеюсь, эта работа станет полезна кому-то еще.

    И добро пожаловать с вашими Issue и PR.

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 19

      0

      Если у вас уже есть Prometheus, отчего не привести всю эту информацию в него и не написать правила для уведомления там? Бонусом получаются HA (на alertmanager), группировка для уведомлений, возможность потом спросить у Prometheus «что видел мониторинг в момент срабатывания правила». Для PostgreSQL точно есть экспортер, позволяющий произвольные запросы, для остальных баз он либо есть, либо тривиально пишется. И в эти экспортеры у вас уезжает только определение метрик, а смысл уведомления видно не в коде, который надо глазами разбирать сквозь boilerplate-код соединения с источниками данных, а в одном выражении с человекопонятными именами метрик (которые всё равно придумывать). Приёмники уведомлений ваяются так же через webhook какие угодно.

        0
        И когда вам надо написать алерт на какую-то бизнес-логику, причем на основе данных из более чем одного сервиса — тут и наступает описанный случай.
          0

          Я Вашу статью прочитал, а Вы мой комментарий — нет, это досадно. Бизнес-логика может быть хоть какой, и данные из этого множества баз это всё равно метрики, имеющие по отдельности свой смысл, который можно назвать прямо в имени метрики. Исключение составляют только вопросы типа «возьмём оттуда топ100 строк и отсюда топ100 строк и сравним как списки», но мне хотелось бы видеть пример осмысленного алерта с такой механикой. Подсчёт rps за период на сложность, по моему мнению, не тянет.

            0
            Прошу прощения, если ответил не на тот вопрос. Постараюсь привести пример: идем в кликхаус, берем данные за текущую минуту, берем данные за последний час, сравниваем дельту. Идем в постгрес, смотрим — какая дельта для какого клиента максимальная. Если превысили — алертим. Примерно так.
              0
              И что же тут сложного запихать эту дельту с помощью zabbix_sender в zabbix, а далее настроить там 50 оттенков любых алертов? На вскидку скрипт на bash в 10-15 строк + Несколько кликов мышкой в zabbix и все готово.

              Я могу ошибаться, но складывается впечатление, что Вы не осилили в полной мере хоть одну из систем мониторинга.
                0
                bash скрипт, котором мы сходили куда надо, взяли любые данные и как-то их сверили — справится с любой задачей, как мне кажется. Тут трудно спорить. И, конечно, я не гуру в, например, zabbix. Инструмент писался из наших потребностей — уметь в одном скрипте за один раз анализировать данные из разных источников, типа логов из Loki, метрик из Prometheus и данных из Postgres. И если zabbix это умеет и довольно легко сделать — чтож, это значит, что я этого не знал. Мне кажется, ничего страшного в этом нет. Ну или мы «не осилили», можно и так сказать, почему бы и нет)
                0
                Для этого пишется простой экспортер на %language_name%. Выше справедливо заметили, что смешивать сбор данных и алертинг на основе этих данных не очень удобно в сопровождении.
                  0
                  А что имеется ввиду под смешиванием сбора данных и алертинга? Я не очень уловил. Особенно если мы говорим в рамках задачи, где решение об алерте принимается на основе данных из более чем одного источника. Как вы видите такую систему? Мне правда интересно
                    0
                    Так, как это сделано в прометеусе — данные преобразуются в метрики (с помощью экспортеров), которые хранятся отдельно, и потом на основе них строятся алерты.

                    А как вы при сборе «на лету» будете смотреть исторические данные, особенно если источники данных эволюционировали со временем? Допустим, вы мониторите конверсию на основе данных из постгри, которые хранятся в табличке conversion_rate. Собирали эти данные 6 месяцев, а потом разработка решила переделать все на кликхаус и новые данные теперь хранятся в клике.
                    И теперь, чтобы построить какой-то сложный алерт (например, «сравни текущую конверсию с конверсией годом ранее и скажи если все плохо») вам придется городить какую-то адовую логику с кучей условий «если дата меньше такой-то — смотри в постгрю, иначе смотри в кликхаус» вместо того, чтобы работать с одной метрикой.
                      0
                      А, теперь я понял о чем речь. Да, конечно это все имеет смысл.
                        0
                        Мне все равно кажется, что не всегда так просто это сделать. Например, метрика (текущий RPS относительно исторического в N часов) — кто и где ее считать должен? А если для алерта мне еще надо взять данных из другого источника — допустимые лимиты какие-то?
          0
          Господи, ну почему на Lua? Я ничего не имею против Lua. Но как по мне порог вхождения в bash ниже, чем в Lua.
            0
            Легко встроить. Язык привычен для использования в качестве встраиваемого (ну, например, Tarantool). И, убежден, он в среднем сильно легче для изучения, чем баш) Хотя, разумеется, это индивидуально. Хотя, он, конечно, не без странных и, порой, раздражающих моментов
              0
              Просто в обиходе общения с ОС Linux чаще работаешь с Bash, нежели со специфичным Lua. Я вот к чему. Ну в этом и есть Open Source, а не заказная разработка. Каждый пишет как удобно ему и отдает на рассмотрение сообщества.
                0
                Справедливости ради — я баш скрипты не писал ни разу в жизни, так вот сложилось, только отдельные команды использовал, а вот на lua бывало пробовал себе awesome wm настроить (да и на днях очередную попытку сделал). Но я и не бекенд разработчик и не девопс, потому не релевантен в данном случае))
            0

            Если метрику сложно собрать имеющимися инструментами, а также дополнительно нужно обработать какой-то логикой — пишется свой Prometheus exporter который отдаст заветное 42. В подавляющем большинстве он примитивен. Аналогично решается задача кастомной метрикой в zabbix. IMHO прекрасный образовательный проект получился, практические применение выглядит не убедительно

              0
              Практически всегда какую-то задачу можно решить несколькими вариантами. Вариант, что вы описали, вполне возможно рабочий для примера, что я привел выше. Я, к сожалению (к счастью?) не очень близко знаком со всеми возможностями zabbix. И он, возможно, сумеет вытащить мне нужные данные из баз данных и других источников.
              Мне сейчас кажется, что проще выглядит путь — написать один скрипт (затем другой скрипт, затем править) для сконфигурированного Balerter, чем писать и вносить правки в prometheus exporter, затем надо обязательно иметь zabbix и править там. Я допускаю, что ошибаюсь, но пока мне кажется так.
                0

                Часто даже писать не нужно, "изучи инструмент с которым работаешь", есть убер комбайн telegraf, который превращает что угодно в метрики, позволяя дополнительно манипулировать данными. Корреляции, гистерезис, аномалии — все мимо без хранилища. Это не вопрос религии, это вопрос проектирования, архитектуры и ресурсов

              0
              очень похоже на errbot

              Only users with full accounts can post comments. Log in, please.