Prometheus وGrafana

PromQL للأسئلة الحقيقية

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

PromQL للأسئلة الحقيقية

قدّم الدرس السابق صياغة PromQL ومشغّلاتها بشكل منعزل. هذا الدرس مختلف: يبدأ من الأسئلة التي يطرحها مهندس الاستجابة للحوادث أو مهندس SRE فعلياً أثناء حادثة أو مراجعة سعة، ثم يعرض صياغة PromQL الدقيقة التي تجيب عنها. الأنماط الثلاثة المغطاة هنا — نسب الأخطاء، وكميّات مئينية (percentiles) للكمون من المدرّجات التكرارية، واستعلامات السعة والإشباع — تمثّل قرابة 80 % من لوحات التحكم وقواعد التنبيه التي ستكتبها في بيئة الإنتاج. أتقن هذه الأنماط وستتمكن من بناء أي استعلام مراقبة تحتاجه.

النمط الأول: نسب الأخطاء

أكثر مستهدفات مستوى الخدمة (SLO) شيوعاً في شركات مثل Google وNetflix وAmazon هي مستهدف معدل الأخطاء: مثلاً "يجب أن ينجح 99.9 % من الطلبات." تعرض Prometheus أعداد الطلبات عبر عدّاد، وعادةً يُسمى http_requests_total مع بطاقات كـstatus وjob وhandler. لحساب نسبة الأخطاء تحتاج إلى معدلَي تغيير — معدل الأخطاء خلال النافذة الزمنية ومعدل إجمالي الطلبات خلال النافذة ذاتها — ثم تقسيمهما.

# نسبة الأخطاء خلال 5 دقائق لكل job (القيم 0-1؛ اضرب × 100 للحصول على نسبة مئوية) sum by (job) (rate(http_requests_total{status=~"5.."}[5m])) / sum by (job) (rate(http_requests_total[5m])) # معدل الاحتراق من الميزانية (burn-rate): ما مدى سرعة استنزاف ميزانية الأخطاء؟ # ميزانية الأخطاء = 1 - هدف SLO (مثلاً 0.001 لـ 99.9%) # معدل الاحتراق > 1 يعني أنك ستنفد الميزانية قبل نهاية النافذة الزمنية. ( sum(rate(http_requests_total{status=~"5.."}[1h])) / sum(rate(http_requests_total[1h])) ) / 0.001
يستخدم مطابق البطاقة =~"5.." تعبيراً نمطياً RE2. يطابق أي سلسلة حالة يبدأ أول حرف فيها بـ5 — وهو ما يشمل 500 و503 و504 وغيرها — دون الحاجة إلى سرد كل رمز. هذا هو النمط المعياري لأخطاء خادم HTTP في Prometheus.

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

# نسبة أخطاء قوية — ترجع 0 (وليس "لا بيانات") حين تكون الأخطاء صفراً ( sum by (job) (rate(http_requests_total{status=~"5.."}[5m])) or (sum by (job) (rate(http_requests_total[5m])) * 0) ) / sum by (job) (rate(http_requests_total[5m]))

النمط الثاني: كمون p95 من المدرّجات التكرارية

مقياس المدرّج التكراري (histogram) — مثل http_request_duration_seconds — هو في الواقع ثلاث عائلات مقاييس في آنٍ واحد: _bucket (الأعداد التراكمية لكل حد le مضبوط)، و_sum (المجموع الكلي لجميع القيم المرصودة)، و_count (إجمالي عدد القياسات). متوسط الكمون هو ببساطة _sum / _count، لكن المتوسطات تخفي كمون الذيل (tail latency) تماماً. في الإنتاج تحتاج إلى مئينيات.

تقوم الدالة histogram_quantile(φ, le_buckets) باستيفاء (interpolate) المئين φ من حدود الحاويات. يحوّل تغليف سلاسل _bucket بـrate() العدّادات التراكمية إلى معدل تغيير لكل ثانية لكل حاوية، مما يتيح لـhistogram_quantile الإجابة عن "ما هو p95 خلال الخمس دقائق الماضية؟" بدلاً من "منذ بدء العملية؟"

# كمون p95 لكل job خلال آخر 5 دقائق histogram_quantile( 0.95, sum by (job, le) ( rate(http_request_duration_seconds_bucket[5m]) ) ) # كمون p99 مقسّم حسب handler (للوحات تحكم لكل endpoint) histogram_quantile( 0.99, sum by (handler, le) ( rate(http_request_duration_seconds_bucket[5m]) ) ) # متوسط الكمون (اعرضه دائماً جانب p95/p99 للمقارنة) sum by (job) (rate(http_request_duration_seconds_sum[5m])) / sum by (job) (rate(http_request_duration_seconds_count[5m]))
تغطية الحاويات هي كل شيء. لا تستطيع histogram_quantile سوى الاستيفاء داخل حد حاوية مضبوط. إذا كان p99 يساوي باستمرار أعلى حاوية مضبوطة (مثلاً le="10")، ترجع الدالة قيمة ذلك الحد تحديداً — لا الـ99 المئيني الحقيقي — وسيظهر مقيداً اصطناعياً في لوحات التحكم. دائماً اضبط حاويات تغطي توزيع الكمون الفعلي، مع +Inf لالتقاط ما تجاوزها. الحاويات الافتراضية في عميل Prometheus (.005 حتى 10 ثوانٍ) مناسبة لـAPIs الويب العامة؛ الخدمات الصغيرة عالية التردد غالباً ما تحتاج دقة أدق تحت المللي ثانية.

