Prometheus - популярный инструмент мониторинга с открытым исходным кодом, который обеспечивает функциональность для отображения, запросов и предупреждений о данных временных рядов, собранных с различных целей. Как правило, он используется в сочетании с Grafana для визуализации и построения информационных панелей наблюдаемости, которые позволяют вам быстро понять состояние ваших систем.
Еще одна менее известная особенность заключается в том, что она также предоставляет модель pull, которая позволяет отправлять запросы PromQL через HTTP. Эта модель может использоваться как для доступа к историческим данным за определенный период времени, так и к текущим данным.
Используя эту модель, мы можем комбинировать ее с другими вещами, такими как механизм выражений, для создания сервисов или инструментов, которые можно использовать для решения ряда различных проблем. В этой статье я рассмотрю несколько примеров использования обоих по отдельности, а затем построю простую службу оценки выражений, написанную на Go.
Запрос Прометея
Давайте попробуем вытягивать HTTP-модель, отправив простой запрос к API с помощью curl. Если у вас нет доступа к экземпляру Prometheus, вы можете легко настроить его с помощью официальных инструкций Приступая к работе.
>> curl $HOST/api/v1/query?query=go_goroutines | jq . { "status": "success", "data": { "resultType": "vector", "result": [ { "metric": { "__name__": "go_goroutines", "endpoint": "https-metrics", "instance": "...", "job": "kubelet", "metrics_path": "/metrics", "namespace": "kube-system", "node": "...", "service": "example" }, "value": [ 1608777052.769, "291" ] } ] } }
Что касается API v1, ответом будет статус с типом результата и массивом, содержащим множество значений. Для этого конкретного запроса значения являются мгновенными векторами всех приложений, которые генерируют метрику go_goroutine, которая является метрикой по умолчанию в официальной клиентской библиотеке Go. Для службы с именем example она вернула значение 291 во время эпохи 1608777052.
Экспериментируя с кодом
Мы можем расширить пример curl и написать код, который будет принимать выражение и динамически оценивать его по результату ответа на запрос. Для этого мы можем использовать библиотеку Go под названием expr. Преимущество использования динамической оценки выражений заключается в том, что вы можете передавать свою бизнес-логику во время выполнения, обычно через конфигурацию. Это похоже на то, как работают правила Prometheus's Alert Manager.
Для начала рассмотрим простой пример использования expr и того, как его можно использовать для компиляции и выполнения выражения для деления двух переменных:
Expr также поддерживает логическую логику, настраиваемые или встроенные функции, настраиваемые операторы и многое другое. Теперь давайте взглянем на клиент Prometheus Go (та же библиотека, о которой говорилось ранее) и сделаем запрос:
Запросы к Prometheus довольно просты. Вы могли заметить, как было бы легко объединить их и создать приложение, которое позволит нам вводить правила для оценки.
Давайте сделаем это, проверив, когда сервис превышает определенное количество HTTP-запросов в секунду в течение определенного периода времени. В этом примере мы будем использовать настраиваемую метрику под названием http_request_duration_seconds, которая представляет собой гистограмму, которая также предоставляет количество запросов http_request_duration_seconds_count.
В этом примере полный запрос PromQL должен представлять собой агрегированную скорость, усредненную за определенный период времени, мы проверим среднюю скорость за 5 минут, укажем службу в селекторе меток и просуммируем по службе.
sum(rate(http_request_duration_seconds_count{service="example"}[5m])) by (service)
Для выражения мы укажем имя переменной как query_result, и мы проверим, больше или равно 100 запросов в секунду.
query_result >= 100
Теперь мы можем собрать пример процедурно в отдельной программе:
Замечательно, он будет выводить true или false в зависимости от того, превышает ли количество наших запросов в секунду 100.
Написание службы
Давайте продолжим, но встроим это в службу, которая отправляет сообщения в канал Slack. В нем будет рабочий пул, который запускает набор настроенных правил, которые запрашивают Prometheus, оценивают выражение, затем преобразуют результат в строку и, наконец, отправляют сообщение в канал Slack, используя входящий веб-перехватчик.
Вот список всех библиотек, которые я буду использовать для этого:
- Client_golang - Прометей
- Expr - движок выражения
- Гадюка - конфигурация
- Зеролог - логирование
- Errors - обработка ошибок
- Slack - slack API
Примечание. Поскольку это пример, я не буду вдаваться в подробности дизайна, и это не относится к производственному качеству.
Для начала структура сервиса соответствует макету проекта и включает только необходимые компоненты для локального запуска проекта.
Сюда входят cmd, config и внутренние каталоги, а затем файлы go.mod и go.sum. Каталог cmd включает точку входа приложения, которое обрабатывает создание службы и завершение работы. Внутренний файл / example / server / server.go настроит зависимости и соединит приложение вместе, а внутренний / процессы / оценщик / оценщик.go обрабатывает запуск рабочего пула с настроенным набором правил.
Он полностью зависит от конфигурации, и новые правила можно добавлять без перекомпиляции. Я создал два примера правил, один из которых получает среднее время сборки мусора за последние 30 минут и сравнивает его с последним днем для службы, а другой - общую память, используемую службой в настоящее время.
Конфиг находится в yaml, я просто опустил хосты для Slack и Prometheus:
И, наконец, вот пример выполнения с выводом в Slack!
Вот и все, полный исходный код можно найти на моем GitHub.
Резюме
Для этого существует множество вариантов использования, которые могут выйти за рамки бота Slack, один из которых я недавно использовал для автоматизации масштабирования базы данных с помощью управляемого продукта, не поддерживающего автомасштабирование.
Prometheus - очень универсальный инструмент в стеке наблюдаемости, но его также можно использовать для оптимизации или анализа ваших приложений и систем. Спасибо за чтение!