Мониторинг C++ приложений: метрики, алерты и лучшие практики

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Мониторинг C++ приложений: от сбора метрик до настройки алертов

Современные C++ приложения работают в высоконагруженных средах: от серверов баз данных до игровых движков и финансовых систем. Без мониторинга вы рискуете пропустить утечку памяти, падение производительности или критический сбой. В этой статье мы разберем, как организовать полноценный мониторинг C++ приложений: какие метрики собирать, как настроить алерты и какие инструменты использовать. Вы получите готовые примеры кода и практические советы.

1. Зачем нужен мониторинг C++ приложений?

Мониторинг — это не просто «посмотреть логи». Это система, которая позволяет:

  • Обнаруживать проблемы на ранней стадии — до того, как они повлияют на пользователей.
  • Анализировать производительность — CPU, память, диски, сеть.
  • Отслеживать бизнес-метрики — количество обработанных запросов, время ответа.
  • Автоматизировать оповещения — алерты при превышении порогов.

Без мониторинга вы работаете вслепую. Особенно это критично для C++ приложений, где ошибка может привести к segfault или неопределенному поведению.

2. Ключевые метрики для C++ приложений

Метрики делятся на три группы: системные, прикладные и бизнес-метрики. Рассмотрим каждую.

2.1 Системные метрики

Эти метрики показывают, как приложение использует ресурсы ОС:

  • CPU usage — загрузка процессора (user, system, idle).
  • Memory usage — RSS, VMS, утечки памяти.
  • Disk I/O — чтение/запись, задержки.
  • Network I/O — входящий/исходящий трафик, ошибки.
  • File descriptors — количество открытых файлов.

Пример сбора метрик через /proc/self/status (Linux):

#include <fstream>
#include <string>
#include <unordered_map>

std::unordered_map<std::string, std::string> parseProcStatus() {
    std::ifstream file("/proc/self/status");
    std::unordered_map<std::string, std::string> metrics;
    std::string line;
    while (std::getline(file, line)) {
        auto pos = line.find(':');
        if (pos != std::string::npos) {
            std::string key = line.substr(0, pos);
            std::string value = line.substr(pos + 2);
            metrics[key] = value;
        }
    }
    return metrics;
}

// Пример использования:
auto status = parseProcStatus();
std::cout << "VM size: " << status["VmSize"] << std::endl;

2.2 Прикладные метрики

Они специфичны для вашего приложения:

  • Время выполнения функций — замеры с помощью std::chrono.
  • Количество ошибок — исключения, возвращаемые коды.
  • Состояние потоков — количество активных/ожидающих потоков.
  • Размер очередей — например, очередь задач.

Пример замера времени:

#include <chrono>
#include <iostream>

class Timer {
    std::chrono::high_resolution_clock::time_point start;
public:
    Timer() : start(std::chrono::high_resolution_clock::now()) {}
    ~Timer() {
        auto end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
        std::cout << "Execution time: " << duration.count() << " us\n";
    }
};

void heavyFunction() {
    Timer t;
    // ... ваш код
}

2.3 Бизнес-метрики

Они отражают ценность для пользователя:

  • Количество обработанных запросов в секунду (RPS).
  • Время ответа (p50, p95, p99).
  • Количество активных сессий.
  • Процент успешных операций.

3. Инструменты для сбора и визуализации метрик

Для C++ приложений популярны следующие связки:

  • Prometheus + Grafana — стандарт де-факто. Prometheus собирает метрики, Grafana отображает.
  • InfluxDB + Telegraf — для временных рядов.
  • ELK Stack (Elasticsearch, Logstash, Kibana) — если нужен анализ логов.
  • OpenTelemetry — современный стандарт для трассировки и метрик.

Пример интеграции с Prometheus через HTTP-эндпоинт (используем библиотеку prometheus-cpp):

#include <prometheus/exposer.h>
#include <prometheus/registry.h>
#include <prometheus/counter.h>
#include <prometheus/gauge.h>

int main() {
    // Создаем HTTP-сервер на порту 8080
    prometheus::Exposer exposer("0.0.0.0:8080");

    // Создаем реестр метрик
    auto registry = std::make_shared<prometheus::Registry>();

    // Создаем счетчик запросов
    auto& counter_family = prometheus::BuildCounter()
        .Name("http_requests_total")
        .Help("Total number of HTTP requests")
        .Register(*registry);

    auto& counter = counter_family.Add({{"method", "GET"}, {"endpoint", "/api"}});

    // Создаем датчик памяти
    auto& gauge_family = prometheus::BuildGauge()
        .Name("memory_usage_bytes")
        .Help("Current memory usage")
        .Register(*registry);

    auto& gauge = gauge_family.Add({});

    // Регистрируем метрики
    exposer.RegisterCollectable(registry);

    // Имитация работы
    while (true) {
        counter.Increment();
        gauge.Set(1024 * 1024 * 256); // 256 MB
        std::this_thread::sleep_for(std::chrono::                

Блоги

Рекомендаций по книгам