התראה ללא מתודולוגיה מחושבת הופכת לרעש: 200 התראות בלילה, שמחציתן "נפתרות" תוך 2 דקות. הצוות מפסיק להגיב—ואז הבעיה האמיתית פוגעת. בפרויקט אחד קיבלנו 150 התראות בשעה עקב סף CPU שהוגדר בצורה שגויה. לאחר יישום מתודולוגיית burn rate, נותרו רק 5. מטרת ההגדרה היא התראות רק למצבים הדורשים פעולה אנושית. התראה מוגדרת כראוי אינה רק הודעה; היא מערכת המאפשרת לזהות בעיות לפני שהן משפיעות על המשתמשים. אנו עוסקים בזה למעלה מ-5 שנים והקמנו ניטור ל-50+ יישומי ווב—מסטארטאפים ועד ארגונים. להלן גישה הנדסית ללא סלסולים.
אילו מדדים לנטר קודם?
התחילו עם ארבעת האותות המוזהבים המתוארים ב-Site Reliability Engineering: זמן אחזור, תעבורה, שגיאות, רוויה. עבור יישום ווב, זמן אחזור (P95), שגיאות (5xx), תעבורה (RPS), ורוויה (CPU, זיכרון) מספיקים. בנוסף, אורך תור, תעודת SSL, ומדדים עסקיים (המרות, הרשמות). SLO (יעד רמת שירות) הוא רמת הזמינות היעד, למשל 99.9% זמינות. SLI (מדד רמת שירות) הוא המדד בפועל שאנו מודדים. התראות עם burn rate מאפשרות תגובה מהירה כאשר הסטייה מה-SLO מאיימת על התקציב.
עקרונות התראה אפקטיבית
התראו על סימפטומים, לא על גורמים. התראה כמו 'האתר לא זמין למשתמשים' חשובה יותר מ-'CPU > 80%'. CPU גבוה הוא גורם שאולי לא משפיע על המשתמשים. עיקרון זה מתואר בספר Google SRE Book.
כלל ארבעת האותות המוזהבים: זמן אחזור, תעבורה, שגיאות, רוויה. התחילו עם שלושת הראשונים. Burn rate במקום ספים: 'שיעור שגיאות > 5% למשך 5 דקות' עדיף על 'שגיאה אחת לדקה'. Burn rate מראה כמה מהר אתם צורכים את תקציב השגיאות של SLO ומאפשר זיהוי מוקדם של חריגות.
למה Burn Rate עדיף על ספים?
התראות מבוססות ספים מייצרות הרבה תוצאות חיוביות שגויות. דוגמה: שגיאה באחת מתוך מאה בקשות היא 1%, אבל אם היא נמשכת שעה, תקציב השגיאות (SLO 99.9%) ימוצה תוך 4 ימים. Burn rate = 10. התראה עם ערך זה תופעל תוך 5 דקות, לא תוך שעה. זה מפחית רעש פי 10.
איך להימנע מהתראות רועשות?
השתמשו ב-burn rate, קיבוץ, ו-deduplication ב-Alertmanager. הגדירו group_wait (30s), group_interval (5m), repeat_interval (4h). התראות צריכות להיות על סימפטומים, לא על גורמים. אם CPU > 80% לא משפיע על משתמשים, זו לא התראה.
הגדרת Stack: Prometheus + Alertmanager + Grafana
דוגמת docker-compose.yml
---
services:
prometheus:
image: prom/prometheus:v2.51.0
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- ./rules:/etc/prometheus/rules
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=30d'
ports:
- "9090:9090"
alertmanager:
image: prom/alertmanager:v0.27.0
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
ports:
- "9093:9093"
grafana:
image: grafana/grafana:11.0.0
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
ports:
- "3000:3000"
volumes:
prometheus_data:
grafana_data:
מדדי יישום (Laravel) והגדרה
עבור Laravel, התקינו את החבילה services: prometheus: image: prom/prometheus:v2.51.0 volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml - ./rules:/etc/prometheus/rules - prometheus_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.retention.time=30d' ports: - "9090:9090" alertmanager: image: prom/alertmanager:v0.27.0 volumes: - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml ports: - "9093:9093" grafana: image: grafana/grafana:11.0.0 environment: - GF_SECURITY_ADMIN_PASSWORD=admin volumes: - grafana_data:/var/lib/grafana ports: - "3000:3000" volumes: prometheus_data: grafana_data: ורשמו מדדים מותאמים אישית:
// app/Providers/AppServiceProvider.php
use Prometheus\CollectorRegistry;
public function boot(): void
{
$registry = app(CollectorRegistry::class);
// Counter — количество HTTP-запросов
$httpRequests = $registry->getOrRegisterCounter(
'app',
'http_requests_total',
'Total HTTP requests',
['method', 'route', 'status']
);
// Histogram — время ответа
$httpDuration = $registry->getOrRegisterHistogram(
'app',
'http_request_duration_seconds',
'HTTP request duration',
['method', 'route'],
[0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0]
);
// Gauge — очередь задач
$queueSize = $registry->getOrRegisterGauge(
'app',
'queue_size',
'Current queue size',
['queue']
);
}Prometheus הגדרה:
---
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
rule_files:
- 'rules/*.yml'
scrape_configs:
- job_name: 'web-app'
static_configs:
- targets: ['app:9000']
metrics_path: /metrics
דוגמת כללי התראה
---
# rules/web-app.yml
groups:
- name: web-app
rules:
# Высокий процент ошибок (5xx)
- alert: HighErrorRate
expr: |
sum(rate(app_http_requests_total{status=~"5.."}[5m])) / sum(rate(app_http_requests_total[5m])) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "Error rate {{ $value | humanizePercentage }}"
description: "5xx rate exceeded 5% for 2 minutes"
# Медленные ответы (P95 > 2 секунды)
- alert: HighLatencyP95
expr: |
histogram_quantile(0.95, sum by (le) (rate(app_http_request_duration_seconds_bucket[5m])) ) > 2
for: 5m
labels:
severity: warning
annotations:
summary: "P95 latency {{ $value | humanizeDuration }}"
# Отсутствие трафика (аномальное падение)
- alert: TrafficDrop
expr: |
sum(rate(app_http_requests_total[5m])) < 0.1 and sum(rate(app_http_requests_total[1h] offset 1h)) > 1
for: 5m
labels:
severity: critical
annotations:
summary: "Traffic almost zero — possible outage"
# Большая очередь задач
- alert: QueueBacklog
expr: app_queue_size{queue="default"} > 1000
for: 10m
labels:
severity: warning
annotations:
summary: "Queue backlog: {{ $value }} jobs"
# SSL сертификат истекает
- alert: SSLCertExpiringSoon
expr: probe_ssl_earliest_cert_expiry - time() < 14 * 24 * 3600
for: 1h
labels:
severity: warning
annotations:
summary: "SSL cert expires in {{ $value | humanizeDuration }}"
---
ניתוב ו-Deduplication ב-Alertmanager
---
# alertmanager.yml
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'severity']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'telegram-critical'
routes:
- match:
severity: critical
receiver: 'telegram-critical'
continue: false
- match:
severity: warning
receiver: 'telegram-warning'
group_interval: 15m
repeat_interval: 12h
receivers:
- name: 'telegram-critical'
telegram_configs:
- bot_token: 'your_bot_token'
chat_id: -1001234567890
message: |
🔴 *{{ .CommonLabels.alertname }}*
{{ range .Alerts }}
{{ .Annotations.summary }}
{{ if .Annotations.description }}{{ .Annotations.description }}{{ end }}
{{ end }}
- name: 'telegram-warning'
telegram_configs:
- bot_token: 'your_bot_token'
chat_id: -1001234567890
message: |
⚠️ *{{ .CommonLabels.alertname }}*
{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname']
השוואה בין Prometheus לשירותי ענן
| קריטריון | Prometheus + Alertmanager | שירותי ענן (CloudWatch, Stackdriver) |
|---|---|---|
| גמישות | שליטה מלאה, כל מדד | יכולות מוגבלות |
| עלות | חינם, רק חומרה | תשלום לפי מדד |
| נעילת ספק | אין | מלאה |
Prometheus + Alertmanager מספקים גמישות ושליטה. בניגוד ל-CloudWatch או Stackdriver, אתם לא קשורים לספק והעלות נמוכה משמעותית בקנה מידה. בפרויקט אחד, הפחתנו עלויות ניטור פי 3 על ידי מעבר מ-Datadog ל-stack עצמי. הגדרה כזו מחזירה את עצמה תוך כמה חודשים על ידי הפחתת עלויות תשתית.
תהליך עבודה ולוחות זמנים משוערים
| שלב | משך | תוצאה |
|---|---|---|
| אנליטיקה | 0.5–1 יום | רשימת אותות מוזהבים, SLO/SLI |
| עיצוב | 0.5 יום | תוכנית התראות, burn rate, ניתובים |
| יישום | 1–2 ימים | Prometheus, Alertmanager, Grafana |
| בדיקות | 0.5–1 יום | סימולציה, בדיקות chaos |
| פריסה | 0.5 יום | ייצור, הדרכת צוות |
הגדרה בסיסית (8–12 כללים) אורכת 1–2 ימי עבודה. אם נדרשים מדדים מותאמים אישית וניתוב מורכב, עד 4 ימים.
מה כלול
- ביקורת מדדי יישום נוכחיים (APM, לוגים, תשתית)
- פריסת Prometheus + Alertmanager + Grafana
- יצירת 8–12 כללי התראה עם burn rate
- אינטגרציה עם Telegram, Slack, או דוא"ל
- לוחות מחוונים בסיסיים של Grafana (שיעור שגיאות, זמן אחזור, RPS, תור)
- תיעוד והדרכת צוות
- אחריות לתוצאה ותמיכה לחודש
אם יש לכם משימה דומה, צרו קשר לייעוץ. נעריך את היקף העבודה תוך יום אחד. הזמינו הגדרת ניטור כדי להיפטר מהרעש ולישון בשקט. קבלו ייעוץ על הגדרת התראות.







