Prometheus وGrafana

قواعد التسجيل والتنبيه

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

قواعد التسجيل والتنبيه

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

سبب وجود قواعد التسجيل

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

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

متى تنشئ قاعدة تسجيل: لأي تعبير PromQL (1) يستغرق أكثر من ~100 مللي ثانية للتقييم، أو (2) يُستخدم في أكثر من مكان واحد، أو (3) يُغذّي تنبيهاً يعمل على قيمة مجمَّعة مسبقاً. يُظهر مفتش الاستعلامات في Grafana وقت التقييم — استخدمه.

بنية ملف قاعدة التسجيل

تقع القواعد في ملفات YAML تُحمَّل عبر فقرة rule_files في prometheus.yml. يمكن أن يضم الملف مجموعات متعددة؛ ولكل مجموعة interval خاص بها (الافتراضي هو evaluation_interval العام).

# prometheus.yml (جزئي) global: evaluation_interval: 15s rule_files: - "rules/*.yml"
# rules/request_rates.yml groups: - name: request_rates # اسم التجميع المنطقي interval: 30s # تجاوز الإعداد العام إذا لزم rules: # معدل الطلبات خمس دقائق مُحسَّب مسبقاً لكل مهمة وحالة - record: job:http_requests_total:rate5m expr: | sum by (job, status) ( rate(http_requests_total[5m]) ) # نسبة الأخطاء للوحات SLO - record: job:http_errors:ratio5m expr: | sum by (job) ( rate(http_requests_total{status=~"5.."}[5m]) ) / sum by (job) ( rate(http_requests_total[5m]) ) # تأخر p99 مجمَّع مسبقاً لكل مهمة - record: job:http_request_duration_seconds:p99_5m expr: | histogram_quantile( 0.99, sum by (job, le) ( rate(http_request_duration_seconds_bucket[5m]) ) )

اصطلاح التسمية level:metric:operations هو التوصية الرسمية لـ Prometheus (يُعرف أيضاً بـ مخطط تسمية قواعد التسجيل). level هو نطاق التجميع (job، instance، cluster)، وmetric هو اسم المقياس الأساسي، وoperations يصف ما جرى فعله (rate5m، p99_5m، ratio1h). اتباع هذا الاصطلاح يجعل القواعد قابلة للاكتشاف ويمنع تعارض الأسماء بين الفرق.

قواعد التنبيه — تشريح تنبيه جيد

قاعدة التنبيه هي تعبير PromQL يُقيَّم دورياً. حين ينتج التعبير متجهاً بنتيجة واحدة أو أكثر، ينتقل التنبيه إلى حالة Pending. بمجرد أن يبقى Pending طوال مدة for، يُطلق (Firing) ويُسلَّم إلى Alertmanager.

# rules/slo_alerts.yml groups: - name: slo_alerts rules: - alert: HighErrorRate # استخدام قاعدة التسجيل المحسوبة مسبقاً — سريعة ومتسقة expr: job:http_errors:ratio5m > 0.01 for: 5m # يجب أن يظل صحيحاً 5 دقائق قبل الإطلاق labels: severity: page # يُوجَّه إلى PagerDuty في Alertmanager team: backend annotations: summary: "معدل أخطاء مرتفع على {{ $labels.job }}" description: | نسبة الأخطاء هي {{ $value | humanizePercentage }} للمهمة {{ $labels.job }}. Runbook: https://wiki.internal/runbooks/high-error-rate - alert: LatencyP99Breach expr: job:http_request_duration_seconds:p99_5m > 0.5 for: 10m labels: severity: page team: backend annotations: summary: "تأخر p99 > 500ms على {{ $labels.job }}" description: | تأخر p99 هو {{ $value | humanizeDuration }} على {{ $labels.job }}. Runbook: https://wiki.internal/runbooks/high-latency - alert: ServiceDown expr: up == 0 for: 1m labels: severity: page annotations: summary: "المثيل {{ $labels.instance }} معطل" description: "المهمة {{ $labels.job }} على {{ $labels.instance }} غير قابلة للوصول منذ أكثر من دقيقة."
Alert lifecycle: Inactive → Pending → Firing → Alertmanager → Notification INACTIVE expr = no results expr fires PENDING waiting for: duration for: elapsed FIRING alert sent to AM Alertmanager route / inhibit / silence / group Notification PagerDuty / Slack expr no longer true → RESOLVED → INACTIVE
دورة حياة التنبيه: ينتقل التنبيه من Inactive إلى Pending ثم Firing بمجرد انقضاء مدة for، ثم يوجّهه Alertmanager إلى قناة الإشعارات.

