Собираем метрики приложения с Prometheus

PrometheusЕсть два концептуально разных подхода к сбору метрик приложения. Есть PUSH подход, при котором хранилище тихо сидит где-нибудь и надеется, что случайный провайдер метрик в него что-нибудь да положит. Например, Graphite сам по себе не занимается сбором данных. Он ждёт, что их доставит прямо к порогу кто-нибудь вроде collectd.

С другой стороны, есть PULL подход. В этом случае агрегатор начинает проявлять инициативу и раз в икс секунд проходится по списку адресов, на которые подписан, чтобы самостоятельно собрать новую порцию данных.

Prometheus использует PULL подход.

Кто такой Prometheus

Prometheus — это open source хранилище метрик, как и Graphite. Но, в отличие от Graphite, он сам добывает себе данные. Всё, что он успел насобирать, можно затем запросить встроенным языком запросов, или отрисовать встроенной рисовалкой графиков. Правда, последней я бы не советовал пользоваться. Даже создатели проекта рекомендуют использовать Grafana, и после первого же прометеевского шедевра я понял, почему. То еще творчество.

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

Установка

Prometheus можно добыть в виде архива с бинарниками, исходников на гитхабе, или образа для Docker. Как обычно, проще всего начать именно с Docker — docker run -p 9090:9090 prom/prometheus. Как только контейнер запущен, Prometheus можно будет открыть на 9090-м порту:

Jobs, targets, instances (и проблемы перевода с английского)

Prometheus нужно откуда-то собирать данные. Для этого у него есть список целей (targets) — URLs, по которым можно запросить метрики. Слушающий на другом конце URL процесс или приложение называется instance. Он должен уметь отвечать на запросы в понятном Prometheus формате, иначе магии не получится.

Что интересно, Prometheus умеет раздавать и свои метрики и поэтому является вполне валидной целью для другого Prometheus. Или даже для себя. На самом деле, по-умолчанию он так и сконфигурирован. Если зайти на его список целей по умолчанию —  http://localhost:9090/targets,то он там будет первым и единственным в списке:

/metrics - это стандартный путь для доступа к данным мониторинга приложения. Настолько стандартный, что в конфигурации его даже указывать не надо, Prometheus всё добавит сам.

В /prometheus/prometheus.yml, что, собственно, и есть конфигурация, появляется еще и концепция задач — jobs.

Задача — это коллекция однотипных целей. Например, если мы мониторим два сервиса — основной и его запасную копию, то их адреса пойдут в одну и ту же задачу.

Формат данных Prometheus

Посмотрим теперь, на что же похожи метрики, которые устроят Prometheus. Для этого можно посмотреть, какие метрики раздаёт он сам на /metrics:

Prometheus: metrics

А там много познавательного. Некоторые строки, например go_gc_duration_seconds_count 10, вполне знакомы. Первый компонент это, очевидно, имя метрики, а 10 — её значение. В отличие от rrdtool и Graphite, временной метки тут нет, так как Prometheus проставит её сам (но его можно отговорить и предоставить свою дату).

Но в большинстве строк еще встречается и непонятная ерунда в фигурных скобках, вроде такой: go_gc_duration_seconds{quantile="1"}. Оказывается, к любой паре метрика-значение можно добавить сколько угодно дополнительных атрибутов «ключ-значение». А те могут быть чем угодно. Например, можно передать имя хоста, с которого метрика собиралась, или дополнительные детали, вроде с какого процессора она снималась — {cpu='1'}, или к какому типу запроса относится — {method='POST'}, и так далее.

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

В довесок ко всему, для каждой цели Prometheus заводит два виртуальных ряда с данными. Один называется up и принимает значения 1 или 0. Единица, если цель еще живая и отвечает, и ноль, если уже всё. Второй ряд — scrape_duration_seconds — показывает, как долго длился запрос. Имея их на руках, очень удобно анализировать, насколько живая цель на данный момент.

Язык запросов

Как только у данных появляется больше чем одно измерение, приходится обзаводиться и языком запросов. У Prometheus такой есть, и он получился на удивление мощным. Так как разбор его инструкций не входит в сегодняшний план, я просто приведу пару примеров, чтобы показать, на что он вообще похож.

  1. Если указать имя ряда данных, вроде go_gc_duration_seconds, то это уже полноценный запрос, который возвращает все значения ряда.
  2. В фигурных скобках можно указать имена и значения атрибутов, например, collectd_cpu{cpu='0'}, что работает как фильтр. Если = заменить на =~, то в фильтре можно использовать регулярные выражения.
  3. С использованием функций и временных фильтров можно вообще творить чудеса. Например, следующий запрос вернет максимальное значение для CPU-0 за последнюю минуту: max_over_time(collectd_cpu{cpu='0'}[1m])

С запросами в Prometheus можно играть прямо из браузера на  localhost:9090/graph:

Сбор метрик

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

Во-первых, некоторые приложения уже умеют выдавать свои метрики в понятном Prometheus формате. Например, etcd и Kubernetes. Etcd, кстати, даже слушает входящие запросы на /metrics, так что подключать его к Prometheus вообще удовольствие.

Во-вторых, есть экспортёры для уймы остальных приложений. Экспортёр — это маленький вэб-сервер, который с одной стороны собирает метрики с приложения, а со второй — раздаёт их всем желающим по адресу /metrics. И таких экспортёров очень много, начиная от collectd, Apache и RabbitMQ и заканчивая вообще экзотическими вещами, вроде девелопмент платы Intel Edison.

Наконец, иногда Prometheus не может сделать прямой HTTP запрос к приложению. Может, оно за файрволом сидит, или слишком хрупкое, чтобы перенести еще один запрос. Но если приложение само может дать о себе знать, что есть pushgateway — посредник, который может принимать такие данные, и потом уже отдавать их Prometheus стандартным образом, через /metrics.

Prometheus: pushgateway

Создание графиков

На той же странице, которая выполняла запросы к данным, есть закладка под названием ‘Graph’, которая может эти данные отрисовать:

Prometheus: график

Правда, получается это у неё так себе.

Grafana, с другой стороны, знакома с Prometheus, и добавить его в качестве источника данных для её графиков можно запросто:

Grafana: Prometheus как источник данных

Заключение

Prometheus — это сборщик метрик приложения, который не будет ждать, когда ему подадут готовое, а сам пойдёт добывать себе данные. В отличие от rrdtool и Graphite, он понимает многомерные данные, что позволяет прикреплять метрике дополнительные сведения о ней: от типа запросов до идентификаторов пользователей.

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

Правда, отрисовка данных у Prometheus получается так себе. Но так как он отлично работает с Grafana, то не такая уж это и проблема.

5 комментариев для “Собираем метрики приложения с Prometheus

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *