Grafana Alerting: Panoya Dayalı Uyarı Tanımlama
Üretim ortamında bir servis çöktüğünde ilk öğrenen sen olmak istiyorsun, değil mi? Telefona bakıyorsun, müşteriden şikayet gelmiş, sen hala habersizsin. Bu senaryo sysadmin’lerin kabusu. Grafana Alerting tam bu noktada devreye giriyor ve doğru kurulduğunda seni bu utanç verici durumdan kurtarıyor.
Bu yazıda Grafana’nın panel tabanlı uyarı sistemini sıfırdan nasıl kuracağını, gerçek dünya senaryolarıyla birlikte anlatacağım. Prometheus metrikleriyle çalışan bir ortam varsayıyorum ama konsept diğer veri kaynaklarına da uygulanabilir.
Grafana Alerting Mimarisi Nedir?
Grafana 8.x ile birlikte gelen Unified Alerting sistemi, eski panel bazlı uyarı sisteminin yerini aldı. Eski sistemde her panel için ayrı ayrı uyarı tanımlıyordun ve bu yönetimi zorlaştırıyordu. Yeni sistemde ise merkezi bir uyarı yöneticisi var.
Temel bileşenler şunlar:
- Alert Rule: Hangi koşulda uyarı tetikleneceğini tanımlar
- Contact Point: Uyarının gideceği hedef (Slack, email, PagerDuty vb.)
- Notification Policy: Hangi uyarının hangi contact point’e gideceğini belirler
- Silences: Belirli uyarıları geçici olarak susturmak için kullanılır
- Alert Groups: Benzer uyarıları gruplar
Grafana Alerting arka planda Prometheus’un Alertmanager konseptini kullanıyor. Zaten harici Alertmanager ile entegre de çalışabiliyor.
Ön Gereksinimler
Önce ortamın hazır olduğunu doğruyalım. Çalışan bir Prometheus ve Grafana instance’ın olması gerekiyor.
# Prometheus ve Grafana servis durumlarını kontrol et
systemctl status prometheus
systemctl status grafana-server
# Prometheus hedeflerinin çalışıp çalışmadığını kontrol et
curl -s http://localhost:9090/api/v1/targets | python3 -m json.tool | grep "health"
# Grafana API'sinin ayakta olduğunu doğrula
curl -s http://localhost:3000/api/health
Grafana konfigürasyon dosyasında alerting’in aktif olduğundan emin ol:
# /etc/grafana/grafana.ini dosyasını düzenle
sudo nano /etc/grafana/grafana.ini
Şu satırların aktif olduğunu kontrol et:
[unified_alerting]
enabled = true
[alerting]
enabled = false
Dikkat et: Eski [alerting] bölümü false olmalı, [unified_alerting] ise true. İkisi aynı anda aktif olamaz.
Değişiklikten sonra Grafana’yı yeniden başlat:
sudo systemctl restart grafana-server
sudo journalctl -u grafana-server -f --no-pager | tail -20
İlk Contact Point Tanımlama
Uyarı kuralı yazmadan önce uyarıların nereye gideceğini belirlemen gerekiyor. Alerting > Contact Points menüsünden yeni bir contact point ekle.
Slack entegrasyonu için webhook URL’i almanın en pratik yolu Slack’te bir uygulama oluşturmak. Ama daha hızlı test için gelen webhook URL’ini doğrudan kullanabilirsin.
Grafana API üzerinden contact point eklemek istersen:
curl -X POST
http://admin:adminpassword@localhost:3000/api/v1/provisioning/contact-points
-H 'Content-Type: application/json'
-d '{
"name": "slack-prod-alerts",
"type": "slack",
"settings": {
"url": "https://hooks.slack.com/services/TXXXXXXXX/BXXXXXXXX/XXXXXXXXXXXXXXXX",
"channel": "#infra-alerts",
"title": "{{ template "slack.default.title" . }}",
"text": "{{ template "slack.default.text" . }}"
}
}'
Email contact point için SMTP konfigürasyonu da grafana.ini‘ye eklenmeli:
[smtp]
enabled = true
host = smtp.yourcompany.com:587
user = [email protected]
password = your_smtp_password
from_address = [email protected]
from_name = Grafana Alerting
starttls_policy = MandatoryStartTLS
Panel Tabanlı Alert Rule Oluşturma
Şimdi asıl konuya geliyoruz. Mevcut bir Grafana panosundaki bir panelden uyarı tanımlamak için iki yol var: doğrudan panel editöründen veya Alerting menüsünden. Her ikisini de göstereceğim.
CPU Kullanım Uyarısı
En klasik senaryo: CPU kullanımı %85’i geçince uyarı ver. Panel editöründe Alert sekmesine geç ve New alert rule butonuna tıkla.
Prometheus sorgusu şöyle olmalı:
# Panel query olarak bu PromQL'i gir
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Bu sorgu her instance için CPU kullanım yüzdesini döndürür
# "by (instance)" etiketi sayesinde her sunucu ayrı ayrı değerlendirilir
Alert rule konfigürasyonu:
- Rule name:
high-cpu-usage - Folder: Infrastructure
- Evaluation group: linux-servers (15s interval)
- Pending period: 5m (5 dakika boyunca koşul sağlanırsa uyarı gönder)
Threshold kısmında:
- Condition: IS ABOVE 85
- For: 5m
Pending period çok önemli. Bunu 0 yaparsan anlık spike’larda sürekli uyarı alırsın. 5 dakika koymak, geçici yüklenmeleri filtreler.
Disk Doluluk Uyarısı
Disk %90’ı dolduğunda uyarı almak istiyorsun. Bu sefer birden fazla threshold kuralı ekleyelim.
# Grafana panel sorgusu
(node_filesystem_avail_bytes{fstype!~"tmpfs|fuse.lxcfs|squashfs",mountpoint!="/"}
/ node_filesystem_size_bytes{fstype!~"tmpfs|fuse.lxcfs|squashfs",mountpoint!="/"})
* 100 < 100
Daha temiz bir sorgu için etiket filtrelerini iyi ayarla. tmpfs ve squashfs filesystem’larını dışarda bırakmak gereksiz gürültüyü önler.
İki aşamalı uyarı için iki ayrı kural tanımlayabilirsin:
# Uyarı seviyesi - disk %80 doldu
(1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100 > 80
# Kritik seviye - disk %90 doldu
(1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100 > 90
Servis Availability Uyarısı
Bir web servisinin up/down durumunu izlemek için Blackbox Exporter kullanıyorsan:
# HTTP endpoint kontrolü - 0 değeri servisin down olduğu anlamına gelir
probe_success{job="blackbox-http"} == 0
# Daha spesifik - belirli bir URL için
probe_success{instance="https://api.yoursite.com/health"} == 0
Bu senaryoda pending period’u düşük tut. Servis gerçekten düştüyse 1 dakika bile uzun sürebilir:
- Pending period: 2m
- Condition: IS BELOW 1
Alert Rule API ile Toplu Tanımlama
Onlarca sunucu yönetiyorsan tek tek GUI’den kural eklemek saçmalık. Provisioning dosyaları veya API kullan.
# YAML provisioning dosyası oluştur
sudo nano /etc/grafana/provisioning/alerting/linux-servers.yaml
apiVersion: 1
groups:
- orgId: 1
name: linux-servers
folder: Infrastructure
interval: 1m
rules:
- uid: linux-cpu-alert-001
title: High CPU Usage
condition: C
data:
- refId: A
queryType: ''
relativeTimeRange:
from: 600
to: 0
datasourceUid: prometheus-uid
model:
expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
intervalMs: 1000
maxDataPoints: 43200
refId: A
- refId: C
queryType: ''
relativeTimeRange:
from: 0
to: 0
datasourceUid: __expr__
model:
conditions:
- evaluator:
params:
- 85
type: gt
operator:
type: and
query:
params:
- A
reducer:
type: last
refId: C
type: classic_conditions
noDataState: NoData
execErrState: Error
for: 5m
annotations:
description: "CPU kullanimi {{ $labels.instance }} sunucusunda %{{ $values.A | printf "%.1f" }} seviyesine ulasti."
summary: "Yuksek CPU kullanimi tespit edildi"
labels:
severity: warning
team: infra
Dosyayı kaydedip Grafana’yı yeniden başlattığında kurallar otomatik yükleniyor:
sudo systemctl reload grafana-server
# veya
sudo systemctl restart grafana-server
# Kuralların yüklendiğini kontrol et
curl -s http://admin:adminpassword@localhost:3000/api/ruler/grafana/api/v1/rules | python3 -m json.tool
Notification Policy Yapılandırması
Contact point tanımladın, kural yazdın. Şimdi hangisinin nereye gideceğini belirlemelisin. Alerting > Notification Policies menüsüne git.
Default policy her şeyi yakalar. Ama production’da severity ve team etiketlerine göre yönlendirme yapmak çok daha mantıklı.
# API ile notification policy güncelleme
curl -X PUT
http://admin:adminpassword@localhost:3000/api/v1/provisioning/policies
-H 'Content-Type: application/json'
-d '{
"receiver": "default-email",
"group_by": ["grafana_folder", "alertname"],
"group_wait": "30s",
"group_interval": "5m",
"repeat_interval": "4h",
"routes": [
{
"receiver": "slack-prod-alerts",
"matchers": ["severity = critical"],
"group_wait": "10s",
"group_interval": "1m",
"repeat_interval": "1h"
},
{
"receiver": "slack-infra-channel",
"matchers": ["team = infra"],
"continue": true
},
{
"receiver": "pagerduty-oncall",
"matchers": ["severity = critical", "env = production"],
"group_wait": "0s"
}
]
}'
Önemli parametreler:
- group_wait: İlk uyarıdan önce bekleme süresi. Başka uyarılar gruba dahil edilir.
- group_interval: Aynı gruptaki yeni uyarılar için bekleme
- repeat_interval: Çözülmemiş uyarı için tekrar bildirim süresi
- continue:
trueolunca eşleşme sonrası diğer route’lara da bakar
Uyarı Template’leri Özelleştirme
Varsayılan uyarı mesajları genelde yeterli bilgi içermiyor. Go template sistemiyle mesajları zenginleştirebilirsin.
# /etc/grafana/provisioning/alerting/templates.yaml
apiVersion: 1
templates:
- name: slack-message
template: |
{{ define "slack.custom.title" }}
[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }}
{{ end }}
{{ define "slack.custom.text" }}
{{ range .Alerts }}
*Sunucu:* {{ .Labels.instance }}
*Servis:* {{ .Labels.job }}
*Onem:* {{ .Labels.severity }}
*Aciklama:* {{ .Annotations.description }}
*Baslangic:* {{ .StartsAt.Format "2006-01-02 15:04:05" }}
{{ if .GeneratorURL }}*Grafana Link:* {{ .GeneratorURL }}{{ end }}
{{ end }}
{{ end }}
Pratik Senaryo: E-ticaret Sitesi İzleme
Diyelim ki bir e-ticaret platformu yönetiyorsun. Kargo saat 18:00’de kapanıyor ve öncesinde yoğunluk oluyor. Bu saatte CPU uyarılarının gelmesi normal. Ama gece 02:00’de aynı uyarı ciddi bir sorun işareti.
Zaman bazlı Silence kullanarak mesai saatlerindeki beklenen yüklenmeleri susturabilirsin:
# API ile silence oluştur - her gün 17:00-19:00 arası CPU uyarılarını sustur
curl -X POST
http://admin:adminpassword@localhost:3000/api/alertmanager/grafana/api/v2/silences
-H 'Content-Type: application/json'
-d '{
"matchers": [
{
"name": "alertname",
"value": "High CPU Usage",
"isRegex": false
},
{
"name": "severity",
"value": "warning",
"isRegex": false
}
],
"startsAt": "2024-01-15T17:00:00Z",
"endsAt": "2024-01-15T19:00:00Z",
"comment": "Aksam yuklenme donemi - beklenen davranis",
"createdBy": "admin"
}'
Aynı sitenin ödeme servisi için SLA uyarısı eklemek istiyorsun. Ödeme başarı oranı %95’in altına düşerse anında bildirim:
# Prometheus sorgusu - son 5 dakikadaki başarısız ödeme oranı
(
sum(rate(payment_requests_total{status="failed"}[5m]))
/
sum(rate(payment_requests_total[5m]))
) * 100 > 5
Bu kural için pending period’u sıfır yap ve PagerDuty’e yönlendir. Ödeme sisteminde 1 dakika bile çok para demek.
Uyarı Durumlarını Anlamak
Grafana’da bir alert rule’un alabileceği durumlar:
- Normal: Hiçbir koşul sağlanmıyor
- Pending: Koşul sağlandı ama
forsüresi henüz dolmadı - Firing: Koşul sağlandı ve
forsüresi geçti, uyarı gönderildi - NoData: Sorgu veri döndürmüyor
- Error: Sorgu çalıştırılırken hata oluştu
NoData durumu için ne yapılacağını mutlaka belirle. Exporter çöktüyse veri gelmiyor ve bu da kritik bir durum olabilir.
# noDataState seçenekleri:
# NoData - sadece NoData uyarısı gönder
# Alerting - sanki kural ateşlenmiş gibi davran
# OK - her şey yolunda say (tehlikeli!)
# KeepLast - son bilinen durumu koru
Alerting Kurallarını Test Etme
Kural yazdın ama doğru çalışıyor mu? Prometheus’ta test sorgusu çalıştır:
# Prometheus query API ile sorguyu test et
curl -s "http://localhost:9090/api/v1/query?query=100%20-%20(avg%20by%20(instance)%20(rate(node_cpu_seconds_total%7Bmode%3D%22idle%22%7D%5B5m%5D))%20*%20100)"
| python3 -m json.tool
# Belirli bir zaman aralığında sorgu
curl -s "http://localhost:9090/api/v1/query_range?query=up&start=2024-01-15T10:00:00Z&end=2024-01-15T11:00:00Z&step=60"
| python3 -m json.tool
Grafana API üzerinden mevcut uyarı durumlarını kontrol et:
# Tüm firing alert'leri listele
curl -s http://admin:adminpassword@localhost:3000/api/alertmanager/grafana/api/v2/alerts
| python3 -m json.tool | grep -A 5 '"status"'
# Belirli bir kural grubunun durumunu kontrol et
curl -s "http://admin:adminpassword@localhost:3000/api/ruler/grafana/api/v1/rules/Infrastructure/linux-servers"
| python3 -m json.tool
Yaygın Sorunlar ve Çözümleri
Çok fazla uyarı geliyor, alarm yorgunluğu var: Pending period değerini artır, daha iyi threshold’lar belirle ve severity etiketlerini doğru kullan. Gereksiz metrikleri filtrele.
NoData uyarıları sürekli geliyor: Exporter’ların çalışıp çalışmadığını kontrol et. Prometheus scrape interval’ini ve Grafana evaluation interval’ini hizala. Çok dar zaman penceresi seçmişsin olabilirsin.
Uyarı geliyor ama Slack’e gitmiyor: Contact point’i test butonuyla test et. SMTP veya webhook bağlantısını doğrula. Notification policy matcher’larının doğru etiketleri hedef aldığından emin ol.
# Grafana log'larında alerting hatalarını ara
sudo journalctl -u grafana-server | grep -i "alerting|alert|notification" | tail -50
# Daha detaylı log için grafana.ini'de log level'ı düşür
[log]
level = debug
filters = alerting:debug
Aynı uyarı sürekli tekrar ediyor: repeat_interval değerini kontrol et. Varsayılan genelde 4 saat. Çözülmüş uyarıların resolve bildirimi gelmiyor olabilir, bu durumda contact point konfigürasyonunu gözden geçir.
Backup ve Versiyon Kontrolü
Tüm alerting konfigürasyonunu Git’e almak iyi bir pratik. Grafana’nın SQLite veritabanına bağlı olmak yerine YAML provisioning tercih et.
# Mevcut kuralları export et
curl -s http://admin:adminpassword@localhost:3000/api/v1/provisioning/alert-rules
> /opt/grafana-backup/alert-rules-$(date +%Y%m%d).json
# Contact points export
curl -s http://admin:adminpassword@localhost:3000/api/v1/provisioning/contact-points
> /opt/grafana-backup/contact-points-$(date +%Y%m%d).json
# Notification policy export
curl -s http://admin:adminpassword@localhost:3000/api/v1/provisioning/policies
> /opt/grafana-backup/policies-$(date +%Y%m%d).json
# Bunları cron'a al
echo "0 2 * * * root /opt/scripts/grafana-backup.sh" >> /etc/cron.d/grafana-backup
Sonuç
Grafana Alerting sistemi doğru kurulduğunda gerçek bir güvenlik ağı oluşturuyor. Ama dikkat etmezsen tam tersine alarm yorgunluğu yaratıp önemli uyarıları gözden kaçırmana sebep oluyor.
Önceliklerin şunlar olmalı: Önce contact point’leri test et, production’da kullanmadan önce her kanalın çalıştığını doğrula. Anlamlı threshold’lar belirle, her şeye varsayılan %80 koyma, gerçek kapasite planlamasına bak. Pending period’u iyi ayarla, anlık spike’ların gürültü yaratmasını önle. Silence’ları stratejik kullan, planlı bakım ve beklenen yüklenme dönemleri için. YAML provisioning kullan, GUI’den yaptıklarını Git’te versiyonlayamazsın.
En önemli tavsiyem: Uyarı kurallarını bir kere kurup unutma. Ayda bir gözden geçir, hangi uyarıların aksiyona yol açtığını, hangilerinin gürültü olduğunu analiz et ve buna göre optimize et. Monitoring sistemi canlı bir organizma, düzenli bakım ister.
