InfluxDB ile Nginx Metriklerini İzleme

Nginx sunucunuzun ne kadar meşgul olduğunu, kaç isteği işlediğini ve bağlantı durumlarını gerçek zamanlı olarak takip etmek istiyorsanız doğru yerdesiniz. InfluxDB ile Nginx metriklerini birleştirmek, üretim ortamlarında trafik anomalilerini yakalamak ve kapasite planlaması yapmak için son derece etkili bir yöntem. Bu yazıda sıfırdan başlayarak Nginx stub status modülünden veri çekmeyi, Telegraf aracılığıyla InfluxDB’ye göndermeyi ve sonuçları anlamlı sorgularla yorumlamayı adım adım anlatacağım.

Genel Mimari

Kurulumdan önce büyük resmi görmek önemli. Şöyle bir akış söz konusu:

Nginx Stub Status -> Telegraf -> InfluxDB -> Grafana (opsiyonel)

Nginx, /nginx_status endpoint’i üzerinden anlık bağlantı ve istek istatistiklerini yayınlar. Telegraf bu endpoint’i belirli aralıklarla scrape eder ve InfluxDB’ye yazar. InfluxDB bu zaman serisi verisini saklar ve sorgulamaya hazır tutar. Grafana veya başka bir araç da bu veriyi görselleştirir.

Nginx Stub Status Modülünü Aktif Etme

Önce Nginx’in stub_status modülüyle derlenip derlenmediğini kontrol edelim:

nginx -V 2>&1 | grep -o with-http_stub_status_module

Çıktıda with-http_stub_status_module görüyorsanız hazırsınız. Göremiyorsanız, paket yöneticinizle yüklenen nginx genellikle bu modülle birlikte gelir. Ubuntu/Debian’da şöyle kontrol edebilirsiniz:

nginx -V 2>&1 | tr -- - 'n' | grep stub

Şimdi Nginx konfigürasyonuna status endpoint’ini ekleyelim. Ayrı bir konfigürasyon dosyası oluşturmak en temiz yol:

sudo nano /etc/nginx/conf.d/stub_status.conf

İçeriği şu şekilde yazın:

