المستوى المطلوب: مبتدئ. هذا المقال مناسب لو قابلت Prometheus لأول مرة، أو شغّال على مشروع فيه Grafana بس مش عارف تكتب استعلام أبعد من up. مش محتاج خبرة سابقة في time series databases، بس مفيد لو فاهم الفرق بين CPU و RAM وعارف يعني إيه HTTP 500.
لو Prometheus بيجمع metrics من 12 خدمة وانت بتفتح Grafana كل صباح وبتبص في رسم بياني واحد، انت بتدفع تخزين على بيانات مش بتستخدمها. الـ 8 استعلامات اللي قدامك بتحوّل Prometheus من "log عرضي" إلى نظام تحذير مبكر يكشف مشاكل الإنتاج قبل ما العميل يلاحظ.
المشكلة في غياب PromQL
Prometheus بيخزّن أرقام كل 15 ثانية لكل خدمة. CPU، الذاكرة، عدد الطلبات، زمن الاستجابة. المشكلة: البيانات الخام مش بتقولك "في مشكلة دلوقتي". انت محتاج تحوّلها لإجابات. PromQL هي اللغة اللي بتسأل بيها الأسئلة دي.
الفريق العادي اللي بيركّب Prometheus بيقعد أسابيع بيرسم رسومات جميلة بدون ما يعرف يجاوب على سؤال زي "كم نسبة الطلبات اللي رجعت 500 آخر 5 دقايق؟". الفرق بين فريق بيستعمل PromQL وفريق مش بيستعمله: الأول بيكتشف العطل في 90 ثانية، التاني بيكتشفه لما العميل يبعت تذكرة.
مثال للمبتدئ: PromQL زي طبيب الباطنة
تخيّل إنك دخلت لطبيب وقعدت قدامه بدون كلام. الطبيب مش هيعرف يكشف على إيه أصلاً. لكن لو قلتله "بطني بتوجعني من ساعة بعد الأكل"، الطبيب يعرف يدور بالظبط في الكبد والمعدة والمرارة، ويعمل أشعة محددة، ويرجّعك بإجابة في 15 دقيقة.
بعد المثال ده، التعريف العملي بسيط: Prometheus بيجمع الأشعة. Grafana بيعرضها على شاشة. PromQL هي السؤال اللي بتسأله للطبيب. بدون السؤال الصح، انت قاعد قدام رسومات وألوان من غير ما تعرف فيه إيه ولا فيه إيه.
التعريف العلمي لـ PromQL
PromQL (Prometheus Query Language) لغة استعلام functional بتشتغل على time series data. كل metric في Prometheus عبارة عن سلسلة من الأرقام مع timestamp و labels. PromQL بياخد السلاسل دي ويعمل عليها 4 عمليات أساسية: filtering بالـ labels، aggregation عبر الأبعاد، rate calculation على المدى الزمني، و arithmetic بين السلاسل.
على عكس SQL اللي بيرجّع جدول ثابت، PromQL بيرجّع instant vector (قيمة واحدة لكل سلسلة في لحظة معيّنة) أو range vector (قيم على مدى زمني). الفرق ده هيبقى مهم لما نشوف الأمثلة.
الـ 8 استعلامات اللي لازم تعرفها
1) هل الخدمة شغّالة؟
up{job="api-server"}
بيرجّع 1 لو Prometheus قدر يعمل scrape للخدمة، و0 لو لأ. لو طلع 0 على instance معيّن، الخدمة وقعت أو الـ scrape config مش صح. ده أبسط استعلام في PromQL وأهم alert لازم تركّبه.
2) كم عدد الطلبات في الثانية؟
rate(http_requests_total[5m])
الـ rate() بيحسب متوسط الزيادة في الـ counter لكل ثانية على آخر 5 دقايق. لو رجّع 142، يبقى الخدمة بتستقبل 142 طلب في الثانية. لاحظ إن الناتج رقم عشري، مش لازم يبقى integer.
3) كم نسبة الأخطاء؟
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
بيرجّع نسبة عشرية. لو رجّع 0.034، يعني 3.4% من الطلبات بترجع 5xx. أي رقم فوق 0.01 (1%) يستاهل تحقيق فوري. الـ regex 5.. بيغطي 500 و 502 و 503 و 504 في نفس الاستعلام.
4) كم زمن الاستجابة P95؟
histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le)
)
P95 معناه: 95% من الطلبات بترد في الزمن ده أو أسرع. لو رجّع 0.840، يعني 95% من الطلبات بترد في 840 مللي ثانية. الأرقام دي بتكشف الـ tail latency اللي المتوسط (average) بيخبّيها. خدمة المتوسط بتاعها 80ms ممكن يكون P95 بتاعها 1.4 ثانية، والـ 5% المتأخرين دول بيمثّلوا أكتر العملاء غضباً.
5) كم استخدام الـ CPU؟
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
بيرجّع نسبة استخدام الـ CPU كنسبة مئوية لكل instance. أي رقم فوق 80% على مدى أكتر من 10 دقايق إشارة لمشكلة. لاحظ إنه بيحسب 100 - idle لأن node_exporter بيقيس الوقت الفاضي مش الوقت المستخدم مباشرةً.
6) كم الذاكرة المستخدمة؟
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
نسبة الذاكرة المستخدمة على كل instance. Linux بيحسب الـ MemAvailable بحساب الـ caches القابلة للتحرير، فالرقم ده أدق من MemFree. لو استعملت MemFree هتلاقي السيرفر بيقولك إن الذاكرة 95% مستخدمة وهو لسه عنده 4 جيجا فاضية فعلاً.
7) كم Pod بيتعاد إنشاؤه؟
sum(rate(kube_pod_container_status_restarts_total[15m])) by (pod)
لو Pod بيتعاد إنشاؤه أكتر من مرة كل 15 دقيقة، فيه مشكلة. ممكن OOM kill، ممكن liveness probe بيفشل، ممكن الـ container بيقع لوحده. الاستعلام ده محتاج kube-state-metrics مركّب على الـ cluster.
8) كم disk space فاضل؟
(node_filesystem_avail_bytes{mountpoint="/"}
/
node_filesystem_size_bytes{mountpoint="/"}) * 100
نسبة المساحة الفاضلة على الـ root partition. تحت 15% إشارة لخطر، تحت 5% إنذار حرج. لو السيرفر امتلأ، الـ logs بتقف والـ writes بتفشل وبتلاقي طوابير من الأخطاء بدون سبب واضح.
سيناريو واقعي: cluster بـ 24 خدمة
فريق DevOps في شركة e-commerce عربية كان شغّال على cluster GKE بـ 24 microservice و 4 nodes. الـ MTTD (Mean Time To Detect) للمشاكل في الإنتاج كان 38 دقيقة، عادةً بيوصل بعد ما العميل يبعت تذكرة دعم.
طبّقوا الـ 8 استعلامات دي على Grafana في 4 alerts بسيطة: error rate أكتر من 1%، P95 أكتر من 1.2 ثانية، CPU أكتر من 85%، Pod restarts أكتر من 3 في 15 دقيقة. النتيجة بعد شهر: الـ MTTD نزل لـ 2.4 دقيقة في المتوسط. أعداد التذاكر اللي العميل فتحها بسبب 5xx نزلت من 47 في الشهر لـ 6.
الفرق ده مش جاي من PromQL "السحرية"، جاي من إن الفريق بقى عنده 4 أسئلة محددة بيسألها كل دقيقة على البيانات اللي كانت موجودة من 4 شهور.
Trade-offs لازم تعرفها
1. Cardinality explosion. لما تضيف label فيه قيم كتير (زي user_id أو request_id)، Prometheus بياكل ذاكرة بتزيد بشكل أسّي. كل توليفة labels بتعمل time series منفصلة. القاعدة العملية: متضيفش label فيه أكتر من 100-200 قيمة فريدة. لو حطّيت user_id ك label وعندك مليون يوزر، Prometheus هيقع في أقل من ساعة.
2. الـ rate() محتاج وقت كافي. rate(metric[1m]) ممكن يطلع noise عشوائي على scrape interval كبير. الحد الأدنى الموصى به 4 × scrape_interval. لو الـ scrape كل 15 ثانية، استعمل [1m] على الأقل.
3. الـ histograms مكلفة. كل histogram بـ 10 buckets بيعمل 10 time series. خدمة فيها 50 endpoint × 10 buckets = 500 time series من metric واحدة. لازم تخطيط مسبق للـ buckets قبل ما تنشر metric كبير على إنتاج.
4. Prometheus مش database طويلة المدى. لو احتجت حفظ بيانات أكتر من 15 يوم، استخدم Thanos أو Mimir للتخزين الطويل. Prometheus لوحده بيقدّم retention عملي 15-30 يوم على disk عادي قبل ما يحتاج compaction أو حذف.
متى لا تكتب PromQL أصلاً
لو الـ stack بتاعك صغير (3-5 خدمات بـ traffic أقل من 100 طلب/ثانية)، استخدم قوالب Grafana الجاهزة للـ Node Exporter Full (ID: 1860) و Kubernetes Mixin. هتاخد 80% من القيمة بـ 0% من جهد كتابة الاستعلامات.
كذلك لو الفريق مش متفرغ لمراقبة Grafana، الـ alerts الذكية في Datadog أو New Relic بتستحق الفلوس مقابل الراحة العقلية. PromQL بياخد وقت تتعلمه، والوقت ده ممكن يكون أغلى من فاتورة SaaS بسيطة لفريق صغير.
الخطوة التالية
افتح Grafana بتاعك دلوقتي وروح على Explore. اختار datasource Prometheus. الصق الاستعلام رقم 3 (نسبة الأخطاء) واستبدل http_requests_total بأسم metric الـ HTTP عندك (ممكن يكون nginx_http_requests_total أو traefik_service_requests_total أو غيرهم). لو رجّع رقم فوق 1%، عندك مشكلة لازم تشتغل عليها قبل ما توصل التذكرة الجاية من العميل.
المصادر
- Prometheus Querying Basics — التوثيق الرسمي للـ PromQL
- Histograms and Summaries — Prometheus Best Practices
- Metric and Label Naming Conventions
- Kubernetes Mixin — قوالب Grafana جاهزة من المجتمع
- Cardinality is Key — Robust Perception (شركة فريق Prometheus الأصلي)
- kube-state-metrics — مصدر metrics الـ Kubernetes
- node_exporter — مصدر metrics الـ Linux/Unix