الفقرة for — أهميتها

مدة for هي دفاعك الأول ضد عواصف التنبيهات الناجمة عن ارتفاعات عابرة. ارتفاع استخدام المعالج لمدة 15 ثانية لا يستوجب إيقاظ أحد في الثالثة صباحاً. إعداد for: 5m يعني أن الشرط يجب أن يكون صحيحاً بصورة ثابتة لمدة خمس دقائق كاملة، مما يرشّح الضوضاء مع الإمساك بالتدهور المستدام.

لا تضع for: 0s على مقاييس عالية الحركة. كل اضطراب — استقصاء بطيء واحد، توقف مؤقت لجمع البيانات المهملة، إعادة تشغيل متتالية — سيُطلق التنبيه. يجب أن تتضمن قواعد التنبيه الإنتاجية على المقاييس القائمة على المعدلات for لا تقل عن 2-5 دقائق. الاستثناء هو up == 0 (إمكانية الوصول إلى المثيل) الذي يمكن استخدامه بشكل معقول مع for: 1m.

التسميات والتعليقات التوضيحية — الجودة التشغيلية

تُدمج التسميات في قواعد التنبيه مع مجموعة تسميات التنبيه التي يستخدمها Alertmanager للتوجيه. severity: page مقابل severity: ticket هو أكثر الأبعاد شيوعاً؛ وإضافة team تتيح التوجيه لكل فريق إلى خدمات PagerDuty منفصلة.

تحمل التعليقات التوضيحية سياقاً مقروءاً للإنسان: summary (جملة واحدة تظهر في Slack)، وdescription (تفصيلي يتضمن رابطاً للـ runbook)، واختيارياً runbook_url. استخدم صيغة قوالب Go لتضمين قيم التسميات ({{ $labels.job }}) والقيمة الحالية ({{ $value }}) مباشرة في الإشعار.

روابط Runbook في كل تنبيه. التنبيه بدون runbook هو لغز يُسلَّم لمهندس نعسان. التعليق التوضيحي runbook_url مدعوم رسمياً من Alertmanager ويُعرض كرابط قابل للنقر في معظم المستقبلات. عامل Runbook المفقود كعائق للنشر، تماماً كما تعامل الاختبار المفقود.

التحقق من الصحة وإعادة التحميل

يأتي Prometheus مع promtool — استخدمه في CI للتحقق من صحة ملفات القواعد قبل وصولها للإنتاج.

# التحقق من جميع ملفات القواعد promtool check rules rules/*.yml # اختبار وحدة تعبيرات التنبيه (promtool test rules) # test/alert_tests.yml rule_files: - ../rules/slo_alerts.yml tests: - interval: 1m input_series: - series: 'http_requests_total{job="api",status="500"}' values: '0 0 0 60 60 60 60 60 60 60' - series: 'http_requests_total{job="api",status="200"}' values: '0 1000 2000 3000 4000 5000 6000 7000 8000 9000' alert_rule_test: - eval_time: 5m alertname: HighErrorRate exp_alerts: [] # لا يزال معلقاً، لم تمر 5 دقائق بعد - eval_time: 10m alertname: HighErrorRate exp_alerts: - exp_labels: job: api severity: page team: backend

شغّل promtool test rules test/alert_tests.yml في pipeline الخاص بك. ثم أعد تحميل Prometheus في وقت التشغيل — دون الحاجة لإعادة التشغيل — إما عبر SIGHUP أو نقطة نهاية HTTP للإعادة (حين يكون --web.enable-lifecycle مفعّلاً): curl -X POST http://localhost:9090/-/reload.

المزالق الإنتاجية

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

انفجار كثافة التسميات: إضافة تسمية عالية الكثافة (مثل user_id) إلى قاعدة تسجيل ينتج سلسلة زمنية مخزّنة واحدة لكل مستخدم. هذا عادةً كارثي. أبقِ قواعد التسجيل عند حبوبية المهمة أو الخدمة، وليس المثيل أو الطلب.

عدم تطابق فترة التقييم مع فترة الاستقصاء: إذا ضبطت interval لمجموعة قواعد أقصر من فترة الاستقصاء للمقاييس الأساسية، ستُعيد القاعدة التقييم على نفس البيانات مراراً، مما يهدر المعالج دون إنتاج معلومات جديدة. أبقِ فترات القواعد مساوية لفترة الاستقصاء أو أكبر منها.