عند التجميع عبر نسخ متعددة (pods أو nodes)، استخدم دائماً sum by (job, le) قبل استدعاء histogram_quantile. حساب مئينيات لكل نسخة ثم حساب متوسطها — "متوسطة المئينيات" — خاطئ إحصائياً ويُقلّل باستمرار من كمون الذيل في أعباء العمل الواقعية.

histogram_quantile aggregation order WRONG — averaging percentiles Pod A _bucket rate(_bucket[5m]) Pod B _bucket rate(_bucket[5m]) histogram_quantile per pod then avg() WRONG p95 underestimates tail CORRECT — aggregate buckets first All Pods _bucket sum by(job, le) rate() histogram_quantile(0.95, aggregated buckets) CORRECT p95 true tail latency
جمّع دائماً حاويات جميع الـPods بـ sum by(job, le) قبل استدعاء histogram_quantile — لا تحسب متوسط مئينيات كل pod على حدة.

النمط الثالث: استعلامات السعة والإشباع

تُأطّر طريقة USE من Google (الاستخدام، الإشباع، الأخطاء) أسئلة السعة حول بُعدَين: ما مدى اقتراب المورد من حده الأقصى، وهل يُراكم بالفعل عملاً لا يستطيع مواكبته؟ تغطي الاستعلامات التالية أهم إشارات السعة في بيئة إنتاجية نموذجية تعمل بـnode_exporter وkube-state-metrics.

# استخدام CPU لكل node (0-1؛ تنبيه عند > 0.80 للحفاظ على هامش أمان) 1 - avg by (instance) ( rate(node_cpu_seconds_total{mode="idle"}[5m]) ) # استخدام الذاكرة لكل node 1 - ( node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes ) # استخدام القرص لكل نقطة تحميل (تنبيه قبل 85%) 1 - ( node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"} ) # Kubernetes: حاويات اقتربت من حد CPU (إشارة إشباع) sum by (namespace, pod, container) ( rate(container_cpu_usage_seconds_total{container!=""}[5m]) ) / sum by (namespace, pod, container) ( kube_pod_container_resource_limits{resource="cpu"} ) # إشباع I/O للقرص: عمق قائمة الانتظار الموزونة (قيم > 1.0 = إشباع كامل) rate(node_disk_io_time_weighted_seconds_total[5m])
توقّع السعة المتبقية. ادمج الاستخدام الحالي مع predict_linear() للتنبؤ بموعد نفاد المورد. الاستعلام التالي يتنبأ بعدد الثواني حتى امتلاء نظام الملفات بناءً على معدل نموه خلال 6 ساعات — مفيد جداً لاكتشاف تسرب بطيء قبل أن يصبح حادثة:

predict_linear(node_filesystem_avail_bytes[6h], 4 * 3600) < 0

نتيجة أقل من صفر تعني أن القرص متوقع امتلاؤه خلال 4 ساعات. اربط هذا بتنبيه مع جملة for لمدة 30 دقيقة لتصفية الارتفاعات العابرة.

الجمع بين الأنماط: لوحة التحكم للإشارات الذهبية

في الإنتاج، تعيش هذه الأنماط الثلاثة معاً في لوحة تحكم واحدة "للإشارات الذهبية" بأربعة صفوف: حركة المرور (إجمالي معدل الطلبات)، والأخطاء (نسبة الخطأ)، والكمون (مدرّجات p50/p95/p99)، والإشباع (CPU + ذاكرة + قرص). يجب أن تمتلك كل خدمة هذه اللوحة قبل دخولها الإنتاج. الاستعلامات أعلاه هي اللبنات البنائية؛ يأتي استعلام معدل احتراق SLO في طبقة التنبيه (الدرس 6) فوقها.

في شركات كـGoogle وSpotify، لوحة الإشارات الذهبية شرط مسبق لاستعداد الإطلاق. لا تستطيع الفرق اجتياز مراجعة الجاهزية الإنتاجية دون إثبات أن هذه الأربعة لوحات مُعبّأة وحدودها مضبوطة وأدلة تشغيل الاستجابة للحوادث تشير إليها. ابنِ هذه العادة مبكراً — إنها أعلى استثمار مراقبة بقيمة إنتاجية لكل ساعة هندسية.