Grafana Dashboard Oluşturma: Kapsamlı Görselleştirme Rehberi

Prometheus ile metriklerini topladın, veriler akıyor, her şey çalışıyor. Ama terminalden curl localhost:9090/metrics çıktısına bakarak bir şeyleri anlamaya çalışmak, okyanusta iğne aramak gibi. İşte tam bu noktada Grafana devreye giriyor. Ham sayıları anlamlı grafiklere, dashboard’lara ve uyarılara dönüştüren bu araç, bir sysadmin’in en değerli silahlarından biri. Bu yazıda sıfırdan profesyonel bir Grafana dashboard’u nasıl oluşturulur, panel tipleri nasıl seçilir, PromQL sorguları nasıl optimize edilir, hepsini gerçek dünya senaryolarıyla ele alacağız.

Grafana’ya İlk Bağlantı ve Temel Ayarlar

Grafana kurulumu tamamlandıktan sonra ilk adım Prometheus veri kaynağını tanımlamak. Bunu yapmadan hiçbir şey göremezsiniz.

# Grafana servisinin çalıştığını doğrula
sudo systemctl status grafana-server

# Grafana log'larını takip et
sudo journalctl -u grafana-server -f

# Grafana konfigürasyon dosyasının yerini bul
sudo find /etc -name "grafana.ini" 2>/dev/null

Grafana varsayılan olarak 3000 portunda çalışır. Tarayıcıdan http://sunucu-ip:3000 adresine gidin. İlk giriş için kullanıcı adı admin, şifre de admin. Sisteme girer girmez şifreyi değiştirmenizi şiddetle tavsiye ederim.

Prometheus Veri Kaynağı Ekleme

UI üzerinden Configuration > Data Sources > Add data source yolunu takip edin. Ama bunu API üzerinden de yapabilirsiniz, ki bu özellikle infrastructure-as-code yaklaşımı benimseyenler için çok daha temiz:

# API ile Prometheus veri kaynağı ekle
curl -X POST 
  -H "Content-Type: application/json" 
  -d '{
    "name": "Prometheus",
    "type": "prometheus",
    "url": "http://localhost:9090",
    "access": "proxy",
    "isDefault": true,
    "jsonData": {
      "timeInterval": "15s",
      "queryTimeout": "60s",
      "httpMethod": "POST"
    }
  }' 
  http://admin:yeni_sifreniz@localhost:3000/api/datasources

access: proxy ayarı önemli. Bu, tarayıcının değil Grafana sunucusunun Prometheus’a bağlandığı anlamına gelir. Eğer Prometheus ile Grafana farklı makinelerdeyse ve Prometheus dışa kapalıysa bu ayar hayat kurtarır.

Dashboard Oluşturmanın Anatomisi

Grafana’da her şey hiyerarşik bir yapıda. Organization > Folder > Dashboard > Row > Panel şeklinde düşünün. Bu hiyerarşiyi anlamak, ilerleyen zamanlarda dashboard’larınızı organize etmeyi çok kolaylaştırır.

Yeni bir dashboard oluşturmak için + > Dashboard yolunu izleyin ya da API’yi kullanın:

# Boş dashboard oluştur
curl -X POST 
  -H "Content-Type: application/json" 
  -d '{
    "dashboard": {
      "title": "Sunucu Performans Metrikleri",
      "tags": ["production", "linux"],
      "timezone": "browser",
      "refresh": "30s",
      "time": {
        "from": "now-1h",
        "to": "now"
      },
      "panels": []
    },
    "folderId": 0,
    "overwrite": false
  }' 
  http://admin:sifre@localhost:3000/api/dashboards/db

Time Range ve Refresh Ayarları

Dashboard oluştururken en çok göz ardı edilen ama en kritik ayarlardan biri time range. Üretim ortamında bir sorun yaşandığında now-5m ile bakarken tam resmi göremezsiniz. Ben genellikle varsayılan değeri now-3h olarak ayarlıyorum. Refresh için production dashboard’larında 30 saniye makul bir değer, ama sorun anında bunu 5 saniyeye çekebilirsiniz.

Panel Tipleri ve Ne Zaman Hangisini Kullanmalısınız

