Мониторинг приложений C++ с библиотекой metrics
При разработке высоконагруженных и критически важных систем на C++ невозможно обойтись без качественного мониторинга. Отслеживание производительности, обнаружение узких мест и оперативное реагирование на сбои — ключевые задачи DevOps и разработчиков. Библиотека metrics (известная также как cppmetrics) предоставляет лёгкий и эффективный способ сбора, агрегации и экспорта метрик прямо из кода C++.
В этой статье мы разберём основные возможности библиотеки, её архитектуру, покажем примеры использования и расскажем, как интегрировать её с системами сбора данных, такими как Prometheus.
Что такое библиотека metrics?
metrics — это header-only библиотека для C++ (C++11 и выше), которая реализует популярные типы метрик из Dropwizard Metrics (Java). Она включает:
- Счётчики (Counters) — для подсчёта событий (например, количество запросов).
- Датчики (Gauges) — для мгновенных значений (текущая загрузка CPU, размер очереди).
- Гистограммы (Histograms) — для анализа распределения значений (время ответа, размер пакета).
- Таймеры (Timers) — комбинация счётчика и гистограммы для измерения длительности операций.
- Метры (Meters) — измеряют скорость событий (запросов в секунду).
Библиотека поддерживает потокобезопасность, настраиваемые резервуары для сэмплирования (например, экспоненциально затухающие) и экспорт метрик в форматах JSON, Prometheus, Graphite.
Установка и подключение
Так как библиотека header-only, установка сводится к копированию заголовочных файлов в ваш проект. Можно использовать CMake FetchContent или просто скопировать папку metrics в include:
#include <metrics/metrics.hpp>
Для работы с Prometheus потребуется также установить prometheus-cpp (опционально).
Пример использования: базовые метрики
Рассмотрим простой HTTP-сервер, который считает количество запросов и измеряет время их обработки.
#include <metrics/metrics.hpp>
#include <iostream>
#include <thread>
#include <chrono>
using namespace metrics;
// Создаём реестр метрик
MetricsRegistry registry("my_app");
// Определяем счётчик и таймер
Counter& request_counter = registry.counter("http.requests.total");
Timer& request_timer = registry.timer("http.requests.duration");
void handle_request() {
auto context = request_timer.create_context(); // старт таймера
request_counter.increment(); // увеличиваем счётчик
// Имитация обработки
std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 100));
// Автоматически фиксируем время при разрушении context
}
int main() {
for (int i = 0; i < 100; ++i) {
handle_request();
}
// Вывод метрик в консоль (JSON)
std::cout << registry.report_json() << std::endl;
return 0;
}
В результате вы получите JSON со счётчиком, 50-м, 75-м, 95-м и 99-м перцентилями времени обработки.
Экспорт метрик в Prometheus
Для интеграции с Prometheus библиотека предоставляет отдельный модуль metrics_prometheus. Пример настройки эндпоинта:
#include <metrics/metrics.hpp>
#include <metrics/prometheus/prometheus_collector.hpp>
#include <metrics/prometheus/prometheus_server.hpp>
using namespace metrics;
int main() {
MetricsRegistry registry("my_service");
// ... регистрация метрик ...
// Создаём HTTP-сервер на порту 8080
PrometheusServer server(registry, 8080);
server.start();
std::cout << "Prometheus metrics available at http://localhost:8080/metrics" << std::endl;
std::this_thread::sleep_for(std::chrono::hours(1));
return 0;
}
Теперь Prometheus сможет забирать метрики в формате text/plain с эндпоинта /metrics.
Продвинутые возможности
- Кастомные резервуары — можно задать свой алгоритм сэмплирования (например, скользящее окно).
- Теги (labels) — поддержка тегов для разбивки метрик по измерениям (метод, статус, регион). <