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, используя входящий веб-перехватчик.

Вот список всех библиотек, которые я буду использовать для этого:

Примечание. Поскольку это пример, я не буду вдаваться в подробности дизайна, и это не относится к производственному качеству.

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

Сюда входят cmd, config и внутренние каталоги, а затем файлы go.mod и go.sum. Каталог cmd включает точку входа приложения, которое обрабатывает создание службы и завершение работы. Внутренний файл / example / server / server.go настроит зависимости и соединит приложение вместе, а внутренний / процессы / оценщик / оценщик.go обрабатывает запуск рабочего пула с настроенным набором правил.

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

Конфиг находится в yaml, я просто опустил хосты для Slack и Prometheus:

И, наконец, вот пример выполнения с выводом в Slack!

Вот и все, полный исходный код можно найти на моем GitHub.

Резюме

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

Prometheus - очень универсальный инструмент в стеке наблюдаемости, но его также можно использовать для оптимизации или анализа ваших приложений и систем. Спасибо за чтение!