Grafana’da onlarca panel tipi var. Hepsini bilmek zorunda değilsiniz, ama temel beş-altı tipi iyi bilmek işinizi çok kolaylaştırır.

Time Series Panel: Ekmek ve Su

CPU kullanımı, network trafiği, request per second gibi zamanla değişen metrikler için Time Series paneli kullanın. Bu en evrensel panel tipi.

# PromQL ile CPU kullanımını hesapla
# Panele ekleyeceğiniz sorgu:
# 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# Test etmek için Prometheus'ta dene:
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

Time Series panel’de dikkat etmeniz gereken ayarlar:

  • Fill opacity: Eğriyi doldurup doldurmamak. Birden fazla metrik varsa 0 bırakın, karmaşık görünür
  • Line width: Genellikle 2 yeterli
  • Point size: Çok sık veri noktası varsa 0 yapın, performansı etkiler
  • Legend: Bottom konumu dashboard’u daha iyi kullanır, ama kalabalık etiketler varsa Hidden yapın

Stat Panel: Tek Sayı, Büyük Etki

Şu an disk doluluk yüzdesi, toplam aktif bağlantı sayısı, uptime gibi tek bir değer göstermek istediğinizde Stat paneli mükemmel.

# Uptime metriği için PromQL
# (time() - node_boot_time_seconds) / 86400
# Sonucu gün cinsinden verir

# Disk kullanım yüzdesi
# (node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_free_bytes{mountpoint="/"}) / node_filesystem_size_bytes{mountpoint="/"} * 100

Stat panel’de Thresholds özelliği çok işe yarıyor. Disk doluluk için eşikler şöyle tanımlayabilirsiniz:

  • 0-70 arası: Yeşil
  • 70-85 arası: Sarı
  • 85-100 arası: Kırmızı

Bu görsel uyarı sistemi sayesinde dashboard’a bir bakışta kritik değerleri yakalıyorsunuz.

Gauge Panel: Yüzde Gösterimi

Gauge, Stat’ın görsel ağırlıklı kardeşi. CPU, RAM, disk gibi 0-100 arasında değişen metrikleri klasik bir gösterge gibi sunar. Stat daha kompakt, Gauge daha dramatik.

Table Panel: Detaylı Karşılaştırma

Birden fazla sunucunun metriklerini karşılaştırmak istediğinizde tablo paneli ideal. Örneğin 10 sunucunun CPU, RAM, disk değerlerini tek tabloda görmek:

# Tüm node'ların CPU kullanımı - panel sorgusu
# 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# Legend formatı: {{instance}}
# Bu sayede her satırda sunucu adı görünür

Table panel’de Transform özelliği çok güçlü. Birden fazla sorguyu join edip tek tabloda gösterebilirsiniz. A sorgusuna CPU, B sorgusuna RAM, C sorgusuna disk ekleyip “Join by field” transform ile sunucu adına göre birleştirebilirsiniz.

Logs Panel: Log Entegrasyonu

Eğer Loki kurduysanız Logs paneli ile Grafana’ya log akışı ekleyebilirsiniz. Metrik dashboard’unuzun altına bir log paneli eklemek, anomali gördüğünüzde hemen log’lara bakmanızı sağlar.

Gerçek Dünya Senaryosu: Linux Sunucu Dashboard’u

Haydi sıfırdan üretimde kullandığım bir dashboard oluşturalım. Bu dashboard Node Exporter metriklerini kullanıyor.

Row Organizasyonu

Dashboard’u row’lara bölerek organize edin:

  • Sistem Genel Bakış (Stat paneller, tek satır)
  • CPU Metrikleri
  • Bellek ve Swap
  • Disk I/O
  • Network

Her row collapsible yapılabilir. Sorun olmayan bölümleri daraltarak sadece kritik alanlara odaklanabilirsiniz.

CPU Dashboard Panelleri

# 1. Toplam CPU kullanımı (Time Series)
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle",instance=~"$instance"}[5m])) * 100)

# 2. CPU mod breakdown - user, system, iowait ayrı ayrı (Time Series, stacked)
rate(node_cpu_seconds_total{instance=~"$instance",mode!="idle"}[5m]) * 100

