UPD: Заметка утратила свою актуальность, с выходом релиза 0.8.0. Со всеми нововведениями можно ознакомиться в статье: Новые возможности postgres_exporter для мониторинга PostgreSQL Добрый день, читатели habr! Prometheus и его экосистема экспортеров (агентов), является хорошим инструментом для любого администратора и разработчика. Простота доставки, простота (относительная) настройки, возможность использования сервиса автоматического обноружения.
Но речь пойдет не столько о Prometheus, сколько об одном из примечательных агентов, а именно о postgres_exporter. Он позволяет собирать метрики с PostgreSQL. Но если бы всё было так просто... К сожалению, документация у postgres_exporter достаточно аскетична и затрагивает только общие случаи. Но что делать, если вам достался экземпляр кластера СУБД с несколькими базами и/или вы хотите собирать метрики по нескольким экземплярам кластера сразу. Собственно, о цели статьи или скорее заметки. Сразу отмечу, что здесь я не буду описывать процессы сборки или настройки Prometheus и postgres_exporter, их взаимодействия. Всё это доступно описано в документации и во многих других источниках. Мне хотелось бы, затронуть некоторые частные случаи использования postgres_exporter, для решения конкретных задач, а именно сбор метрик одним агентом с: Субъективно, плюсы и минусы. Из плюсов: Из минусов: Ну что же, перейдем к практике. Предположим, что у нас имеется экземпляр PostgreSQL с несколькими базами данных и нужно организовать сбор метрик экземпляра и всех баз данных.
Почему я разделил сбор метрик баз данных и экземпляра кластера, всё очень просто, сценарий работы postgres_exporter с несколькими базами данных на одном кластере, подразумевает выполнение одного и того же набора sql-запросов в разных базах данных. И как следствие, при попытке получить метрики из представлений pg_stat_replication, pg_stat_activity, pg_stat_statement и т.п. являющимися общими для кластера, мы всегда получим, в понимании postgres_exporter, один и те же набор метрик который будет приводить к возникновению дублей ключей и значений, что приведет к ошибке.
Посмотрим как это выглядит на практике. Мы имеем тестовый экземпляр с набором баз данных: Запускаем postgres_exporter, с опцией --auto-discover-databases(если в строке подключения не указано имя базы данных, то подключение будет производится к базе данных с именем пользователя): В выводе агента, наблюдаем идиллическую картину, он запущен и смог подключиться ко всем базам данных в кластере (хоть он и не пишет к каким именно, но будем надеяться это исправят): Думаю внимательный читатель заметит, что баз у нас в кластере четыре (postgres, dbtest1, dbtest2 и dbtest3, template0 и template1 — игнорируются), а подключений установлено пять. В нашем случае, postgres_exporter создает два подключения к базе данных postgres. И с этой особенностью нужно быть очень внимательным. Почему? Об этом узнаем чуть дальше. Ну что же, продолжим и по пытаемся получить метрики: В результате, в выводе получаем предупреждения о дубликатах "was collected before with the same name and label values" (а вот в логе postgres_exporter мы предупреждений не увидим): Единственный способ избавится от ошибок, это отключить сбор метрик по-умолчанию. Это можно сделать двумя способами, первый установить переменные окружения PG_EXPORTER_DISABLE_DEFAULT_METRICS и PG_EXPORTER_DISABLE_SETTINGS_METRICS в true или использовать опции --disable-default-metrics и --disable-settings-metrics Перезапускаем postgres_exporter с дополнительными опциями: Пытаемся получить метрики: И вот, все прошло по плану, но в выводе нет ни одной метрики связанной с PostgreSQL: Далее, для того что бы получить полезную нагрузку, нам понадобится сформировать файл, описывающий какие метрики мы хотим получать (не забываем, мы можем собирать только метрики специфичные для баз данных). Для теста, будем собирать метрики из отношения pg_statio_user_tables. Для этого создадим файл queries.yaml, со следующим содержимым: Думаю тут необходимо пояснить один момент, а именно добавление имени базы данных, в которой выполняется запрос. Это обязательное требование, и на это есть как минимум две причины: И так, запускаем нашего агента с опцией --extend.query-path (здесь указывается путь к yaml-файлу с описанием метрик): Пытаемся получить метрики (для наглядности, возьмём только pg_statio_user_tables_heap_blks_hit): В результате, получаем однозначно интерпретируемый набор метрик: В итоге, мы получили возможность, используя опцию --auto-discover-databases, производить сбор метрик со всех баз данных одного экземпляра кластера. Приятным бонусом, может послужить то, что при добавлении новой базы данных не потребуется перезапускать агента.
Но при всем этом, мы остались без метрик экземпляра. Выход, на текущий момент, только один — использовать разных агентов для сбора метрик баз данных и экземпляра.
Выглядит конечно не очень, но данную неприятность возможно нивелировать группируя агентов для сбора метрик с нескольких экземпляров. Эту, еще одну, достаточно интересную возможность рассмотрим ниже. Помните, в начале, мы обратили внимание на "лишнее" подключение.Так вот, это особенность работы postgres_exporter с опцией --auto-discover-databases.
Но почему это может доставить много неприятностей? На самом деле все просто и уже описано выше, а именно проблема в том, что postgres_exporter будет собирать метрики с базы данных postgres дважды и начнет дублировать метрики. Помочь в нашем случае, сможет только появление опции --exclude-databases (так что ждем, с нетерпением, следующий релиз).
И да, если у вас в базе данных postgres будут пользовательские таблицы, то пример приведенный выше окажется нерабочим.  Ну что же, двигаемся дальше. Мы разобрались как получать метрики с нескольких баз данных, теперь рассмотрим вариант, как производить мониторинг, одним агентом нескольких экземпляров. Это очень просто, для этого достаточно перечислить их в переменной окружения DATA_SOURCE_NAME разделяя запятой: Здесь мы подключаемся к двум разным экземплярам кластера, запущенным, в нашем случае, на локальном узле. Вот как это выглядит в логах: Далее, пытаемся получить метрики (для наглядности ограничимся метрикой pg_stat_database_blk_read_time): В результате, с одного агента, получаем метрики по обоим экземплярам: В данном случае, все было несколько проще чем в случае с несколькими базами данных на одном экземпляре. При этом у нас сохранилась возможность получать глобальные метрики со всех экземпляров. И так, третий случай, указанный в целях является комбинацией двух описанных выше, поэтому приводить его не вижу смысла. В итоге, что же мы имеем в сухом остатке, postgres_exporter, на мой взгляд, достаточно интересный и перспективный инструмент администратора для мониторинга экземпляров кластера PostgreSQL и развернутых на них баз данных. Но в силу своего возраста, не лишенный недостатков, которые вполне можно понять и простить. Версия, на момент написания заметки, v 0.5.1. Поддерживаемые версии PostgreSQL 9.4+ (в исходном коде замечено ограничение версии 9.1+).