Prometheus Alerts بالعربي: قلل التنبيهات الكاذبة قبل ما تصحي الفريق
هتخرج من المقال ده بإعداد Alert Rules عملي يقلل التنبيهات الكاذبة، ويخلي التنبيه اللي بيوصلك قابل للتصرف بدل ما يكون صوت مزعج.
مستوى القارئ: متوسط
المشكلة باختصار
الطريقة الشائعة الغلط إنك تعمل alert على أي spike لحظي. مثلًا: لو latency عدّى 500ms لمدة دقيقة، ابعت تنبيه. الطريقة دي بتفشل لأن الإنتاج الطبيعي فيه spikes قصيرة وقت restart، deploy، أو GC pause. النتيجة إن الفريق يتعود يتجاهل التنبيهات، وده أخطر من عدم وجود monitoring.
الافتراض إن عندك خدمة Web عليها حوالي 50K زائر يوميًا، وبتستخدم Prometheus مع Alertmanager. لو عندك 3 instances وكل instance بيعمل restart مرة يوميًا، ممكن تشوف 6 إلى 10 تنبيهات كاذبة في الأسبوع لو القاعدة حساسة زيادة.
الفكرة الأساسية: التنبيه لازم يقيس استمرار المشكلة
ركز: الـ monitoring مش مطلوب منه يثبت إن كل ثانية مثالية. المطلوب يقولك إمتى المستخدمين بيتأثروا بشكل مستمر. الفرق هنا مهم. spike لمدة 30 ثانية ممكن يكون مقبول. latency عالية لمدة 10 دقائق معناها إن في مشكلة تستحق فتح incident.
Prometheus بيدعم ده من خلال حقل for داخل alerting rules. حسب توثيق Prometheus الرسمي، القاعدة لا تعتبر firing إلا بعد استمرار الشرط طول المدة المحددة. المصدر: Prometheus Alerting Rules.
مثال قريب: اعتبر التنبيه زي إنذار حريق في مطبخ. دخان بسيط لمدة 5 ثواني أثناء الطبخ مش حادث. دخان مستمر 5 دقائق محتاج تدخل. نفس المعنى بالظبط ينطبق على latency وerror rate.
إعداد عملي لقاعدة تنبيه أقل إزعاجًا
بدل ما تنبه على request واحد بطيء، استخدم percentile من histogram. Prometheus يوفر دالة histogram_quantile لحساب قيم مثل P95 من buckets. المصدر: Prometheus histogram_quantile.
القاعدة التالية تنبه لما P95 latency يتعدى 700ms لمدة 10 دقائق. الرقم 700ms هنا مناسب كبداية لتطبيق CRUD داخلي. لو المنتج public-facing وحساس، ممكن تبدأ بـ 400ms.
groups:
- name: api-latency.rules
rules:
- alert: HighApiLatencyP95
expr: |
histogram_quantile(
0.95,
sum(rate(http_request_duration_seconds_bucket{job="api"}[5m])) by (le)
) > 0.7
for: 10m
labels:
severity: warning
team: backend
annotations:
summary: "API P95 latency is above 700ms"
description: "P95 latency stayed above 700ms for 10 minutes. Check recent deploys, DB latency, and queue depth."
runbook_url: "https://example.com/runbooks/high-api-latency"
لو القاعدة القديمة كانت بتبعت 12 تنبيه في الأسبوع بسبب spikes قصيرة، إضافة for: 10m ممكن تنزل الرقم إلى 2 أو 3 تنبيهات فعلية. الرقم تقديري، لكنه واقعي لفريق عنده deploy يومي وخدمة عليها traffic متوسط.
اعمل severity بدل ما كل حاجة تبقى incident
مش كل alert لازم يصحي حد الساعة 3 الفجر. أفضل طريقة إنك تقسم التنبيهات. warning يروح Slack أو Microsoft Teams. critical يروح PagerDuty أو Opsgenie. كده الفريق يقدر يفرق بين متابعة مطلوبة وحريق فعلي.
مثال: latency فوق 700ms لمدة 10 دقائق = warning. latency فوق 1.5s لمدة 5 دقائق مع error rate فوق 2% = critical. الـ trade-off هنا إنك هتكتب قواعد أكثر، لكن المكسب إن on-call مش هيتعامل مع كل مشكلة بنفس الوزن.
- alert: CriticalApiLatencyAndErrors
expr: |
(
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{job="api"}[5m])) by (le)) > 1.5
)
and
(
sum(rate(http_requests_total{job="api",status=~"5.."}[5m]))
/
sum(rate(http_requests_total{job="api"}[5m])) > 0.02
)
for: 5m
labels:
severity: critical
team: backend
annotations:
summary: "API is slow and returning 5xx errors"
description: "Latency and error rate are both high. Start incident flow and check DB, cache, and latest deploy."
Runbook صغير أهم من وصف طويل
التنبيه من غير runbook بيحوّل on-call لشخص بيفتش في dashboards وهو تحت ضغط. خلي كل alert فيه runbook_url. مش لازم runbook مثالي. صفحة قصيرة تكفي: أول 3 أوامر، dashboards المطلوبة، وآخر deploy.
مثال أوامر أولية:
# آخر deploy على الخدمة
kubectl rollout history deployment/api -n production
# حالة الـ pods
kubectl get pods -n production -l app=api
# أخطاء آخر 10 دقائق
kubectl logs -n production deployment/api --since=10m | grep -E "ERROR|timeout|connection"
بتكسب سرعة تشخيص. بتخسر وقت بسيط في كتابة runbook وتحديثه. لو كل incident بياخد 25 دقيقة للوصول لأول سبب محتمل، runbook جيد ممكن ينزل الرقم لـ 10 أو 12 دقيقة.
متى لا تستخدم هذه الطريقة
لا تستخدم for: 10m بشكل أعمى مع مشاكل الأمان أو فقدان البيانات. لو فيه payment failures أو data corruption، التأخير 10 دقائق ممكن يكون غالي. استخدم مدة أقصر، أو نبه فورًا مع شروط أدق. كذلك لو traffic قليل جدًا، percentile ممكن يكون مضلل لأن العينة صغيرة. في الحالة دي استخدم counts واضحة أو synthetic checks.
مصادر اعتمد عليها المقال
- توثيق Prometheus Alerting Rules لشرح
forوlabels وannotations. - توثيق histogram_quantile لحساب P95 من histogram buckets.
- توثيق Alertmanager لفكرة routing والتنبيهات حسب labels.
الخطوة التالية
افتح أهم 3 alerts عندك اليوم. لو أي alert منهم مفيهوش for أو runbook_url، ابدأ بيه وعدّل القاعدة قبل ما تضيف تنبيهات جديدة.