مراقبة تطبيقات C++: مقاييس وتنبيهات متقدمة
في التطوير الحديث للأنظمة عالية التحميل بلغة C++، لا يكفي مجرد كتابة كود فعال. لضمان الاستقرار والأداء في بيئة الإنتاج، من الضروري تنفيذ نظام مراقبة متكامل. على المستوى المتقدم، لا يعني ذلك فقط جمع المقاييس الأساسية (CPU، الذاكرة)، بل يشمل أيضًا إنشاء مقاييس أعمال مخصصة، وإعداد تنبيهات ذكية، والتكامل مع أنظمة المراقبة (observability). في هذه المقالة، سنشرح كيفية بناء مراقبة جاهزة للإنتاج لتطبيقات C++ باستخدام Prometheus وGrafana والمقاييس المخصصة.
1. أساسيات المراقبة المتقدمة لـ C++
لماذا لا تكفي المراقبة الأساسية؟ الأدوات التقليدية (htop, perf) تظهر الحمل العام، لكنها لا تعطي فهمًا للحالة الداخلية لتطبيق C++ الخاص بك. تتضمن المراقبة المتقدمة:
- مقاييس الأعمال — عدد الطلبات المعالجة، وقت الاستجابة، حجم قائمة الانتظار.
- مقاييس الأداء — تأخيرات التخصيص، وقت حظر الميوتكس، عدد مرات فقدان الذاكرة المؤقتة (cache misses).
- مقاييس الموارد — تسرب الذاكرة (من خلال عد الكائنات النشطة)، عدد واصفات الملفات المفتوحة.
- تنبيهات ذات عتبات — ليس فقط "CPU > 90%"، بل "p99 latency > 500ms لمدة 5 دقائق".
للتنفيذ، سنحتاج إلى مكتبة prometheus-cpp — عميل لتصدير المقاييس بتنسيق Prometheus. تتيح لك إنشاء العدادات (Counter) والرسوم البيانية (Histogram) وأجهزة القياس (Gauge).
2. دمج عميل Prometheus في تطبيق C++
لننظر إلى مثال لتوصيل وإعداد المقاييس. سنقوم بتثبيت المكتبة عبر vcpkg أو Conan:
# مثال للتثبيت عبر vcpkgvcpkg install prometheus-cppالآن سنكتب فئة أساسية لتصدير المقاييس عبر نقطة نهاية HTTP (عادةً /metrics):
#include <prometheus/exposer.h>#include <prometheus/registry.h>#include <prometheus/counter.h>#include <prometheus/histogram.h>#include <prometheus/gauge.h>
class MetricsExporter {public: MetricsExporter(const std::string& address = "0.0.0.0:8080") : exposer_(address) { registry_ = std::make_shared<prometheus::Registry>(); exposer_.RegisterCollectable(registry_); initMetrics(); }
private: void initMetrics() { // عداد الطلبات auto& counter_family = prometheus::BuildCounter() .Name("http_requests_total") .Help("Total number of HTTP requests") .Register(*registry_); requests_counter_ = &counter_family.Add({{"endpoint", "/api/v1"}});
// رسم بياني لوقت المعالجة auto& histogram_family = prometheus::BuildHistogram() .Name("http_request_duration_seconds") .Help("Request duration in seconds") .Register(*registry_); request_duration_ = &histogram_family.Add( {{"endpoint", "/api/v1"}}, prometheus::Histogram::BucketBoundaries{0.01, 0.05, 0.1, 0.5, 1.0, 2.0} ); }
prometheus::Exposer exposer_; std::shared_ptr<prometheus::Registry> registry_; prometheus::Counter* requests_counter_; prometheus::Histogram* request_duration_;};في كود الإنتاج، ستقوم باستدعاء requests_counter_->Increment() عند كل طلب وتحديث الرسم البياني عبر request_duration_->Observe(latency_seconds). سيعطيك هذا بيانات حقيقية عن الحمل.
3. جمع المقاييس المتقدمة: من التسربات إلى الأداء
الآن سنضيف مقاييس مخصصة خاصة بـ C++. على سبيل المثال، تتبع عدد الكائنات النشطة في تجمع الذاكرة:
#include <atomic>#include &l