# 3. Load Average (Time Series)
node_load1{instance=~"$instance"}
node_load5{instance=~"$instance"}
node_load15{instance=~"$instance"}

# 4. CPU core sayısına göre normalize edilmiş load
node_load1{instance=~"$instance"} / count by (instance) (node_cpu_seconds_total{mode="idle",instance=~"$instance"})

Yukarıdaki sorgularda $instance değişkeni kullandığımı fark ettiniz. Bu Grafana’nın Template Variables özelliği. Tüm sunucular için tek dashboard kullanmanızı sağlar.

Template Variables Oluşturma

Dashboard Settings > Variables > Add variable:

# Variable tipi: Query
# Sorgu:
label_values(node_uname_info, instance)

# Bu sorgu tüm node'ların instance etiketlerini listeler
# Multi-value açık olursa birden fazla sunucu seçebilirsiniz
# Include All option ile tüm sunucuları bir anda görebilirsiniz

Variables oluşturduğunuzda dashboard’un üstünde dropdown menüler belirir. Tek dashboard ile tüm sunucu parkınızı izleyebilirsiniz.

Bellek Panelleri

# RAM kullanım yüzdesi (Gauge veya Stat)
(1 - (node_memory_MemAvailable_bytes{instance=~"$instance"} / node_memory_MemTotal_bytes{instance=~"$instance"})) * 100

# Detaylı bellek breakdown (Time Series)
node_memory_MemTotal_bytes{instance=~"$instance"}
node_memory_MemAvailable_bytes{instance=~"$instance"}
node_memory_Buffers_bytes{instance=~"$instance"}
node_memory_Cached_bytes{instance=~"$instance"}

# Swap kullanımı
(node_memory_SwapTotal_bytes{instance=~"$instance"} - node_memory_SwapFree_bytes{instance=~"$instance"}) / node_memory_SwapTotal_bytes{instance=~"$instance"} * 100

Pro tip: Bellek grafiğinde unit ayarını bytes yapın, percent değil. Grafana otomatik olarak GB, MB gibi uygun birime dönüştürür. Yüzde kullanırsanız 16 GB’ın yüzde 80’inin ne kadar olduğunu kafadan hesaplamak zorunda kalırsınız.

Disk I/O Panelleri

# Disk okuma/yazma hızı (bytes/s)
rate(node_disk_read_bytes_total{instance=~"$instance",device!~"dm-.*"}[5m])
rate(node_disk_written_bytes_total{instance=~"$instance",device!~"dm-.*"}[5m])

# IOPS
rate(node_disk_reads_completed_total{instance=~"$instance",device!~"dm-.*"}[5m])
rate(node_disk_writes_completed_total{instance=~"$instance",device!~"dm-.*"}[5m])

# Disk latency - bu kritik bir metrik!
rate(node_disk_read_time_seconds_total{instance=~"$instance"}[5m]) / rate(node_disk_reads_completed_total{instance=~"$instance"}[5m])

# Disk doluluk yüzdesi (tüm mount point'ler)
(node_filesystem_size_bytes{instance=~"$instance",fstype!~"tmpfs|fuse.lxcfs"} - node_filesystem_free_bytes{instance=~"$instance",fstype!~"tmpfs|fuse.lxcfs"}) / node_filesystem_size_bytes{instance=~"$instance",fstype!~"tmpfs|fuse.lxcfs"} * 100

Disk I/O grafiklerinde yazma değerlerini negatife çevirmek yaygın bir pratik. Böylece okuma yukarı, yazma aşağı gider ve ikisi birbirinden görsel olarak ayrışır. Bunu yapmak için yazma sorgusuna -1 çarpmanız yeterli.

PromQL Sorgularını Optimize Etme

Dashboard performansı için sorgu optimizasyonu kritik. Özellikle çok sayıda panel ve uzun time range’de yavaş sorgular Prometheus’u bunaltır.

# Kötü sorgu: her çağrıda tüm time series'i çeker
sum(node_cpu_seconds_total)

# İyi sorgu: önceden filtrele, sonra aggregate et
sum by (instance) (rate(node_cpu_seconds_total{mode!="idle",job="node"}[5m]))

