Prometheus وGrafana

أنواع المقاييس وتنسيق العرض

18 دقيقة الدرس 2 من 32

أنواع المقاييس وتنسيق العرض

يُعرّف Prometheus أربعة أنواع أساسية من المقاييس، يُمثّل كل منها جانبًا مختلفًا من سلوك النظام. اختيار النوع الخاطئ هو أحد أكثر الأخطاء شيوعًا بين المستخدمين الجدد — فالمقياس المصنّف بشكل خاطئ ينتج نتائج استعلام خاطئة بصورة غير مباشرة، يصعب اكتشافها تحت ضغط الإنتاج. يغطي هذا الدرس ما هو كل نوع، ومتى يُستخدم، وكيف يعمل تنسيق الإرسال السلكي، وما الذي يتعطل عند الخطأ في الاختيار.

العداد (Counter)

العداد هو عدد صحيح أو عشري يزيد بشكل رتيب ولا ينخفض أبدًا (أو يُعاد ضبطه على الصفر عند إعادة تشغيل العملية). إنه الاختيار الصحيح لأي قياس يمثّل "الإجمالي منذ البداية": الطلبات المُخدَّمة، البايتات المُرسَلة، الأخطاء المُواجَهة، المهام المُكتملة.

القاعدة الحاسمة: لا تستخدم عدادًا لأي شيء يمكن أن ينخفض. عمق قائمة الانتظار الحالي ليس عدادًا. درجة حرارة المعالج ليست عدادًا. إذا وجدت نفسك بحاجة إلى طرح قراءتين للعداد، فأنت تستخدم النوع بشكل صحيح — فدالتا rate() وincrease() مصممتان تمامًا لذلك.

لماذا تُعاد ضبط العدادات: عند إعادة تشغيل عملية ما، يكتشف Prometheus إعادة الضبط بمراقبة قيمة scrape أقل من القيمة السابقة. تتعامل دوال مثل rate() تلقائيًا مع إعادة ضبط العدادات عن طريق تقسيم الفترة الزمنية وجمع المعدلات الجزئية. لهذا يجب ألا تستخدم delta() أو الطرح الخام على العداد — فهذه الدوال لا تتعامل مع عمليات الإعادة.

اتفاقية التسمية: تنتهي أسماء العدادات دائمًا بـ_total. على سبيل المثال: http_requests_total، process_cpu_seconds_total، rpc_errors_total.

المقياس (Gauge)

المقياس هو قيمة يمكن أن ترتفع وتنخفض بشكل اعتباطي. يمثّل لقطة من الحالة الحالية. أمثلة: الذاكرة المستخدمة، عدد goroutines، الاتصالات النشطة، درجة الحرارة الحالية، عمق قائمة الانتظار، نسبة الإصابة في الذاكرة المؤقتة، نسبة استخدام القرص.

تُستخدم المقاييس مع دوال مثل avg_over_time() وmax_over_time() والعمليات الحسابية البسيطة — لا حاجة للمعدل. كما أنها النوع الصحيح لقيم التهيئة وأرقام الإصدارات (عبر حيل التسمية) والحالة المنطقية المُرمَّزة كـ0/1.

نمط الإنتاج — إشارات التشبع: يُسمّي Google SRE الإشارات الذهبية الأربع التشبعَ إشارةً رئيسية. يجب أن يعرض كل مورد تمتلكه (المعالج، الذاكرة، مجموعة الخيوط، مجموعة الاتصالات، القرص) مقياسًا يُظهر الاستخدام الحالي كنسبة من السعة. التنبيه عتبيًا (gauge > 0.85) على هذه المقاييس هو الآلية الأكثر موثوقية للإنذار المبكر قبل أن ينضب المورد.

الرسم البياني التراكمي (Histogram)

الرسم البياني التراكمي يأخذ عينات من الملاحظات ويحسبها في مجموعات (buckets) قابلة للتهيئة. كما يتتبع إجمالي العدد المتراكم ومجموع جميع القيم المُلاحَظة، مما يتيح تقدير القيم المئوية بدقة وحساب المتوسط عبر تجميعات السلاسل الزمنية.

يُنشئ رسم بياني واحد باسم http_request_duration_seconds تلقائيًا ثلاث سلاسل معروضة:

  • http_request_duration_seconds_bucket{le="0.1"} — عدد الطلبات التي انتهت في ≤ 100 مللي ثانية
  • http_request_duration_seconds_count — العدد الإجمالي للملاحظات
  • http_request_duration_seconds_sum — مجموع جميع المدد المُلاحَظة