server {
    listen 127.0.0.1:8080;
    server_name localhost;

    location /nginx_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

Burada dikkat etmeniz gereken nokta: endpoint’i sadece localhost’a açıyoruz. Dışarıdan erişilebilir olmasının hiçbir anlamı yok ve güvenlik riski oluşturur. access_log off satırı da bu endpoint’in logları şişirmesini önler.

Konfigürasyonu test edip yeniden yükleyelim:

sudo nginx -t && sudo systemctl reload nginx

Şimdi çalışıp çalışmadığını doğrulayalım:

curl http://127.0.0.1:8080/nginx_status

Şuna benzer bir çıktı görmelisiniz:

Active connections: 42
server accepts handled requests
 15234 15234 48921
Reading: 0 Writing: 1 Waiting: 41

Bu sayıların ne anlama geldiğini bir kenara not edelim çünkü InfluxDB’de bu metriklerle çalışacağız:

  • Active connections: Şu an aktif olan toplam bağlantı sayısı
  • accepts: Toplam kabul edilen bağlantı sayısı (sunucu başlatıldığından beri)
  • handled: Başarıyla işlenen bağlantı sayısı
  • requests: İşlenen toplam HTTP istek sayısı
  • Reading: İstek header’ı okunmakta olan bağlantı sayısı
  • Writing: Cevap yazılmakta olan bağlantı sayısı
  • Waiting: Keep-alive bağlantılarında bekleyen istemci sayısı

InfluxDB Kurulumu

InfluxDB 2.x sürümünü kullanacağız. InfluxDB 1.x hala yaygın olsa da 2.x’in Flux sorgu dili ve web UI’ı çok daha kullanışlı.

# GPG anahtarını ekle
wget -q https://repos.influxdata.com/influxdata-archive_compat.key
echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' | sha256sum -c && cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null

# Repo ekle
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list

# Kur
sudo apt-get update && sudo apt-get install influxdb2 -y

# Başlat
sudo systemctl enable influxdb && sudo systemctl start influxdb

İlk kurulum sonrası InfluxDB’yi yapılandırmanız gerekiyor. Web arayüzüne http://sunucu-ip:8086 adresinden erişebilirsiniz ya da CLI kullanabilirsiniz:

influx setup 
  --username admin 
  --password GucluBirSifre123! 
  --org myorg 
  --bucket nginx-metrics 
  --retention 30d 
  --force

Bu komut şunları oluşturur:

  • admin: Yönetici kullanıcı
  • myorg: Organizasyon adı
  • nginx-metrics: Nginx verilerinin saklanacağı bucket
  • 30d: 30 günlük veri saklama süresi

Kurulum sonrası token’ı kaydedin. İlerleyen adımlarda lazım olacak:

influx auth list --user admin --hide-headers | awk '{print $3}'

Telegraf Kurulumu ve Konfigürasyonu

Telegraf, InfluxData’nın veri toplayıcısı. Nginx stub_status için hazır bir input plugin’i var, bu yüzden özel bir şey yazmamıza gerek yok.

sudo apt-get install telegraf -y

Telegraf’ı sıfırdan konfigüre etmek için varsayılan konfigürasyon dosyasını yedekleyip yenisini oluşturalım:

sudo mv /etc/telegraf/telegraf.conf /etc/telegraf/telegraf.conf.bak
sudo nano /etc/telegraf/telegraf.conf

Temel konfigürasyon şu şekilde:

[global_tags]
  environment = "production"
  server = "web-01"

[agent]
  interval = "10s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "2s"
  flush_interval = "10s"
  flush_jitter = "5s"
  precision = ""
  hostname = ""
  omit_hostname = false

# InfluxDB v2 output
[[outputs.influxdb_v2]]
  urls = ["http://127.0.0.1:8086"]
  token = "BURAYA_TOKEN_YAZIN"
  organization = "myorg"
  bucket = "nginx-metrics"

# Nginx input
[[inputs.nginx]]
  urls = ["http://127.0.0.1:8080/nginx_status"]
  response_timeout = "5s"

# Sistem metrikleri (opsiyonel ama tavsiye edilir)
[[inputs.cpu]]
  percpu = true
  totalcpu = true
  collect_cpu_time = false
  report_active = false

[[inputs.mem]]

[[inputs.disk]]
  ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"]

[[inputs.net]]
  interfaces = ["eth0", "ens3"]

global_tags bölümündeki environment ve server tag’leri çok değerli. Birden fazla sunucu izliyorsanız hangi verinin nereden geldiğini ayırt etmenizi sağlar.

Telegraf’ı başlatmadan önce konfigürasyonu test edelim:

telegraf --config /etc/telegraf/telegraf.conf --test

Hata yoksa çıktıda nginx measurement’larını görmelisiniz. Başlatalım:

sudo systemctl enable telegraf && sudo systemctl start telegraf

Logları takip ederek sorun var mı kontrol edelim:

sudo journalctl -u telegraf -f

InfluxDB’de Verileri Doğrulama

Birkaç dakika bekledikten sonra InfluxDB’ye veri gelip gelmediğini kontrol edelim:

influx query '
from(bucket: "nginx-metrics")
  |> range(start: -5m)
  |> filter(fn: (r) => r._measurement == "nginx")
  |> limit(n: 10)
'

Çıktıda şuna benzer satırlar görmelisiniz:

_measurement  _field              _value  _time
nginx         active              42      2024-01-15T10:23:10Z
nginx         accepts             15234   2024-01-15T10:23:10Z
nginx         handled             15234   2024-01-15T10:23:10Z
nginx         requests            48921   2024-01-15T10:23:10Z
nginx         reading             0       2024-01-15T10:23:10Z
nginx         writing             1       2024-01-15T10:23:10Z
nginx         waiting             41      2024-01-15T10:23:10Z

Mükemmel, veriler geliyor.

Gerçek Dünya Sorguları

Şimdi asıl faydalı kısma geldik. Üretim ortamında sık kullandığım Flux sorgularını paylaşacağım.

Saniye Başına İstek Sayısı (RPS)

Nginx stub_status kümülatif değerler döndürür, yani toplam sayıları gösterir. RPS hesaplamak için türev almak gerekiyor:

influx query '
from(bucket: "nginx-metrics")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "nginx" and r._field == "requests")
  |> derivative(unit: 1s, nonNegative: true)
  |> yield(name: "requests_per_second")
'

nonNegative: true parametresi çok önemli. Nginx yeniden başlatıldığında sayaçlar sıfırlanır ve bu negatif bir türev üretir. Bu parametre o durumu filtreler.

Aktif Bağlantı Trendi

Son 24 saat boyunca 5 dakikalık ortalamalar:

influx query '
from(bucket: "nginx-metrics")
  |> range(start: -24h)
  |> filter(fn: (r) => r._measurement == "nginx" and r._field == "active")
  |> aggregateWindow(every: 5m, fn: mean, createEmpty: false)
  |> yield(name: "active_connections_avg")
'

Keep-Alive Bağlantı Oranı

Waiting bağlantıların aktif bağlantılara oranı keep-alive verimliliğini gösterir. Bu oran yüksekse keep-alive çalışıyor demektir:

influx query '
from(bucket: "nginx-metrics")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "nginx")
  |> filter(fn: (r) => r._field == "waiting" or r._field == "active")
  |> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> map(fn: (r) => ({r with keepalive_ratio: float(v: r.waiting) / float(v: r.active) * 100.0}))
  |> keep(columns: ["_time", "keepalive_ratio"])
'

Anlık Sunucu Durumu

Şu anki durumu özetleyen tek satırlık sorgu:

influx query '
from(bucket: "nginx-metrics")
  |> range(start: -1m)
  |> filter(fn: (r) => r._measurement == "nginx")
  |> last()
  |> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
'

Alerting Kuralları Oluşturma

Veri toplamak güzel ama uyarı almadan izlemenin bir anlamı yok. InfluxDB 2.x’in yerleşik alerting sistemi var.

Yüksek Aktif Bağlantı Uyarısı

influx query '
from(bucket: "nginx-metrics")
  |> range(start: -5m)
  |> filter(fn: (r) => r._measurement == "nginx" and r._field == "active")
  |> mean()
  |> map(fn: (r) => ({
      r with
      _level: if r._value > 500 then "critical"
              else if r._value > 300 then "warning"
              else "ok"
  }))
'

InfluxDB UI üzerinden bu sorguyu bir Check olarak kaydedebilir ve Slack, email veya webhook üzerinden bildirim gönderebilirsiniz. UI’da Alerting > Checks > Create Check yolunu izleyin.

Telegram ile Bildirim

Birçok ekip Slack yerine Telegram kullanıyor. InfluxDB HTTP endpoint notification rule’unu Telegram Bot API ile entegre etmek için şu endpoint’i kullanabilirsiniz:

# Test amaçlı Telegram mesajı gönderme
curl -s -X POST 
  "https://api.telegram.org/botBOT_TOKEN/sendMessage" 
  -d chat_id="CHAT_ID" 
  -d text="UYARI: Nginx aktif bağlantı sayısı 500'ü aştı!"

InfluxDB notification endpoint’i olarak https://api.telegram.org/botBOT_TOKEN/sendMessage adresini ekleyebilirsiniz.

Log Tabanlı Metrikler ile Zenginleştirme

Stub_status sınırlı veri sağlar. HTTP durum kodu dağılımı, yanıt süreleri gibi detaylı metrikleri almak için Nginx log formatını zenginleştirip Telegraf’ın logparser veya tail plugin’ini kullanabilirsiniz.

Önce Nginx log formatını güncelleyelim:

sudo nano /etc/nginx/nginx.conf

http bloğuna şunu ekleyin:

log_format metrics '$remote_addr - $remote_user [$time_local] '
                   '"$request" $status $body_bytes_sent '
                   '"$http_referer" "$http_user_agent" '
                   'rt=$request_time uct=$upstream_connect_time '
                   'uht=$upstream_header_time urt=$upstream_response_time';

access_log /var/log/nginx/access.log metrics;

Şimdi Telegraf konfigürasyonuna tail input’unu ekleyelim:

[[inputs.tail]]
  files = ["/var/log/nginx/access.log"]
  from_beginning = false
  pipe = false
  data_format = "grok"
  grok_patterns = ["%{COMBINED_LOG_FORMAT} rt=%{NUMBER:request_time:float} uct=%{NUMBER:upstream_connect_time:float} uht=%{NUMBER:upstream_header_time:float} urt=%{NUMBER:upstream_response_time:float}"]
  name_override = "nginx_access"
  [inputs.tail.tags]
    log_type = "access"

Bu sayede HTTP status kodlarını, yanıt sürelerini ve upstream bağlantı sürelerini de takip edebilirsiniz.

Çoklu Nginx Sunucusu İzleme

Birden fazla Nginx sunucusu varsa her birine Telegraf kurmak yerine merkezi bir Telegraf instance’ından scrape edebilirsiniz. Ama bu durumda uzak sunucularda stub_status’u dışarıya açmanız gerekir, bu da güvenlik riski demektir. En doğru yöntem her sunucuya Telegraf kurup ortak InfluxDB’ye yazmak.