# Recording rule kullan - sık kullanılan karmaşık sorguları önceden hesapla
# /etc/prometheus/rules/recording_rules.yml
cat << 'EOF' > /etc/prometheus/rules/recording_rules.yml
groups:
  - name: node_recording_rules
    interval: 15s
    rules:
      - record: job:node_cpu_usage:avg
        expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
      
      - record: job:node_memory_usage:ratio
        expr: 1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)
      
      - record: job:node_disk_read_rate:irate5m
        expr: irate(node_disk_read_bytes_total[5m])
EOF

# Config'i doğrula
promtool check rules /etc/prometheus/rules/recording_rules.yml

# Prometheus'u reload et
curl -X POST http://localhost:9090/-/reload

Recording rule’lar oluşturduktan sonra panellerde uzun PromQL sorguları yerine job:node_cpu_usage:avg gibi kısa isimleri kullanabilirsiniz. Dashboard hem daha hızlı yükler hem de sorgular daha okunaklı olur.

Alerting Kuralları ve Dashboard Entegrasyonu

Dashboard’lar sadece izleme değil, uyarı sistemi için de temel. Grafana’da panel üzerinden alert oluşturabilirsiniz ama ben daha güvenilir bulduğum için Prometheus alertmanager’ı tercih ediyorum. Yine de Grafana alerting’i basit senaryolar için hızlı çözüm sunuyor.

# Grafana API ile alert rule oluştur
curl -X POST 
  -H "Content-Type: application/json" 
  -d '{
    "orgId": 1,
    "name": "Yuksek CPU Kullanimi",
    "condition": "C",
    "data": [
      {
        "refId": "A",
        "queryType": "",
        "relativeTimeRange": {"from": 300, "to": 0},
        "datasourceUid": "prometheus",
        "model": {
          "expr": "100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)",
          "interval": "",
          "legendFormat": "{{instance}}"
        }
      },
      {
        "refId": "C",
        "queryType": "",
        "relativeTimeRange": {"from": 0, "to": 0},
        "datasourceUid": "__expr__",
        "model": {
          "conditions": [{"evaluator": {"params": [85], "type": "gt"}}],
          "refId": "C",
          "type": "classic_conditions"
        }
      }
    ],
    "noDataState": "NoData",
    "execErrState": "Error",
    "for": "5m",
    "annotations": {"summary": "CPU kullanimi %85 uzerinde"},
    "labels": {"severity": "warning"}
  }' 
  http://admin:sifre@localhost:3000/api/ruler/grafana/api/v1/rules/production

Dashboard’u JSON Olarak Yönetme

Dashboard’larınızı Git’te versiyonlamak hem backup hem de team collaboration açısından şart. Grafana her dashboard’u JSON formatında export/import destekliyor.

# Dashboard'u JSON olarak dışa aktar
curl -s http://admin:sifre@localhost:3000/api/dashboards/uid/sunucu-performans 
  | python3 -m json.tool > dashboard-sunucu-performans.json

# Tüm dashboard'ları backup script'i
#!/bin/bash
GRAFANA_URL="http://localhost:3000"
AUTH="admin:sifre"
BACKUP_DIR="/opt/grafana-backups/$(date +%Y%m%d)"

mkdir -p "$BACKUP_DIR"

# Tüm dashboard uid'lerini al
DASHBOARD_UIDS=$(curl -s -u "$AUTH" "$GRAFANA_URL/api/search?type=dash-db" | python3 -c "
import sys, json
data = json.load(sys.stdin)
for d in data:
    print(d['uid'])
")

for UID in $DASHBOARD_UIDS; do
  curl -s -u "$AUTH" "$GRAFANA_URL/api/dashboards/uid/$UID" 
    | python3 -m json.tool > "$BACKUP_DIR/dashboard-$UID.json"
  echo "Backup alindi: $UID"
done

echo "Toplam $(echo "$DASHBOARD_UIDS" | wc -l) dashboard backup edildi"

Bu script’i crontab’a ekleyerek günlük otomatik backup alabilirsiniz.

Dashboard’u Daha Etkili Kullanma: İpuçları

Annotations Kullanın

Deployment zamanlarını, bakım pencerelerini veya incident’ları grafik üzerinde işaretlemek için Annotations kullanın. “Bu spike neden oldu?” sorusunun cevabı genellikle o saatteki deployment’tır.

# API ile annotation ekle
curl -X POST 
  -H "Content-Type: application/json" 
  -d '{
    "dashboardUID": "sunucu-performans",
    "time": '"$(date +%s000)"',
    "tags": ["deployment", "production"],
    "text": "v2.4.1 production deploy - servis yeniden baslatildi"
  }' 
  http://admin:sifre@localhost:3000/api/annotations

