Сегодня поговорим о сборе метрик
По аналогии с zabbix агентом у промитиуса имеются экспортеры
Для сервисов могут существовать разные варианты экспортеров
Мы же поставим один из самых распространенных экспортеров общих метрик ОС Linux - node_exporter
Скачаем и распакуем бинарный файл node_exporter:
root@serv:/tmp# cd /opt/
root@serv:/opt# wget https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-amd64.tar.gz
root@serv:/opt# tar zxf node_exporter-1.1.2.linux-amd64.tar.gz
root@serv:/opt# mv node_exporter-1.1.2.linux-amd64 node_exporter
Можно включать или отключать коллекторы(опционал) при старте например для метрик cpu или filesystem
Список коллекторов - индивидуальная черта экспортера node_exporter, в других экспортерах данных опций может и не быть Список всех коллекторов есть на официальной страничке GitHub: https://github.com/prometheus/node_exporter Используя параметры запуска можно включать или отключать данные коллекторы:
root@serv:/opt/node_exporter# ./node_exporter --help 2>&1 | grep collector ... --collector.cpu Enable the cpu collector (default: enabled). ... --collector.filesystem Enable the filesystem collector (default: enabled). ...
Существуют и параметры для запуска:
--web.listen-address=":9100" - адрес и порт node_exporter для входящих подключений
--web.telemetry-path="/metrics" - URL, по которому будут доступны метрики
--web.max-requests - максимальное кол-во одновременных запросов получения метрик
--web.config="" - экспериментальная опция, принимает путь конфигурации web.config с настройками TLS
Простейший запуск без параметров:
root@serv:/opt/node_exporter# ./node_exporter
Пример конфигурационного файла для демона systemd:
root@serv:/opt/node_exporter# cat /etc/systemd/system/node_exporter.service [Unit] Description=Node Exporter Wants=network-online.target After=network-online.target
Не рекомендуется запускать node_exporter в докере т.к. ему требуется доступ к основной ОС для получения метрик
Потребуется смонтировать все файловые системы внутрь докер контейнера
Лучше и проще запустить его в виде сервиса
После старта node_exporter начинает собирать данные ОС, используя виртуальные системы /proc и /sys
Вывести список отдаваемых метрик экспортером:
root@serv:~# curl localhost:9100/metrics ... # TYPE node_disk_reads_completed_total counter node_disk_reads_completed_total{device="vda"} 325190 ...
Пример выше - node_disk_reads_completed_total, которая показывает количество чтений с диска
Формат метрики:
metric_name{tag1="key1", tag2="key2"} num
metric_name - название метрики, можно использовать при запросах к prometheus
В фигурных скобках указываются теги (используются для фильтрации метрик) для конкретной метрики
num - текущее значение метрики
Указать серверу прометею на экспортер через файл /opt/prometheus/prometheus.yml: global: scrape_interval: 15s
scrape_interval - задает период опроса экспортеров Prometheus
Во секции scrape_configs - указываем цели для мониторинга
global - глобальная часть настроек
Рестарт для перечитывания конфига:
root@serv:/opt/prometheus# systemctl restart prometheus
Запрос к экспортеру с помощью promtool:
root@serv:~# ./promtool query instant http://localhost:9090 up
up{instance="localhost:9090", job="prometheus"} => 1 @[111.222]
up{instance="localhost:9100", job="node"} => 1 @[111.222]
Выше up - встроенная метрика для отображения статуса настроенных экспортеров
Теги - instance отвечает за адрес экспортера, имя задачи job из настроек Prometheus
В конце выводится последнее значение метрики и время, когда оно было получено
1 - экспортер доступен, 0 - экспортер недоступен
Задача node с адресом localhost:9100 и значением 1 т.е. Prometheus успешно подключился к экспортеру и собирает данные
Используйте PromQL для получения метрик и их фильтрации используя теги, примеры:
Когда Prometheus забирает метрики с экспортера то добавляет свои внутренние теги:
- instance (адрес экспортера)
- job (указано в конфигурации)
После этого финальная метрика записывается в TSDB
Добавьте к метрикам тег через env, назовем его - dev в /opt/prometheus/prometheus.yml: global: scrape_interval: 15s
Выше две метрики с различными тегами, в первой метрике добавился тег env="dev", во второй метрике данный тег отсутствует
Вторая метрика - старая, Prometheus получил ее до переконфигурации, но не удалил т.к. срок ее хранения не истек (15 дней)
Вывести только новую метрику через тег env:
root@serv:~# ./promtool query instant http://localhost:9090 'node_disk_reads_completed_total{env="dev"}'
node_disk_reads_completed_total{device="vda", env="dev", instance="localhost:9100", job="node"} => 325190 @[121526.40]
Вывести исторические данные, указав промежуток в квадратных скобках, пример - 5 минут:
root@serv:~# ./promtool query instant http://localhost:9090 'node_disk_reads_completed_total{env="dev"}[5m]'
node_disk_reads_completed_total{device="vda", env="dev", instance="localhost:9100", job="node"} =>
Основные параметры запуска:
-redis.addr=redis://localhost:6379 - адрес и порт Redis сервера
-web.listen-address - адрес прослушивания входящих подключений для Prometheus
-web.telemetry-path - url забрать метрики для Prometheus
Файл для сервиса:
Выше учетка prometheus ранее создавалась в части 1:
root@serv:/opt/prometheus# useradd -s /sbin/nologin -d /opt/prometheus prometheus
Перечитать демонов:
systemctl daemon-reload
Добавляем в автозапуск и стартуем:
systemctl enable redis_exporter
systemctl start redis_exporter
Проверим статус:
systemctl status redis_exporter
Указываем прометею на экспортера /etc/prometheus/prometheus.yml: global: scrape_interval: 15s
Рассмотрим на примере приложения языка go Оговорка, вдаваться в описание кода не буду, 42 строчки разобрать самостоятельно - легко
Установим последний стабильный релиз golang:
root@serv:~# wget https://golang.org/dl/go1.16.4.linux-amd64.tar.gz
root@serv:~# tar zxf go1.16.4.linux-amd64.tar.gz
Переменная GOROOT нужна golang интерпретатору чтоб находит путь к встроенным библиотекам
Переменная PATH необходима чтоб не писать полный путь к бинарнику go
Пропишите переменные окружения в .bashrc для учетки:
root@serv:~# echo 'export GOROOT=$HOME/go' >> .bashrc
root@serv:~# echo 'export PATH=$PATH:$GOROOT/bin' >> .bashrc
root@serv:~# go version
Создайте директорию проекта:
root@serv:~# mkdir -p app/src/app
root@serv:~# cd app/src/app
main.go:
Где, кратко:
main - отвечает за выполнение при старте программы, регистрирует подсчеты для прометея
handler - функция обработки запросов
apiDurations - метрика подсчета времени обработки запроса
apiProcessed - метрика подсчета количества входящих запросов
Мы хотим узнать сколько входящих запросов обрабатывает наше приложение и время обработки запросов
Для этого были подключены golang библиотеки Prometheus к приложению:
любой запрос вызывает функцию handler, которая засыпает рандомно до 3 секунд и выводит путь
метрики входящих запросов и времени обработки регистрируются для прометея
Компиляция и запуск
Создадим бинарный файл из исходного кода:
root@serv:~/app/src/app# export GOPATH=$HOME/app
root@serv:~/app/src/app# go mod init
root@serv:~/app/src/app# go get
root@serv:~/app/src/app# go build -o app main.go
Переменная GOPATH нужна компилятору чтоб найти файлы проекта
Параметр -o app - имя выходного файла
Параметр - main.go - имя файла с исходным кодом
Свяжем метрики приложения с прометем в prometheus.yml: global: scrape_interval: 15s
app_api_processed_ops_total = 2 - количество запросов отрботанных приложением
app_api_durations_seconds - время обработки запросов
Выводы
В большинстве случаев для вычленения проблем работы приложений необходимо мониторить:
время ответов
время обработки функций и запросов
Для других языков библиотеки подключаются аналогично примеру выше
Метрики по модели push
Выше мы настроили 3 варианта pull моделей, когда Prometheus ходит на экспортеры по http и собирает с них метрики
Если у нас есть непостоянно работающие приложения или задачи планировщика cron, то необходима уже push модель
Используйте экспортер - pushgateway, который принимает метрики и отдает их в Prometheus
Основные опции запуска:
--web.listen-address=":9091" - адрес для входящих подключений
--web.telemetry-path="/metrics" - путь метрик для Prometheus
--persistence.file="" - файл хранения полученных метрик, по умолчанию хранятся в памяти, исчезают при рестарте
--persistence.interval=5m - частота сохранения метрик в файл
Запуск с помощью docker:
root@serv:/opt# docker pull prom/pushgateway
root@serv:/opt# docker run -d -p 9091:9091 prom/pushgateway
Запуск как бинарник:
root@serv:/opt# wget https://github.com/prometheus/pushgateway/releases/download/v1.4.0/pushgateway-1.4.0.linux-amd64.tar.gz
root@serv:/opt# tar zxf pushgateway-1.4.0.linux-amd64.tar.gz
root@serv:/opt# mv pushgateway-1.4.0.linux-amd64 pushgateway && cd pushgateway
root@serv:/opt/pushgateway# ./pushgateway
Данные для запуска сервисом:
root@serv:/opt/pushgateway# cp ./pushgateway /usr/local/bin/
root@serv:/opt/pushgateway#useradd --no-create-home --shell /bin/false pushgateway
root@serv:/opt/pushgateway#chown pushgateway:pushgateway /usr/local/bin/pushgateway
Опишем файл сервиса vi /etc/systemd/system/pushgateway.service:
Включение и ребут:
systemctl daemon-reload
systemctl enable pushgateway --now
systemctl status pushgateway
Pushgateway имеет встроенный web-интерфейс (порт 9091 по умолчанию), однако рассмотрим примеры работы консолью
Выше были отправлены две метрики - test_metric_1 со значением 6 и test_metric_2 - со значением 12
Опция --data-binary - передает данные с помощью POST
url отправки - тут использован путь /metrics/job/test_metrics, где: job - label, test_metrics - значение
job - тэг из scrape_config в Prometheus
Отправить метрики с тэгами (в примере названия - dev и prod):
root@serv:/opt/pushgateway# cat <<EOF | curl --data-binary @- http://localhost:9091/metrics/job/test_metrics
test_metric_1{type="dev"} 3
test_metric_2{type="prod"} 6
EOF
Расширенный вариант отправки доп. параметров метрик с указанием типа передаваемой метрики:
root@serv:/opt/pushgateway# cat <<EOF | curl --data-binary @- http://localhost:9091/metrics/job/test_metrics
# TYPE test_metric_1 gauge
test_metric_1 15487
# TYPE test_metric_2 gauge
test_metric_2 238
EOF
Выше мы добавили новую метрику test_app_processed с тремя тегами:
Тег type=dep задан напрямую в метрике по аналогии выше
Два остальных тега заданы через URL: job=test_metrics и instance=localhost
Разделение нужно для того, чтоб можно было например удалять метрики не по одной, а сразу конкретной группы:
root@serv:/opt/pushgateway# echo 'test_metric_2{type="fire"} 100' | curl --data-binary @- http://localhost:9091/metrics/job/test_metrics/instance/localnet
Имеем две группы метрик:
job=test_metrics,instance=localhost
job=test_metrics,instance=localnet
Удалить все метрики группы (например localnet):
root@serv:/opt/pushgateway# curl -X DELETE http://localhost:9091/metrics/job/test_metrics/instance/localnet
Подключим pushgateway к Prometheus в prometheus.yml:
Параметр honor_labels: true запрещает Prometheus заменять переданные нами теги своими собственными:
По "классике": Prometheus собирает метрики, обращаясь по http к экспортеру на url /metrics
Забирает оттуда доступные метрики с тегами
После добавляет свои внутренние теги, указанные в конфигурации job_name и переданные
В pushgateway мы же теги выставляем самостоятельно