Skip to content
Bloga dön
Teknoloji Nginx Log Analizi Sistem Yönetimi Linux DevOps

Nginx Log Analizi: Access ve Error Loglarını Okuma, Anlama ve Otomatize Etme Rehberi

Nginx web sunucusunun access ve error loglarını detaylı bir şekilde inceleyerek performans optimizasyonu, güvenlik açığı tespiti ve hata ayıklama süreçlerini sahada uygulanabilir yöntemlerle ele alıyoruz.

Caner Serbest

Sistem ve Altyapı

5 dk okuma

Nginx Log Analizi: Access ve Error Logları ile Sistem Görünürlüğü

Sistem yöneticileri ve DevOps mühendisleri olarak günlük mesaimizin büyük bir kısmı, çalışan sistemlerin sağlığını korumak ve olası aksaklıkları önceden tespit etmekle geçer. Canlı (production) ortamda koşan bir uygulamanın arkasında duran web sunucusu, bize sistemin nabzını tutan en değerli veriyi sağlar: Loglar.

Nginx, yüksek performanslı yapısı ve düşük kaynak tüketimi sayesinde modern web altyapılarının omurgasını oluşturur. Ancak Nginx’i kurup varsayılan ayarlarla çalıştırmak işin sadece ilk adımıdır. Gerçek operasyonel olgunluk, bu sunucunun ürettiği logları doğru okumak, anlamlandırmak ve olası krizleri loglar üzerinden henüz büyümeden yakalamakla başlar.

Bu yazıda, Nginx access (erişim) ve error (hata) loglarının yapısını inceleyecek, log formatlarını özelleştirecek ve komut satırı araçlarıyla pratik log analizi senaryolarını ele alacağız.


1. Nginx Loglarının Anatomisi

Nginx varsayılan olarak iki tür log dosyası üretir:

  • Access Log: Sunucuya gelen her bir HTTP isteğini kaydeder.
  • Error Log: Nginx’in çalıştırma süreçlerindeki hataları, uyarıları ve kritik durumları kaydeder.

Bu dosyalar tipik olarak Linux sistemlerde /var/log/nginx/ dizini altında yer alır. Birinci adım, bu dosyaların içinde ne yazdığını anlamaktır.

Varsayılan Access Log Formatı (combined)

Nginx yapılandırma dosyasında (/etc/nginx/nginx.conf), log_format yönergesi ile logların nasıl yazılacağı belirlenir. Varsayılan olarak gelen combined formatı şu şekildedir:

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

Bu satırdaki alanları tek tek inceleyelim:

  • $remote_addr: İsteği yapan istemcinin (client) IP adresi.
  • $remote_user: HTTP temel kimlik doğrulaması (Basic Auth) kullanılıyorsa kullanıcı adı.
  • [$time_local]: İsteğin ulaştığı tarih ve saat.
  • "$request": HTTP metodu (GET, POST vb.), istenen URI ve kullanılan protokol (HTTP/1.1, HTTP/2).
  • $status: Sunucunun döndürdüğü HTTP durum kodu (200, 404, 500 vb.).
  • $body_bytes_sent: İstemciye gönderilen gövdenin bayt cinsinden boyutu (headerlar hariç).
  • "$http_referer": Kullanıcının bu sayfaya gelmesini sağlayan önceki sayfanın adresi.
  • "$http_user_agent": İstemcinin tarayıcı ve işletim sistemi bilgisi.

2. Özel Log Formatı Oluşturma ve JSON Loglama

Varsayılan log formatı birçok senaryoda yeterlidir ancak modern log toplama araçları (Elasticsearch, Loki, Fluentd vb.) ile çalışırken JSON formatı büyük avantaj sağlar. JSON formatındaki loglar, regex ile uğraşmadan doğrudan parse edilebilir.

/etc/nginx/nginx.conf dosyası içerisindeki http bloğuna şu özel log formatını ekleyebiliriz:

http {
    log_format json_escape escape=json
      '{"$time_local": "$time_local",'
      '"remote_addr": "$remote_addr",'
      '"request": "$request",'
      '"status": "$status",'
      '"body_bytes_sent": "$body_bytes_sent",'
      '"request_time": "$request_time",'
      '"http_referrer": "$http_referer",'
      '"http_user_agent": "$http_user_agent"}';

    server {
        access_log /var/log/nginx/access_json.log json_escape;
    }
}

Bu yapılandırmada ek olarak $request_time değişkenini ekledik. Bu değişken, isteğin alınmasından yanıtın istemciye gönderilmesine kadar geçen süreyi saniye cinsinden (milisaniye hassasiyetinde) gösterir. Performans darboğazlarını bulmak için bu alan kritik önem taşır.


3. Komut Satırından Hızlı Log Analizi Senaryoları

Her zaman gelişmiş log yönetim sistemlerine sahip olmayabiliriz. SSH ile sunucuya bağlandığımızda awk, grep, sort ve uniq gibi standart Linux araçlarıyla anlık analizler yapabilmek bir sistem yöneticisinin en temel becerisidir.

Senaryo A: En Çok İstek Gönderen IP Adreslerini Bulma

Bir DDoS saldırısı veya web scraping faaliyeti şüphesi olduğunda, en çok istek yapan IP’leri görmek ilk adımdır:

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10

Açıklama:

  1. awk '{print $1}': Log satırındaki ilk alanı (yani IP adresini) alır.
  2. sort: IP adreslerini alfabetik olarak sıralar.
  3. uniq -c: Aynı IP’leri sayarak kaçar kez geçtiğini önüne yazar.
  4. sort -nr: Sayılara göre azalan sırada (büyükten küçüğe) sıralar.
  5. head -n 10: En üstteki ilk 10 kaydı gösterir.

Senaryo B: HTTP Durum Kodlarının Dağılımını Görme