تسمية المجموعة le (أقل من أو يساوي) إلزامية. يُلحق Prometheus دائمًا مجموعة le="+Inf" تساوي _count. يستخدم تقدير القيم المئوية histogram_quantile()، التي تُجري استيفاءً خطيًا داخل المجموعة — تعتمد الدقة كليًا على توضع المجموعات بالنسبة لتوزيع بياناتك الفعلي.

سوء تهيئة المجموعات يؤدي إلى مؤشرات SLO مضللة: إذا كان مؤشر SLO هو "99% من الطلبات تحت 200 مللي ثانية" لكن مجموعات الرسم البياني هي [0.1, 0.5, 1.0, 5.0]، فإن أقرب حد للمجموعة هو 500 مللي ثانية. ستعيد histogram_quantile(0.99, ...) قيمة تتراوح بين 100 و500 مللي ثانية بناءً على الاستيفاء الخطي — وليس قياسًا لمكان حركة المرور الفعلية. على نطاق Google، أدى هذا إلى اعتقاد الفرق بأنها تلبي مؤشرات SLO للكمون بينما كانت تنتهكها فعليًا. ضع دائمًا حدَّي مجموعتين على الأقل ضمن نافذة مؤشر SLO.

توصيات المجموعات الافتراضية لكمون HTTP (.005، .01، .025، .05، .1، .25، .5، 1، 2.5، 5، 10 ثانية) تناسب خدمات الويب النموذجية. لاستدعاءات RPC الداخلية أو قواعد البيانات، أزح المجموعات بمقدار رتبة من الحجم إلى الأسفل. حدد المجموعات في أدوات القياس قبل أول نشر — تغييرها بأثر رجعي يكسر لوحات المعلومات الحالية وقواعد التسجيل.

الملخص (Summary)

الملخص أيضًا يأخذ عينات من الملاحظات لكنه يحسب القيم المئوية القابلة للتهيئة على جانب العميل خلال نافذة زمنية منزلقة. يعرض تسميات القيم المئوية المحسوبة مسبقًا مثل {quantile="0.99"} جنبًا إلى جنب مع _count و_sum.

المفاضلة الرئيسية مقارنةً بالرسوم البيانية التراكمية:

  • الملخصات دقيقة عند قيمة القيمة المئوية لكن لا يمكن تجميعها عبر الحالات المتعددة. يعمل sum(rate(...)) على _count و_sum، لكن لا يمكنك بمعنى إحصائي حساب متوسط سلاسل {quantile="0.99"} من 50 pod — النتيجة لا معنى لها إحصائيًا.
  • الرسوم البيانية التراكمية تقريبية (تستوفي داخل المجموعات) لكن قابلة للتجميع بالكامل. يمكنك استدعاء histogram_quantile() عبر المجموعات المدمجة من جميع الحالات للحصول على قيمة مئوية على مستوى الأسطول.
الإجماع الصناعي: لأي خدمة مصغرة تعمل على نسخ متعددة — وهي كل خدمة في الإنتاج — استخدم الرسوم البيانية التراكمية بدلًا من الملخصات. الملخصات أنسب للأدوات أحادية العملية (أدوات سطر الأوامر، المهام الدفعية) حيث تلزم قيم مئوية دقيقة على جانب العميل دون خلفية Prometheus. مكتبات العميل Go وJava تعتمد الرسوم البيانية التراكمية افتراضيًا لهذا السبب.

تنسيق العرض

يجمع Prometheus المقاييس عبر HTTP من نقطة نهاية /metrics. تنسيق الإرسال السلكي هو بروتوكول نصي بسيط سطر بسطر مُعرَّف في مواصفة OpenMetrics. تحتوي كل عائلة مقاييس على سطر HELP (وصف بشري) وإعلان TYPE، يعقبهما سطر بيانات واحد لكل سلسلة زمنية.