Panel Link’leri

Bir panelden diğerine ya da external sisteme link eklemek navigation’ı hızlandırır. Örneğin bir sunucunun CPU grafiğinden o sunucunun detay dashboard’una link ekleyebilirsiniz. Panel settings > Panel links bölümünden yapılandırılır.

Grafana Provisioning ile Otomatik Kurulum

Dashboard’ları ve datasource’ları config dosyasından otomatik yüklemek için provisioning kullanın:

# /etc/grafana/provisioning/dashboards/default.yaml
cat << 'EOF' > /etc/grafana/provisioning/dashboards/default.yaml
apiVersion: 1
providers:
  - name: 'default'
    orgId: 1
    folder: 'Production'
    type: file
    disableDeletion: false
    updateIntervalSeconds: 30
    allowUiUpdates: true
    options:
      path: /var/lib/grafana/dashboards
      foldersFromFilesStructure: true
EOF

# Dashboard JSON dosyasını kopyala
sudo cp dashboard-sunucu-performans.json /var/lib/grafana/dashboards/

# Grafana restart
sudo systemctl restart grafana-server

Bu yapıyla yeni bir sunucu kurduğunuzda tek komutla tüm dashboard’larınız hazır oluyor.

Yaygın Hatalar ve Çözümleri

“No data” görünüyor ama metrikler Prometheus’ta var: Label selector’larını kontrol edin. instance=~"$instance" kullandığınızda variable’ın değeri gerçekten o label değeriyle eşleşiyor mu diye bakın. Explore menüsünden sorguyu test edin.

Dashboard yüklemesi çok yavaş: Panel sayısını azaltın veya time range’i kısaltın. Recording rule’ları kullanın. Çok sık refresh etmeyin. Dashboard’u birden fazla sayfaya bölmeyi düşünün.

Grafik değerleri mantıksız görünüyor: Unit ayarını kontrol edin. Bytes metriği için unit “bytes” olmalı, “short” değil. Ayrıca rate() fonksiyonu kullandığınızda değerlerin per-second olduğunu unutmayın.

Timezone sorunları: Dashboard timezone’unu browser yerine explicit timezone olarak ayarlayın. Özellikle farklı ülkelerde ekipler çalışıyorsa UTC kullanmak daha sağlıklı.

Sonuç

Grafana, ham Prometheus metriklerini gerçek anlamda işe yarar bilgiye dönüştürüyor. İyi tasarlanmış bir dashboard, sabah işe geldiğinizde 30 saniyede sistemin durumunu kavramanızı sağlar. Kötü tasarlanmış biri ise sizi daha da fazla karıştırır.

Bu yazıda anlattıklarımı özetlersek:

  • Veri kaynağı ve temel yapıyı doğru kurmak her şeyin temeli
  • Doğru panel tipini seçmek verinin anlaşılırlığını doğrudan etkiliyor
  • Template variables ile tek dashboard, tüm sunucu parkı
  • Recording rule’lar hem performans hem okunabilirlik için şart
  • Dashboard’ları JSON olarak versiyonlamak ve provisioning ile otomatik dağıtmak production ortamı için olmazsa olmaz

Başlangıç olarak Node Exporter için Grafana’nın kendi community hub’ında hazır dashboard’lar bulabilirsiniz. Dashboard ID 1860 (Node Exporter Full) mükemmel bir başlangıç noktası. Ama zamanla kendi ihtiyaçlarınıza göre özelleştirdiğiniz dashboard’lar çok daha değerli olacak. Çünkü siz sisteminizi en iyi tanıyan kişisiniz.

Benzer Konular

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir