Prometheus метрики в C++: библиотека prometheus-cpp
В современной разработке программного обеспечения мониторинг стал неотъемлемой частью production-систем. Prometheus — одно из самых популярных решений для сбора и анализа метрик. Если вы пишете на C++ и хотите добавить мониторинг в своё приложение, библиотека prometheus-cpp — это то, что вам нужно. Она предоставляет полную поддержку типов метрик Prometheus и позволяет легко экспортировать их через HTTP.
Что такое prometheus-cpp?
prometheus-cpp — это клиентская библиотека для C++, которая реализует протокол экспорта метрик Prometheus. Она поддерживает все основные типы метрик: Counter, Gauge, Histogram и Summary. Библиотека написана на современном C++ (C++11 и выше), не имеет внешних зависимостей (кроме стандартной библиотеки и libcurl для HTTP-сервера) и активно поддерживается сообществом.
Установка
Самый простой способ установки — через vcpkg или Conan. Для vcpkg выполните:
vcpkg install prometheus-cpp
Если вы предпочитаете собирать вручную, клонируйте репозиторий и используйте CMake:
git clone https://github.com/jupp0r/prometheus-cpp.git
cd prometheus-cpp
mkdir build && cd build
cmake ..
make -j4
sudo make install
Основные концепции
Библиотека строится вокруг следующих компонентов:
- Registry — реестр, который хранит все метрики приложения.
- Counter — счётчик, который только увеличивается (например, количество запросов).
- Gauge — значение, которое может как увеличиваться, так и уменьшаться (например, количество активных соединений).
- Histogram — гистограмма для измерения распределения значений (например, время ответа).
- Summary — квантильная оценка (похожа на гистограмму, но вычисляет точные перцентили).
Пример: создание Counter и Gauge
Рассмотрим простой пример — HTTP-сервер, который считает количество запросов и отслеживает количество активных соединений.
#include <prometheus/counter.h>
#include <prometheus/gauge.h>
#include <prometheus/registry.h>
#include <prometheus/exposer.h>
int main() {
// Создаём реестр метрик
auto registry = std::make_shared<prometheus::Registry>();
// Создаём семейство Counter
auto& counter_family = prometheus::BuildCounter()
.Name("http_requests_total")
.Help("Total number of HTTP requests")
.Register(*registry);
// Добавляем метку "method" со значением "GET"
auto& http_requests = counter_family.Add({{"method", "GET"}});
// Создаём семейство Gauge
auto& gauge_family = prometheus::BuildGauge()
.Name("active_connections")
.Help("Number of active connections")
.Register(*registry);
auto& active_connections = gauge_family.Add({});
// Экспортируем метрики на порту 8080
prometheus::Exposer exposer("0.0.0.0:8080");
exposer.RegisterCollectable(registry);
// Имитация работы
while (true) {
http_requests.Increment(); // +1 к счётчику
active_connections.Set(42); // устанавливаем значение 42
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}
Пример: Histogram для времени ответа
Гистограммы полезны для замера латентности. Определим бакеты для времени ответа:
#include <prometheus/histogram.h>
// Создаём гистограмму с бакетами: 0.1, 0.5, 1.0, 2.5, 5.0 секунд
auto& histogram_family = prometheus::BuildHistogram()
.Name("http_request_duration_seconds")
.Help("Request latency in seconds")
.Register(*registry);
auto& request_duration = histogram_family.Add(
{{"handler", "/api/v1"}},
prometheus::Histogram::BucketBoundaries{0.1, 0.5, 1.0, 2.5, 5.0}
);
// При каждом запросе замеряем время и записываем
auto start = std::chrono::steady_clock::now();
// ... обработка запроса ...
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed = end - start;
request_duration.Observe(elapsed.count());
Экспорт метрик через HTTP
Для того чтобы Prometheus мог собирать метрики, необходимо запустить HTTP-сервер, который отдаёт их в текстовом формате. Библиотека предоставляет класс Exposer, который делает это автоматически. По умолчанию он слушает на указанном адресе
Также в библиотеке
GraphQL библиотека на C++: реализация API с помощью graphql-cpp
Работа с XML в C++: библиотеки pugixml, TinyXML-2 и RapidXML
TypeStack/class-validator для TypeScript: полное руководство с примерами
Генерация PDF в Java: обзор библиотек iText, Apache PDFBox, OpenPDF