# HELP http_requests_total Total HTTP requests received since process start. # TYPE http_requests_total counter http_requests_total{method="GET",status="200"} 1027453 http_requests_total{method="GET",status="500"} 312 http_requests_total{method="POST",status="200"} 88921 # HELP http_request_duration_seconds HTTP request latency histogram. # TYPE http_request_duration_seconds histogram http_request_duration_seconds_bucket{handler="/api/v1/query",le="0.05"} 24054 http_request_duration_seconds_bucket{handler="/api/v1/query",le="0.1"} 33444 http_request_duration_seconds_bucket{handler="/api/v1/query",le="0.25"} 100392 http_request_duration_seconds_bucket{handler="/api/v1/query",le="+Inf"} 144320 http_request_duration_seconds_sum{handler="/api/v1/query"} 53423.147 http_request_duration_seconds_count{handler="/api/v1/query"} 144320 # HELP go_goroutines Number of goroutines currently running. # TYPE go_goroutines gauge go_goroutines 231

قواعد التنسيق الرئيسية: يجب أن تتطابق أسماء المقاييس مع [a-zA-Z_:][a-zA-Z0-9_:]*. قيم التسمية هي سلاسل UTF-8 بين علامتي اقتباس مزدوجتين؛ تُهرَّب الشرطات المائلة العكسية وعلامات الاقتباس المزدوجة الداخلية. يُلحق اختياريًا طابع زمني (Unix بالمللي ثانية) كحقل ثالث لكنه نادرًا ما يُستخدم — يتتبع Prometheus طابعه الزمني الخاص للـscrape. تبدأ سطور التعليقات بـ#؛ أي سطر آخر يبدأ بـ# غير صالح.

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

curl -s http://localhost:9090/metrics | grep -E '^(#|http_)' # For a remote target via port-forward (Kubernetes): kubectl port-forward svc/my-app 8080:8080 curl -s http://localhost:8080/metrics | grep 'TYPE\|HELP' | head -30
Prometheus metric types and their time-series shapes Prometheus Metric Types — Shapes Over Time Counter Monotonic · resets on restart Gauge Arbitrary up/down · snapshot Histogram le= .05 .5 Buckets · aggregatable p99 Summary p99 p90 p50 Client-side quantiles · single instance Text Exposition Format (wire protocol) # HELP http_requests_total Total HTTP requests since start. # TYPE http_requests_total counter http_requests_total{method="GET",status="200"} 1027453 [optional_timestamp_ms] Metric name Label set (key=value pairs) Sample value
أنواع مقاييس Prometheus الأربعة وتنسيق النص المُعرَض الذي يتشاركونه على نقطة نهاية /metrics.

أفضل ممارسات القياس على نطاق واسع

في Google وLyft والشركات المماثلة، عقد القياس جزء من واجهة برمجة الخدمة. بعض القواعد المكتسبة بصعوبة:

  • استخدم دائمًا الوحدات الأساسية: ثوانٍ، بايت، نسب (0–1). لا تستخدم المللي ثانية أو الميغابايت — يفترض PromQL وGrafana وحدات SI الأساسية، وخلطها يُنشئ أخطاء قياس في لوحات التحكم تُضيّع ساعات المناوبة.
  • تعدد قيم التسمية يقتل قاعدة بيانات السلاسل الزمنية: لا تستخدم معرّف المستخدم أو عنوان IP أو عنوان URL أو أي قيمة غير محدودة كتسمية. كل مجموعة تسمية فريدة تُنشئ سلسلة زمنية جديدة في TSDB الخاص بـPrometheus. خدمة بـ100,000 مستخدم تعرض {user_id=...} ستُسقط خادم Prometheus في غضون ساعات بنفاد الذاكرة. حدد تعدد التسميات بضع مئات من القيم المتميزة لكل تسمية.
  • اجعل أسماء المقاييس ذات بادئة بالنظام الفرعي: myservice_http_requests_total وليس requests_total. البادئة تبقى بعد اتحاد البيانات وخطوط الإرسال عن بُعد حيث تندمج المقاييس من خدمات عديدة.
  • اعرض مقياس معلومات البناء: المقياس myservice_build_info{version="1.4.2", commit="a3f91c"} 1 (دائمًا قيمته 1) يُتيح التنبيه الواعي بالإصدار وربط التراجع في لوحات التحكم دون الحاجة إلى استخراج السجلات.
اختبر تنسيق العرض محليًا: شغّل promtool check metrics < /path/to/metrics.txt قبل نشر أي قياس جديد. يكتشف هذا عدم تطابق الأنواع، وأسماء التسميات غير القانونية، وبادئات _total المفقودة على العدادات، وأخطاء ترتيب مجموعات الرسم البياني التراكمي — وكلها تُفسد نتائج الاستعلام بصمت في الإنتاج.