引言:为什么C++应用程序监控对稳定性至关重要?
现代C++应用程序运行在高负载环境中:游戏服务器、金融系统、物联网设备和嵌入式解决方案。没有适当的监控,即使编写完美的代码也可能导致灾难性后果——从内存泄漏到凌晨3点服务完全崩溃。在本文中,我们将探讨如何配置完整的C++应用程序监控:收集哪些指标,如何组织日志记录以及如何设置警报,以便高枕无忧。
1. C++应用程序的关键指标
C++应用程序监控始于选择正确的指标。我们将它们分为三组:
1.1. 系统级指标
- CPU Usage — 处理器占用百分比以及用户/内核模式时间。
- Memory Usage — 常驻内存大小、虚拟内存、缺页错误次数。
- Disk I/O — 磁盘读写操作(对数据库尤其重要)。
- Network I/O — 发送/接收字节数,错误次数。
1.2. 应用级指标
- Request latency — 请求处理时间(p50, p95, p99)。
- Throughput — 每秒处理的请求数。
- Error rate — 错误百分比(异常、超时)。
- Connection pool — 活动/等待连接数。
1.3. C++运行时指标
- Memory allocation — new/delete调用次数,堆内存分配。
- Thread count — 活动线程数,死锁检测。
- Object pool utilization — 对象池中已占用对象的百分比。
通过Prometheus C++客户端导出指标的示例:
#include <prometheus/exposer.h>#include <prometheus/registry.h>#include <prometheus/counter.h>#include <prometheus/gauge.h>
using namespace prometheus;
int main() { // 创建指标HTTP服务器 Exposer exposer{"0.0.0.0:8080"}; auto registry = std::make_shared<Registry>();
// 请求计数器 auto& request_counter = BuildCounter() .Name("http_requests_total") .Help("Total number of HTTP requests") .Register(*registry);
// 当前线程数的Gauge auto& thread_gauge = BuildGauge() .Name("app_thread_count") .Help("Current number of active threads") .Register(*registry);
// 注册指标 exposer.RegisterCollectable(registry);
// 模拟应用程序运行 while (true) { request_counter.Increment(); thread_gauge.Set(5.0); // 示例值 std::this_thread::sleep_for(std::chrono::seconds(1)); }}2. 指标收集工具:Prometheus和Grafana
在C++生态系统中,收集指标的事实标准是Prometheus配合Grafana。Prometheus是一个拉取系统:您的应用程序通过HTTP提供指标,Prometheus按设定的时间间隔自行抓取。
2.1. 在C++中配置指标导出
流行的库:
- prometheus-cpp(官方Prometheus C++客户端)。
- opentelemetry-cpp — 用于追踪和指标(更现代)。
- NanoMsg + custom exporter — 用于嵌入式系统。
与Prometheus-cpp集成的示例(完整代码如上)。启动后检查端点:
curl http://localhost:8080/metrics
# HELP http_requests_total Total number of HTTP requests# TYPE http_requests_total counterhttp_reques