Добрый день, читатели habr!


В первой заметке о posgres_exporter, я рассмотрел достаточно частный случай, при работе с новой, на тот момент фитчей, а именно возможностью мониторинга одним экспортером набора экземпляров и/или баз данных. И описал тот "букет" проблем с которыми при этом столкнулся и какие обходные решения применял, что бы это всё заработало.
И вот, 25 ноября, вышел очередной релиз postgres_exporter 0.8.0. В нём были решены проблемы описанные в предыдущей заметке, а также, что особо приятно, добавлен новый функционал.


Прошу под кат...


Для начала хотелось бы более подробно познакомить Вас с postgre_exporter и написать, своего рода, короткое руководство по быстрому старту. Пройдемся по основным пунктам:


  1. Переменные окружения и параметры запуска
  2. Что такое "метрики по-умолчанию"
  3. Как добавлять собственные метрики

Описание


postgres_exporter — утилита сбора метрик с экземпляров кластера СУБД PostgreSQL в формате доступном Prometheus, написанная на языке Go, имеет открытый исходный код и распространяется бесплатно.


Переменные окружения и аргументы командной строки


У postgres_exporter, как таковой, отсутствует конфигурационный файл и все параметры передаются в экспортер либо через переменные окружения, либо через аргументы командной строки. При этом, параметры подключения к СУБД возможно передать только через переменные окружения.


Переменные окружения


Как говорилось выше, переменные окружения можно разделить на две группы. Первые передают строку подключения, вторые — дублируют аргументы командной строки.


Начнем с первой группы. Эти переменные начинаются с префикса DATA_SOURCE_:


  • DATA_SOURCE_NAME — используется по-умолчанию. Позволяет записывать строку подключения как в формате ключ=значение, так и в виде URI и может содержать логин и пароль подключения.
    Допустимые варианты задания подключения к PostgreSQL:


    • postgresql://rolename@dbhost:dbport/datname?sslmode=disable;
    • postgresql://rolename:rolpass@dbhost:dbport?sslmode=disable&db=datname;
    • postgresql://rolename:rolpass@?sslmode=disable&dbname=database&host=dbhost&port=dbport;
    • postgresql://rolename:rolpass@?sslmode=disable&dbname=database&host=/tmp (подключение через UNIX-сокет, берется из unix_socket_directories экземпляра PostgreSQL);
    • host=dbhost port=dbport dbname=database user=rolename sslmode=disable;

    Если нужно подключаться к нескольким экземплярам (не допускается использование пробела после запятой):


    • postgresql://rolename@dbhost:dbport/datname?sslmode=disable,postgresql://rolename@dbhost:dbport/datname?sslmode=disable;
    • sslmode=disable dbname=postgres host=127.0.0.1 port=5434 user=postgres,sslmode=disable dbname=postgres port=5432 user=postgres.

  • DATA_SOURCE_URI — альтернативна DATA_SOURCE_NAME. Это вариант подойдет, только в случае, если предполагается подключение к одному экземпляру PostgreSQL).
    В переменной DATA_SOURCE_URI задается часть URI без логина и пароля, в виде "dbhost:dbport/dbname?key=value". Логин и пароль берутся из переменных окружения DATA_SOURCE_USER и DATA_SOURCE_PASS, либо из файлов DATA_SOURCE_USER_FILE DATA_SOURCE_PASS_FILE.
    Когда логин и пароль хранятся в файлах, их содержимое извлекается и пере присваивается переменным DATA_SOURCE_USER и DATA_SOURCE_PASS. Далее, в коде, все это собирается в полноценный URI вида: "postgresql://" + DATA_SOURCE_USER + ":" + DATA_SOURCE_PASS + "@" + DATA_SOURCE_URI
  • DATA_SOURCE_URI_FILE — тоже самое что и DATA_SOURCE_URI, только читается из файла;
  • DATA_SOURCE_USER — при использовании DATA_SOURCE_URI, задаёт имя пользователя для подключения к СУБД;
  • DATA_SOURCE_USER_FILE — тоже самое что и DATA_SOURCE_USER, только читается из файла;
  • DATA_SOURCE_PASS — при использовании DATA_SOURCE_URI, задаёт пароль пользователя для подключения к СУБД;
  • DATA_SOURCE_PASS_FILE — тоже самое что и DATA_SOURCE_PASS, только читается из файла;.

