مراقبة تطبيقات C++: مقاييس وتنبيهات متقدمة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مراقبة تطبيقات C++: مقاييس متقدمة وإعداد التنبيهات

\n\n

في ظل الأنظمة عالية التحميل، لم تعد مراقبة تطبيقات C++ خيارًا بل أصبحت ضرورة. لم يعد جمع البيانات الأساسية عن وحدة المعالجة المركزية والذاكرة كافيًا لتقديم صورة كاملة. على المستوى المتقدم، يتطلب الأمر تتبع قوائم الانتظار الداخلية، ووقت تنفيذ الأقسام الحرجة، وعدد تسرب الموارد، وحتى حالة مجمعات الخيوط. في هذه المقالة، سنناقش كيفية تنظيم جمع المقاييس، وإعداد التنبيهات، ودمج تطبيق C++ مع أنظمة المراقبة الحديثة مثل Prometheus و Grafana.

\n\n

1. جمع المقاييس على مستوى التطبيق

\n\n

الخطوة الأولى نحو المراقبة المتقدمة هي دمج الأدوات مباشرة في الكود. بدلاً من العوامل الخارجية، نضيف عدادات ومخططات بيانية وأجهزة استشعار مباشرة في منطق الأعمال.

\n\n

لننظر إلى مثال باستخدام مكتبة Prometheus-CPP. لنفترض أن لدينا معالج طلبات HTTP، ونريد تتبع:

\n\n
    \n
  • عدد الطلبات المعالجة (عداد).
  • \n
  • وقت معالجة الطلب (مخطط بياني).
  • \n
  • عدد الأخطاء (عداد مع علامات).
  • \n
\n\n
#include <prometheus/counter.h>\n#include <prometheus/histogram.h>\n#include <prometheus/registry.h>\n\nusing namespace prometheus;\n\n// سجل المقاييس العام\nstd::shared_ptr<Registry> registry = std::make_shared<Registry>();\n\n// إنشاء عداد الطلبات\nauto& request_counter = BuildCounter()\n    .Name("http_requests_total")\n    .Help("Total number of HTTP requests")\n    .Register(*registry);\n\n// إنشاء مخطط بياني لوقت الاستجابة\nauto& request_duration = BuildHistogram()\n    .Name("http_request_duration_seconds")\n    .Help("Request duration in seconds")\n    .Register(*registry);\n\n// دالة معالجة الطلب\nvoid handle_request(const std::string& endpoint) {\n    auto start = std::chrono::high_resolution_clock::now();\n\n    // محاكاة المعالجة\n    std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 100));\n\n    auto end = std::chrono::high_resolution_clock::now();\n    std::chrono::duration<double> elapsed = end - start;\n\n    // تحديث المقاييس\n    request_counter.Increment();\n    request_duration.Observe(elapsed.count());\n}\n
\n\n

يسمح هذا النهج بالحصول على بيانات دقيقة حول أداء كل نقطة نهاية، بدلاً من المؤشرات المتوسطة للنظام.

\n\n

2. مقاييس متقدمة: قوائم الانتظار، مجمعات الخيوط، والتسريبات

\n\n

لتطبيقات C++ عالية التحميل، من الضروري تتبع حالة الموارد الداخلية. لننظر إلى ثلاثة أنواع رئيسية من المقاييس:

\n\n

2.1. عمق قوائم انتظار الرسائل

\n

إذا كان التطبيق يستخدم قوائم انتظار المهام (مثلًا، بناءً على std::queue مع أقفال)، أضف مستشعرًا للحجم الحالي لقائمة الانتظار:

\n\n
#include <prometheus/gauge.h>\n\nauto& queue_size = BuildGauge()\n    .Name("task_queue_size")\n    .Help("Current number of tasks in queue")\n    .Register(*registry);\n\n// في كود المنتج/المستهلك\nvoid push_task(Task t) {\n    std::lock_guard<std::mutex> lock(mutex);\n    queue.push(t);\n    queue_size.Set(queue.size()); // تحديث المقياس\n}\n
\n\n

2.2. حالة مجمع الخيوط

\n

تتبع عدد الخيوط النشطة والمنتظرة والمحظورة. يمكن استخدام std::thread::hardware_concurrency() وعدادات مخصصة:

\n\n
auto& threads_active = BuildGauge()\n    .Name("thread_pool_active_threads")\n    .Help("Number of currently active threads")\n    .Register(*registry);\n\n// عند بدء/إنهاء المهمة\nthreads_active.Set(active_thread_count);\n
\n\n

2.3. تسرب الموارد (المقابض، الذاكرة)

\n

من خلال اعتراض new/delete أو استخدام مخصصات الذاكرة، يمكن تتبع عدد الكائنات الحية من نوع معين:

\n\n
auto& live_connection                

المدونات

توصيات الكتب