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 = 5000yaparak 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.