Во вторую группу входят переменные дублирующие аргументы. Т.е. при запуске у вас есть выбор, задать параметры работы приложения в виде переменных окружения, либо передать в качестве аргументов при запуске. Начинаются с префикса PG_EXPORTER_:


  • PG_EXPORTER_WEB_LISTEN_ADDRESS — задаёт адрес и порт, через который экспортер будет принимать запросы от Prometheus. По-умолчанию :9187;
  • PG_EXPORTER_WEB_TELEMETRY_PATH — путь по которому отдаются метрики. По-умолчанию /metrics;
  • PG_EXPORTER_DISABLE_DEFAULT_METRICS — отключает сбор метрики по-умолчанию. О том что это за метрики, будет ниже. Принимает значения только true или false. По-умолчанию false (сбор метрик разрешен);
  • PG_EXPORTER_DISABLE_SETTINGS_METRICS — отключает сбор метрик из представления pg_settings. О том что это за метрики, будет ниже. Принимает значения только true или false. По-умолчанию false (сбор метрик разрешен);
  • PG_EXPORTER_AUTO_DISCOVER_DATABASES — обнаруживает все БД экземпляра кластера для сбора их метрик. Принимает значения только true или false. По-умолчанию false (сбор метрик производится только в той БД которая была указана в парраметрах подключения);
  • PG_EXPORTER_EXCLUDE_DATABASES — исключает БД из списка баз по которым собираются метрики, если PG_EXPORTER_AUTO_DISCOVER_DATABASES=true. Представляет список имен БД разделенных запятой. По-умолчанию — пустая строка. ВАЖНО:
    • шаблоны template0 и template1 — не требуется исключать, так они отсекаются на стадии получения списка баз данных из pg_databases;
    • невозможно исключить базу данных указанную в URI.
  • PG_EXPORTER_EXTEND_QUERY_PATH — Путь к YAML-файлу, который содержит пользовательские запросы. Файл queries.yaml содержит примеры;
  • PG_EXPORTER_CONSTANT_LABELS — Метка (константа) добавляемая во все метрики. Записывается в виде списка пар метка=значение, разделенных запятой.

Аргументы командной строки


  • web.listen-address — тоже самое, что PG_EXPORTER_WEB_LISTEN_ADDRESS;
  • web.telemetry-path — тоже самое, что PG_EXPORTER_WEB_TELEMETRY_PATH;
  • disable-default-metrics — тоже самое, что PG_EXPORTER_DISABLE_DEFAULT_METRICS;
  • disable-settings-metrics — тоже самое, что PG_EXPORTER_DISABLE_SETTINGS_METRICS;
  • auto-discover-databases — тоже самое, что PG_EXPORTER_AUTO_DISCOVER_DATABASES;
  • exclude-databases — тоже самое, что PG_EXPORTER_EXCLUDE_DATABASES;
  • extend.query-path — тоже самое, что PG_EXPORTER_EXTEND_QUERY_PATH;
  • constantLabels — тоже самое, что PG_EXPORTER_CONSTANT_LABELS;
  • dumpmaps — Показывает внутреннее содержание карты метрик. Используется для отладки пользовательских запросов. Не приводит к запуску приложения;
  • log.level — задает один из возможных уровней логирования: debug, info, warn, error, fatal;
  • log.format — задает способ и формат вывода журнала. Например: logger:syslog?appname=bob&local=7 или logger:stdout?json=true. По-умолчанию logger:stderr.

Метрики по-умолчанию


Метрики по-умолчанию — это некоторый набор метрик для мониторинга, сбор которых заложен непосредственно в коде. Сбор метрик по-умолчанию, можно отключить задав параметры командной строки --disable-default-metrics и/или --disable-settings-metrics или определив соответствующие переменные окружения.
Замечу, что в текущей версии была решена проблема использования метрик при включенном autoDiscovery, из-за которого, происходило дублирование метрик, что приводило к ошибкам.


