Production ortamında bir Nginx sunucusu çalıştırıyorsunuz, trafik geliyor, istekler işleniyor. Peki sunucunuzun gerçekten sağlıklı olup olmadığını, kaç isteği reddettiğini, yanıt sürelerinin ne durumda olduğunu biliyor musunuz? “Bir şeyler ters gidince bakarız” yaklaşımı sysadmin’in en büyük düşmanıdır. Bu yazıda Nginx metriklerini Prometheus ile toplamayı ve Grafana üzerinde anlamlı dashboardlar oluşturmayı adım adım ele alacağız.
Genel Mimariyi Anlamak
Önce büyük resmi görelim. Bu izleme zinciri şu şekilde çalışır:
- Nginx:
stub_statusmodülü ile temel metrikler sunar veyanginx-prometheus-exporterdaha zengin veri sağlar - Prometheus Exporter: Nginx’ten metrikleri çekip Prometheus’un anlayacağı formata çevirir
- Prometheus: Metrikleri düzenli aralıklarla “scrape” eder ve zaman serisi veritabanında saklar
- Grafana: Prometheus’u veri kaynağı olarak kullanarak görselleştirme yapar
Bu zincirde en kritik halka exporter katmanıdır. Nginx kendi başına Prometheus formatında veri üretmez, bu yüzden bir aracıya ihtiyaç duyarız.
Nginx Stub Status Modülünü Aktif Etmek
Her şeyden önce Nginx’in stub_status modülünün aktif olup olmadığını kontrol edin:
nginx -V 2>&1 | grep -o with-http_stub_status_module
Eğer çıktı with-http_stub_status_module dönüyorsa hazırsınız. Ubuntu/Debian üzerinde nginx paketi genellikle bu modülle birlikte gelir. CentOS/RHEL için nginx resmi reposundan kurulum yapmanızı öneririm.
Şimdi Nginx konfigürasyonuna stub_status endpoint’i ekleyelim:
sudo nano /etc/nginx/conf.d/stub_status.conf
server {
listen 127.0.0.1:8080;
server_name localhost;
location /nginx_status {
stub_status on;
access_log off;
# Sadece localhost ve monitoring sunucusuna izin ver
allow 127.0.0.1;
allow 10.0.0.0/8; # İç ağ subnet'iniz
deny all;
}
}
Bu konfigürasyonda dikkat edilmesi gereken nokta: stub_status endpoint’ini public internete açmayın. Sadece monitoring sunucunuzun IP’sine izin verin. Konfigürasyonu test edip reload edelim:
sudo nginx -t && sudo systemctl reload nginx
Endpoint’in çalıştığını doğrulayalım:
curl http://127.0.0.1:8080/nginx_status
Çıktı şöyle görünmeli:
Active connections: 42
server accepts handled requests
1024 1024 8192
Reading: 2 Writing: 5 Waiting: 35
Bu ham veriler Prometheus için uygun değil, burada exporter devreye giriyor.
Nginx Prometheus Exporter Kurulumu
nginx-prometheus-exporter, Nginx’in stub_status çıktısını Prometheus formatına dönüştüren hafif bir Go uygulamasıdır. GitHub üzerinden binary olarak indirip kullanabiliriz.
# En güncel versiyonu GitHub'dan kontrol edin
cd /tmp
wget https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v1.1.0/nginx-prometheus-exporter_1.1.0_linux_amd64.tar.gz
tar -xzf nginx-prometheus-exporter_1.1.0_linux_amd64.tar.gz
sudo mv nginx-prometheus-exporter /usr/local/bin/
sudo chmod +x /usr/local/bin/nginx-prometheus-exporter
Exporter’ı sistemd servisi olarak çalıştıralım:
sudo nano /etc/systemd/system/nginx-prometheus-exporter.service
[Unit]
Description=Nginx Prometheus Exporter
After=network.target
[Service]
Type=simple
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/nginx-prometheus-exporter
-nginx.scrape-uri=http://127.0.0.1:8080/nginx_status
-web.listen-address=:9113
-web.telemetry-path=/metrics
Restart=on-failure
RestartSec=5s
NoNewPrivileges=yes
ProtectHome=yes
ProtectSystem=strict
[Install]
WantedBy=multi-user.target
Prometheus kullanıcısı mevcut değilse oluşturun:
sudo useradd --no-create-home --shell /bin/false prometheus
sudo systemctl daemon-reload
sudo systemctl enable --now nginx-prometheus-exporter
sudo systemctl status nginx-prometheus-exporter
Exporter’ın metrik üretip üretmediğini kontrol edin:
curl http://localhost:9113/metrics | head -30
nginx_connections_active, nginx_http_requests_total gibi metrikler görüyorsanız her şey yolunda demektir.
Prometheus Kurulumu ve Konfigürasyonu
Eğer ortamınızda Prometheus zaten varsa bu bölümü atlayabilirsiniz. Yoksa hızlıca kuralım:
cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v2.48.0/prometheus-2.48.0.linux-amd64.tar.gz
tar -xzf prometheus-2.48.0.linux-amd64.tar.gz
sudo cp prometheus-2.48.0.linux-amd64/prometheus /usr/local/bin/
sudo cp prometheus-2.48.0.linux-amd64/promtool /usr/local/bin/
sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo cp -r prometheus-2.48.0.linux-amd64/consoles /etc/prometheus/
sudo cp -r prometheus-2.48.0.linux-amd64/console_libraries /etc/prometheus/
sudo chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus
Prometheus ana konfigürasyon dosyasını düzenleyelim:
sudo nano /etc/prometheus/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_timeout: 10s
alerting:
alertmanagers:
- static_configs:
- targets: []
rule_files: []
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'nginx'
static_configs:
- targets: ['localhost:9113']
metrics_path: /metrics
scrape_interval: 10s
# Nginx sunucusunu etiketle
relabel_configs:
- source_labels: [__address__]
target_label: instance
replacement: 'web-server-01'
Birden fazla Nginx sunucusu izliyorsanız targets listesini genişletin:
- job_name: 'nginx'
static_configs:
- targets:
- '10.0.0.10:9113'
- '10.0.0.11:9113'
- '10.0.0.12:9113'
metrics_path: /metrics
scrape_interval: 10s
Konfigürasyonu doğrulayın:
promtool check config /etc/prometheus/prometheus.yml
Prometheus’u systemd servisi olarak başlatın ve birkaç dakika bekledikten sonra http://sunucu-ip:9090/targets adresinden scrape durumunu kontrol edin. Nginx job’ının “UP” durumunda olması gerekiyor.
Gerçek Dünya Senaryosu: Çoklu Nginx Instance İzleme
Diyelim ki yük dengeleyici arkasında 3 adet uygulama sunucusu var. Her birinde Nginx çalışıyor ve farklı servislere proxy yapıyor. Bu durumda her sunucuya exporter kurup Prometheus’a ekliyoruz, ancak etiketleri doğru yönetmek kritik:
- job_name: 'nginx-web-cluster'
static_configs:
- targets: ['10.0.1.10:9113']
labels:
environment: 'production'
role: 'frontend'
datacenter: 'istanbul-dc1'
- targets: ['10.0.1.11:9113']
labels:
environment: 'production'
role: 'api-gateway'
datacenter: 'istanbul-dc1'
- targets: ['10.0.1.12:9113']
labels:
environment: 'staging'
role: 'frontend'
datacenter: 'ankara-dc2'
Bu etiket yapısı Grafana’da filtreleme ve karşılaştırma yapmayı çok kolaylaştırır.
Grafana Kurulumu
# Ubuntu/Debian için
sudo apt-get install -y apt-transport-https software-properties-common
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt-get update && sudo apt-get install grafana
sudo systemctl enable --now grafana-server
Grafana varsayılan olarak 3000 portunda çalışır. İlk giriş için admin/admin kullanıcı adı ve şifresiyle giriş yapın, ardından şifreyi değiştirmeyi unutmayın.
Prometheus Veri Kaynağı Ekleme
Grafana web arayüzünde:
- Sol menüden Connections > Data Sources seçin
- Add data source butonuna tıklayın
- Prometheus’u seçin
- URL alanına
http://localhost:9090girin (Prometheus aynı sunucudaysa) - Save & Test butonuna basın
Yeşil “Data source is working” mesajı görmelisiniz.
Grafana’da Nginx Dashboard Oluşturma
Grafana’nın hazır dashboard ekosistemi çok güçlü. Nginx için en popüler dashboard ID’si 9614‘tür (NGINX Prometheus Exporter). Bunu import etmek için:
- Sol menüden Dashboards > Import seçin
- Import via grafana.com alanına
9614yazın - Load butonuna basın
- Veri kaynağı olarak eklediğiniz Prometheus’u seçin
- Import edin
Bu hazır dashboard ile anında birçok metriği görebilirsiniz. Ancak production ortamı için özelleştirilmiş paneller oluşturmanızı öneririm.
Kritik PromQL Sorguları
Grafana panel oluştururken kullanacağınız PromQL sorgularını paylaşayım:
Saniyedeki istek sayısı (RPS):
rate(nginx_http_requests_total[5m])
Aktif bağlantı sayısı:
nginx_connections_active
Bağlantı durumlarına göre breakdown:
nginx_connections_reading
nginx_connections_writing
nginx_connections_waiting
Son 1 saatteki toplam istekler:
increase(nginx_http_requests_total[1h])
Accept oranı ile handled oranı karşılaştırması (drop’ları yakalar):
rate(nginx_connections_accepted_total[5m])
rate(nginx_connections_handled_total[5m])
Bu iki değer arasındaki fark, düşürülen bağlantı sayısını gösterir. Production’da bu farkın sıfır olması gerekir. Fark varsa worker_connections limitine takılıyorsunuzdur.
Alerting: Kritik Uyarılar Oluşturma
Görselleştirme güzel ama asıl önemli olan sorunları erkenden yakalamak. Prometheus’a alert kuralları ekleyelim:
sudo nano /etc/prometheus/nginx_alerts.yml
groups:
- name: nginx_alerts
interval: 30s
rules:
- alert: NginxDown
expr: nginx_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Nginx servis durdu - {{ $labels.instance }}"
description: "{{ $labels.instance }} üzerindeki Nginx 1 dakikadır yanıt vermiyor."
- alert: NginxHighConnectionDrop
expr: rate(nginx_connections_accepted_total[5m]) - rate(nginx_connections_handled_total[5m]) > 0
for: 2m
labels:
severity: warning
annotations:
summary: "Nginx bağlantı kaybı tespit edildi"
description: "Saniyede {{ $value }} bağlantı düşürülüyor. worker_connections limitini kontrol edin."
- alert: NginxHighActiveConnections
expr: nginx_connections_active > 1000
for: 5m
labels:
severity: warning
annotations:
summary: "Nginx aktif bağlantı sayısı yüksek"
description: "Aktif bağlantı sayısı {{ $value }} seviyesinde. Kapasite planlaması gerekebilir."
- alert: NginxRequestRateSpike
expr: rate(nginx_http_requests_total[5m]) > 10000
for: 3m
labels:
severity: warning
annotations:
summary: "Nginx istek oranı spike yapıyor"
description: "Saniyede {{ $value }} istek geliyor. DDoS veya anormal trafik olabilir."
Bu kural dosyasını prometheus.yml‘e ekleyin:
rule_files:
- /etc/prometheus/nginx_alerts.yml
Prometheus’u reload edin:
sudo systemctl reload prometheus
# veya
curl -X POST http://localhost:9090/-/reload
Nginx Log’larını da İşin İçine Katmak
Stub_status sadece toplam sayıları verir, HTTP durum kodlarına göre breakdown görmez. Bunun için iki seçeneğiniz var:
1. Seçenek: Nginx Plus (ticari, extended status)
2. Seçenek: VTS modülü (nginx-module-vts, community)
VTS modülü varsa çok daha zengin metrikler elde edersiniz. Ubuntu’da şöyle kurabilirsiniz:
sudo apt-get install libnginx-mod-http-vhost-traffic-status
Nginx konfigürasyonuna ekleyin:
http {
vhost_traffic_status_zone;
server {
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format prometheus;
allow 127.0.0.1;
deny all;
}
}
}
Bu durumda exporter’a gerek kalmaz, doğrudan Prometheus /status endpoint’ini scrape edebilir. Bu metriklerle durum kodu bazlı hata oranı gibi kritik göstergeleri izleyebilirsiniz.
Grafana Dashboard’ını Özelleştirmek
İyi bir Nginx dashboard’u şu panelleri içermelidir:
- RPS (Request Per Second): Anlık yük durumu
- Aktif Bağlantılar: Zaman serisi grafiği, peak’leri görmek için
- Reading/Writing/Waiting: Bağlantı durumu dağılımı (stacked area)
- Accepted vs Handled: Drop rate tespiti için
- Uptime: Nginx’in ne zamandır ayakta olduğu
- Alert durumu: Hangi alertların aktif olduğu
Her panel için Stat, Time series, Gauge widget tiplerini duruma göre kullanın. Anlık değerler için Stat, trend analizi için Time series idealdir.
Panel düzenleme sırasında şu ayarlara dikkat edin:
- Thresholds: Kritik değerlere kırmızı renk atayin (örneğin aktif bağlantı 800’ü geçince sarı, 1000’i geçince kırmızı)
- Alert rules: Panel bazında Grafana alert’ı da ekleyebilirsiniz
- Refresh interval: Production dashboard’ları için 30 saniye makul bir değer
Güvenlik Notları
Bu kurulumda dikkat etmeniz gereken birkaç güvenlik konusu var:
- stub_status endpoint’i: Kesinlikle sadece internal ağa açın, nginx.conf üzerindeki
allow/denydirektiflerini doğru yapılandırın - Exporter portu (9113): Firewall’da sadece Prometheus sunucusunun erişimine izin verin
- Prometheus (9090): Dışarıya açmayın, Grafana’nın internal’dan erişmesi yeterli
- Grafana (3000): Reverse proxy arkasına alın, HTTPS kullanın
# UFW ile exporter'ı sadece Prometheus sunucusuna aç
sudo ufw allow from 10.0.0.5 to any port 9113 comment 'Prometheus scrape'
sudo ufw deny 9113
Sorun Giderme
Kurulum sürecinde sık karşılaşılan sorunlar:
Exporter “connection refused” hatası veriyorsa:
# stub_status'ün dinlediği portu kontrol et
ss -tlnp | grep 8080
# Nginx konfigürasyonunu test et
sudo nginx -t
# Exporter loglarına bak
sudo journalctl -u nginx-prometheus-exporter -f
Prometheus’ta target “DOWN” görünüyorsa:
# Exporter'ın ayakta olup olmadığını kontrol et
curl http://localhost:9113/metrics
# Firewall kurallarını kontrol et
sudo iptables -L -n | grep 9113
Grafana’da “No data” görünüyorsa:
# Prometheus'ta metriğin var olduğunu doğrula
curl 'http://localhost:9090/api/v1/query?query=nginx_connections_active'
# Zaman aralığını ve job adını kontrol et
Sonuç
Nginx’i Prometheus ve Grafana ile izlemek başlangıçta birkaç kurulum adımı gerektirse de kazanımları çok büyük. Artık sunucunuzda neler döndüğünü gerçek zamanlı görüyor, anormalliklerden anında haberdar oluyorsunuz. “Müşteri şikayet etti, biz de fark ettik” dönemini geride bırakıyorsunuz.
Bu mimarinin güzel yanı ölçeklenebilirliği: 1 sunucu izlemek için kurduğunuz yapıya 50 sunucu eklemek sadece Prometheus konfigürasyonuna birkaç satır eklemek anlamına geliyor. Etiket sistemi sayesinde ortam, lokasyon, rol gibi boyutlarda filtreleme yapabiliyorsunuz.
Bir sonraki adım olarak blackbox_exporter ile HTTP endpoint kontrolü ve alertmanager ile Slack/PagerDuty entegrasyonu kurmanızı öneririm. O zaman gerçekten proaktif bir izleme altyapısına kavuşmuş olursunuz. Production’da “her şey yolunda” demek için ekranda yeşil ışıklar yanıyor olmalı, tahminlere değil.