Her sunucunun telegraf.conf dosyasında global_tags’i farklı tutun:

# web-01 sunucusu için
[global_tags]
  environment = "production"
  server = "web-01"
  datacenter = "istanbul"

# web-02 sunucusu için
[global_tags]
  environment = "production"
  server = "web-02"
  datacenter = "ankara"

Sonra InfluxDB’de sunucuya göre filtreleyin:

influx query '
from(bucket: "nginx-metrics")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "nginx")
  |> filter(fn: (r) => r.server == "web-01")
  |> filter(fn: (r) => r._field == "active")
  |> aggregateWindow(every: 1m, fn: max)
'

Veri Saklama ve Downsampling

30 günlük ham veri çok yer kaplar. Eski veriler için downsampling yaparak hem disk tasarrufu sağlayabilir hem de uzun vadeli trendleri koruyabilirsiniz.

InfluxDB’de Task oluşturarak bunu otomatikleştirebilirsiniz:

influx task create --name "nginx-downsampling" --file - << 'EOF'
option task = {name: "nginx-downsampling", every: 1h}

from(bucket: "nginx-metrics")
  |> range(start: -2h, stop: -1h)
  |> filter(fn: (r) => r._measurement == "nginx")
  |> aggregateWindow(every: 5m, fn: mean, createEmpty: false)
  |> to(bucket: "nginx-metrics-downsampled", org: "myorg")
EOF

Bu task her saat çalışır ve bir önceki saatin verisini 5 dakikalık ortalamalar olarak başka bir bucket’a yazar. Ana bucket’ta veriyi 7 gün, downsampled bucket’ta 90 gün saklayabilirsiniz.

Performans Optimizasyonu

InfluxDB yoğun yazma yüklerinde yavaşlayabilir. Birkaç pratik öneri:

  • Batch size artırın: Telegraf’ta metric_batch_size = 5000 yaparak ağ round-trip sayısını azaltın
  • Collection interval’ı dengeleyin: 10 saniye genellikle iyi bir noktadır. 1 saniye yapmak gereksiz yük oluşturur
  • Tag kardinalitesi düşük tutun: Her kullanıcı için ayrı tag oluşturmak gibi hatalardan kaçının. Tag değerleri sabit ve az sayıda olmalı
  • Disk I/O izleyin: InfluxDB yazma yoğun bir veritabanıdır, SSD şiddetle tavsiye edilir
  • Shard duration ayarı: Kısa süreli bucket’lar için shard duration’ı düşürün:
influx bucket update 
  --name nginx-metrics 
  --shard-group-duration 1d

Sorun Giderme

Yaygın sorunlar ve çözümleri:

Telegraf veri göndermiyor:

# Token geçerliliğini kontrol et
influx auth list

# Telegraf debug modunda çalıştır
telegraf --config /etc/telegraf/telegraf.conf --debug --test

Nginx status endpoint erişilemiyor:

# Port dinleniyor mu?
ss -tlnp | grep 8080

# Nginx konfigürasyon hatası var mı?
sudo nginx -t

InfluxDB disk dolu:

# Bucket boyutlarını kontrol et
influx bucket list

# Eski verileri sil (dikkatli kullanın!)
influx delete 
  --bucket nginx-metrics 
  --start 1970-01-01T00:00:00Z 
  --stop 2024-01-01T00:00:00Z 
  --predicate '_measurement="nginx"'

Sonuç

InfluxDB ile Nginx metriklerini izlemek başta karmaşık görünebilir ama bir kez kurulumunu tamamladıktan sonra gerçekten güçlü bir gözlemlenebilirlik katmanı elde ediyorsunuz. Stub_status’un sağladığı temel metrikler anlık trafik durumunu takip etmek için yeterli, log tabanlı metriklerle de HTTP durum kodu dağılımı ve yanıt süresi gibi detaylara inebiliyorsunuz.

Üretim ortamında şu üç şeye mutlaka dikkat edin: stub_status endpoint’ini asla dışarıya açmayın, tag kardinalitesini düşük tutun ve veri saklama politikası belirleyin. Bunları doğru kurduğunuzda aylarca sorunsuz çalışan, anomalileri önceden yakalayan bir izleme sisteminiz olur.

Grafana tarafını da eklemek isteyenler için bir sonraki yazıda InfluxDB datasource’unu Grafana’ya bağlamayı ve Nginx için hazır dashboard oluşturmayı ele alacağım.

Bir yanıt yazın

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