По-умолчанию в мониторинг передаются метрики из следующих представлений:


  • pg_stat_bgwriter;
  • pg_stat_database;
  • pg_stat_database_conflicts;
  • pg_locks;
  • pg_stat_replication;
  • pg_stat_activity;
  • pg_settings.

Из того, на что стоит обратить внимание это pg_stat_replication и pg_stat_activity, так как набор возвращаемых полей зависит от версии PostgreSQL. Для этого, в экспортере производится проверка версии СУБД и выбирается соответствующий запрос. Указывать версию в пользовательских запросах, нельзя. Предполагается, что администратор заранее знает, какой версии, экземпляр будет мониторится. Так же могут возникнуть проблемы, если пытаться собирать метрики одним экспортером с экземпляров различных версий.
С метриками настроек экземпляра (pg_settings) всё несколько проще, они формируются запросом:


SELECT name, setting, COALESCE(unit, ''), short_desc, vartype
    FROM pg_settings
    WHERE vartype IN ('bool', 'integer', 'real');

Таким образом, по-умолчанию, формируется набор метрик только из численных значений.


Далее, рассмотрим вывод экспортера и в том числе разберёмся в том, почему захордкоженные метрики имеют своё право на существование. Для примера возьмем две метрики: shared_buffers и wal_sender_timeout. В выводе экспортера, на каждую метрику мы получаем три строки.
Первая строка — представляет подсказку и состоит из имени метрики в postgres_exporter, описания (колонка short_desc представления pg_settings) и если происходило приведение к базовому типу, указывается к какому именно (значение в квадратных скобках).
Во второй строке, указывается тип значения, в терминах Prometheus. И третья строка, метрика с набором меток и присвоенным значением.


Возвращаемые значения для shared_buffers.


# HELP pg_settings_shared_buffers_bytes Sets the number of shared memory buffers used by the server. [Units converted to bytes.]
# TYPE pg_settings_shared_buffers_bytes gauge
pg_settings_shared_buffers_bytes{server="127.0.0.1:5432"} 1.34217728e+08

pg_settings_shared_buffers_bytes — имя метрики. Оно, по правилам хорошего тона, составляется из имени таблицы, имени метрики и единицы измерения. Далее идет, короткое описание из таблицы pg_settings. И последнее, указание на то, что значении метрики было приведено к единице измерения байт (Units converted to bytes). Почему на последнее стоит обратить внимание, потому что непосредственно в базе значение выглядит несколько иначе, а именно:


      name      | setting | unit |                          short_desc                          
----------------+---------+------+--------------------------------------------------------------
 shared_buffers | 16384   | 8kB  | Sets the number of shared memory buffers used by the server.

Тип метрики у нас GAUGE, это значит она может принимать произвольные значения, в течении времени. В нашем случае количество буферов, при подстройке, может меняется в обе стороны.
О типах метрик и их отличиях, можно подробнее узнать в документации Prometheus.


Следующая метрика wal_sender_timeout. Информационные поля собираются по тому же принципу, что описан выше. Только в этом случае значение метрики приводится к секундам, а в базе хранится в миллисекундах. С этой особенностью нужно быть внимательными и учитывать при построении графиков.


# HELP pg_settings_wal_sender_timeout_seconds Sets the maximum time to wait for WAL replication. [Units converted to seconds.]
# TYPE pg_settings_wal_sender_timeout_seconds gauge
pg_settings_wal_sender_timeout_seconds{server="127.0.0.1:5432"} 60

Значение хранимое в базе данных:


demo=# SELECT name, setting, COALESCE(unit, ''), short_desc, vartype FROM pg_settings WHERE  name='wal_sender_timeout';
        name        | setting | coalesce |                     short_desc                     | vartype 
--------------------+---------+----------+----------------------------------------------------+---------
 wal_sender_timeout | 60000   | ms       | Sets the maximum time to wait for WAL replication. | integer

Все значения имеющие единицы измерения приводятся к двум типам: метрики объема к байтам; метрики времени к секундам.


Пользовательский набор метрик


В дополнение или взамен метрик по-умолчанию, можно использовать собственные. Для этого достаточно задать путь к файлу, с пользовательскими запросами, через аргумент --extend.query-path=query.yaml или через переменную окружения PG_EXPORTER_EXTEND_QUERY_PATH.
В репозитории проекта имеется YAML-файл с примерами: queries.yaml


Отмечу, что по сравнению с предыдущей версией, в 0.8.0 добавились новые ключи master и cache_seconds. На примере ниже разберем формат записи и назначение полей.


Пример содержимого файла queries.yaml


pg_database:
  query: "SELECT pg_database.datname, pg_database_size(pg_database.datname) as size_bytes FROM pg_database"
  master: true
  cache_seconds: 30
  metrics:
    - datname:
        usage: "LABEL"
        description: "Name of the database"
    - size_bytes:
        usage: "GAUGE"
        description: "Disk space used by the database"

Ключи и значения из примера выше:


  • pg_database — произвольный префикс метрик возвращаемых запросом (Обязательный);
  • query — содержит SQL-запрос (Обязательный);
  • master — выполнять запрос только в базе данных, указанной при подключении в URI (мастер-БД). Необходим при запуске экспортера с флагом --auto-discover-databases. Принимает значения true или false. По-умолчанию false. (Не обязательное);
  • cache_seconds — время, в течении которого будут возвращаться данные кэша. Задаётся в секундах;
  • metrics — содержит список меток и метрик;
  • datname, size_bytes — элемент списка. Имя элемента списка должно совпадать с именем колонки в запросе;
  • usage — тип значения. Принимает COUNTER, GAUGE, LABLE (подробнее в документации Prometheus)
  • description — Произвольное описание метрики

Пример возвращаемых метрик:


# HELP pg_database_size_bytes Disk space used by the database
# TYPE pg_database_size_bytes gauge
pg_database_size_bytes{datname="dbtest1",server="localhost:5432"} 1.0105503e+07
pg_database_size_bytes{datname="demo",server="localhost:5432"} 2.813719199e+09
pg_database_size_bytes{datname="postgres",server="localhost:5432"} 4.735491e+06
pg_database_size_bytes{datname="template0",server="localhost:5432"} 7.758339e+06
pg_database_size_bytes{datname="template1",server="localhost:5432"} 7.758339e+06

Резюме


Ну и резюмируем, все что мы имеем в последней версии postgres_exporter 0.8.0. В основном, все улучшения касаются работы мониторинга нескольких экземпляров и/или нескольких БД в экземпляре.


  • Аргумент exclude-databases (появился в 0.6.0) позволяет исключать базы данных из списка БД по которым будет производится сбор метрик. Но нельзя исключить БД которая указана в URI-подключения, так как она является мастер-базой;
  • Появилась возможность использовать пользовательские запросы к глобальным представления (pg_stat_activity, pg_stat_database и т.п.) вместе с аргументом auto-discover-databases. Для этого, было добавлено дополнительное поле master, указывающее на то, что запрос должен выполняться только в мастер-базе;
  • Появилась возможность использовать метрики по-умолчанию совместно с аргументом auto-discover-databases;
  • Для пользовательских запросов, было добавлено поле cache_seconds, позволяет задавать время (в секундах) на которое будет за кэширован ответ сервера на соответствующий запрос.

Источники


  • Prometheus [1] — это приложение с открытым исходным кодом, используемое для мониторинга событий и оповещения о них. Он записывает метрики в реальном времени в базу данных временных рядов, построенную с использованием модели HTTP-запроса, с гибкими запросами и оповещениями в режиме реального времени.
  • postgres_exporter — это экспортер метрик PostgreSQL для Prometheus.
    Версия, на момент написания заметки, v 0.5.1. Поддерживаемые версии PostgreSQL 9.4+ (но как показала практика, работает и на 9.3).

Комментарии (3)


  1. chemtech
    01.02.2020 16:20

    Спасибо за пост. Какой дашборд вы рекомендуете для использования совместно с postgres_exporter?


  1. sfalkongm Автор
    01.02.2020 19:51

    Спасибо.
    Я собирал собственный дашборд для Grafana, из того что есть, к сожалению, подходящего ничего не нашел. Тем более, это достаточно индивидуально, сильно зависит от того какие метрики для Вас ключевые


  1. IvanVakhrushev
    03.06.2021 13:52

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