Sistemde ani bir hata artışı (örneğin 502 Bad Gateway veya 404 Not Found patlaması) olup olmadığını görmek için:

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

Burada $9 alanı genellikle HTTP durum kodunu tutar (eğer özel format kullanılmadıysa ve log formatındaki boşluklara göre index değişmediyse). Güvenli olması adına, durum kodunun her zaman nerede geçtiğini bilmek veya JSON formatı kullanmak daha sağlıklıdır.

Senaryo C: En Yavaş Yanıt Veren İstekleri Listeleme

Eğer log formatımızda $request_time değişkeni varsa, en uzun süren istekleri şu şekilde bulabiliriz (örneğin özel bir log formatı kullanıldığını varsayalım):

awk '($NF > 1.0) {print $0}' /var/log/nginx/access_json.log

Bu komut, yanıt süresi 1 saniyenin üzerinde olan istekleri ekrana basar.


4. Error Log Yönetimi ve Kritik Hatalar

Nginx error logları, sistemin arka planda yaşadığı problemleri anlamak için hayati önem taşır. Error log seviyeleri (log levels) şunlardır: debug, info, notice, warn, error, crit, alert, emerg.

Üretim ortamında genellikle error veya crit seviyesi tercih edilir. debug seviyesi disk alanını çok hızlı dolduracağı ve performansı düşüreceği için sadece test ortamlarında kullanılmalıdır.

Sık Karşılaşılan Error Log Örnekleri ve Anlamları

  1. Permission Denied Hatası:

    2024/03/24 10:15:00 [crit] 12345#12345: *1 stat() "/usr/share/nginx/html/index.html" failed (13: Permission denied)

    Çözm: Nginx worker sürecini çalıştıran kullanıcının (genellikle www-data veya nginx), ilgili dosya veya dizin üzerinde okuma iznine sahip olmadığını gösterir. chown veya chmod komutlarıyla izinler düzenlenmelidir.

  2. Upstream Bağlantı Hatası (502 Bad Gateway):

    2024/03/24 10:18:22 [error] 12345#12345: *15 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.1.50...

    Çözüm: Nginx’in yönlendirmeye çalıştığı arka uç uygulamanın (örneğin 3000 portunda koşan Node.js uygulaması veya PHP-FPM) ayakta olmadığını veya ilgili portu dinlemediğini gösterir.

  3. Worker Bağlantı Limiti (Worker Connections):

    2024/03/24 10:22:10 [alert] 12345#12345: *9999 worker_connections are not enough...

    Çözüm: Sunucu yoğun trafik alıyor ve Nginx yapılandırmasındaki worker_connections limiti dolmuş. nginx.conf içindeki olaylar (events) bloğunda bu limit artırılmalı ve sistem limitleri (nofile) gözden geçirilmelidir.


5. Log Rotasyonu ve Disk Doluluğunu Önleme

Canlı ortamlarda Nginx log dosyaları gigabaytlarca büyüklüğe ulaşabilir. Bu durum hem disk doluluğuna yol açar hem de log dosyalarını okumayı imkansız hale getirir. Linux dünyasında bu sorunu çözmek için Logrotate aracı kullanılır.

Nginx kurulumu ile birlikte genellikle /etc/logrotate.d/nginx altında örnek bir yapılandırma dosyası gelir:

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

Bu yapılandırmanın ne anlama geldiğine bakalım:

  • daily: Loglar her gün rotate edilir (arşivlenir).
  • rotate 14: Eski loglardan sadece son 14 tanesi saklanır, daha eskileri silinir.
  • compress: Eski loglar gzip ile sıkıştırılır.
  • sharedscripts ve postrotate: Loglar rotate edildikten sonra Nginx’e USR1 sinyali gönderilir. Bu sinyal, Nginx’in yeni log dosyalarına yazmaya devam etmesini sağlar (dosya tanımlayıcılarının yenilenmesi - reopen logs).

6. Log Analizini Otomatize Etmek

Manuel komutlar günlük kontroller için yeterlidir ancak büyük yapılarda gerçek zamanlı izleme şarttır. Bu aşamada açık kaynaklı araçlar devreye girer:

  • GoAccess: Terminalde interaktif olarak, hatta web arayüzü üzerinden real-time Nginx log analizi yapmanızı sağlayan harika bir araçtır. Hafiftir ve kurulumu son derece basittir.
  • ELK Stack (Elasticsearch, Logstash, Kibana) / Grafana Loki: Logların merkezi bir sunucuda toplandığı, görsel panolar (dashboards) hazırlandığı ve anormal trafik artışlarında alarm mekanizmalarının kurulduğu kurumsal çözümlerdir.

GoAccess ile Hızlı Görselleştirme

Sunucunuza GoAccess kurarak anlık trafik analizi yapmak için:

sudo apt install goaccess
goaccess /var/log/nginx/access.log -c --log-format=COMBINED

Bu komut terminal üzerinde tarayıcı, IP, durum kodları vebot trafiğini kategorize eden interaktif bir menü açar.


Sonuç

Nginx log analizi, sadece bir hata ayıklama süreci değil, aynı zamanda sistem güvenliğini artırma, kullanıcı davranışlarını anlama ve performans optimizasyonu yapma sanatıdır. Varsayılan ayarlarla yetinmeyip log formatlarını ihtiyacınıza göre özelleştirmek, log rotasyonunu düzenli tutmak ve komut satırı araçlarına hakim olmak, bir sistem yöneticisini sıradanlıktan uzaklaştırıp operasyonel güvenilirlik sağlar.

Unutmayın; en iyi sistem yöneticisi, sorunlar kullanıcıya yansımadan önce loglar üzerinden durumu fark edendir.


Bu yazı Gemini ile otomatik oluşturulmuştur.