Log Analizi ile Performans Sorunlarını Tespit Etme

Sunucular konuşur, ama çoğu sysadmin onları dinlemeyi bilmez. Log dosyaları, bir sistemin günlük yaşamının ham kaydıdır ve içlerinde gömülü olan performans sorunlarını bulmak, bazen bir dedektiflik çalışmasına dönüşür. Yıllarca “sunucu yavaş” şikayetiyle uğraştıktan sonra şunu öğrendim: Cevap neredeyse her zaman loglarda saklıdır. Sadece nereye bakacağını bilmen gerekiyor.

Log Analizine Neden Ciddi Yaklaşmalısın

Pek çok sysadmin performans sorunlarını top, htop veya vmstat gibi araçlarla anlık olarak izler. Bu yaklaşım reactive’dir yani sorun zaten başlamışken devreye girersin. Oysa loglar sana geçmişi sunar. Gece 3’te yaşanan ani yük artışını sabah 9’da loglardan okuyabilirsin. Hangi servisin ne zaman çöktüğünü, hangi sorgunun veritabanını kilitlediğini, hangi kullanıcının sistemi kasıtlı ya da kasıtsız olarak yorduğunu loglar üzerinden tespit edebilirsin.

Log analizi sana şunları verir:

  • Sorunun tam zaman damgası
  • Sorundan önce ve sonra olan olaylar
  • Tekrarlayan örüntüler ve trendler
  • Kapasite planlaması için veri

Hangi Loglara Bakacaksın

Linux sistemlerde performans sorunları için incelemeniz gereken başlıca log dosyaları ve dizinleri şunlardır:

  • /var/log/syslog veya /var/log/messages: Sistem geneli olaylar, kernel mesajları
  • /var/log/kern.log: Kernel seviyesi hatalar, OOM killer kayıtları
  • /var/log/dmesg: Boot sonrası donanım ve sürücü mesajları
  • /var/log/auth.log: Kimlik doğrulama ve oturum açma kayıtları
  • /var/log/nginx/ veya /var/log/apache2/: Web sunucusu erişim ve hata logları
  • /var/log/mysql/ veya /var/log/postgresql/: Veritabanı yavaş sorgu logları
  • /var/log/audit/audit.log: Sistem çağrısı ve kaynak kullanım izleme

Journald kullanan modern sistemlerde ise journalctl komutu bu logların büyük çoğunluğunu birleşik şekilde sunar.

Temel Log Analiz Araçları

grep, awk ve sed ile Hızlı Filtreleme

Karmaşık araçlara geçmeden önce Unix’in temel araçlarını iyi bilmek gerekir. Aşağıdaki örnek, son bir saatteki hata mesajlarını filtreler:

# Son 1 saatteki ERROR ve CRITICAL kayıtlarını bul
grep -E "ERROR|CRITICAL|FATAL" /var/log/syslog | 
  awk -v date="$(date -d '1 hour ago' '+%b %d %H:%M')" '$0 >= date'

# Nginx access logunda 500 hatalarını say ve IP bazlı grupla
grep " 500 " /var/log/nginx/access.log | 
  awk '{print $1}' | sort | uniq -c | sort -rn | head -20

# MySQL yavaş sorgu logunda sorgu sürelerini çıkar
grep "Query_time" /var/log/mysql/slow.log | 
  awk '{print $3}' | sort -n | tail -20

journalctl ile Sistemd Logları

Modern systemd tabanlı sistemlerde journalctl son derece güçlü bir araçtır:

# Son 2 saatteki kritik mesajları getir
journalctl --since "2 hours ago" -p err..emerg

# Belirli bir servisin loglarını zaman aralığıyla filtrele
journalctl -u nginx.service --since "2024-01-15 08:00:00" --until "2024-01-15 10:00:00"

# Kernel OOM (Out of Memory) olaylarını bul
journalctl -k | grep -i "out of memory|oom|killed process"

# Disk I/O hatalarını tara
journalctl -k --since "yesterday" | grep -iE "I/O error|blk_update_request|read error"

logwatch ile Otomatik Özet

logwatch aracı günlük log özetleri için idealdir:

# Kurulum
apt install logwatch  # Debian/Ubuntu
yum install logwatch  # RHEL/CentOS

# Bugünün detaylı raporunu ekrana bas
logwatch --detail High --range today --output stdout

# Son 7 günlük özet raporu oluştur
logwatch --detail Med --range '2 Days ago for 7 days' --output mail --mailto [email protected]

Gerçek Dünya Senaryosu 1: Web Sunucusunda Yavaşlama

Bir müşteriden “site çok yavaş” şikayeti geldi ve monitoring araçlarınız anlık olarak yüksek bir yük göstermiyor. Bu durumda ilk yapacağın şey Nginx veya Apache access loglarını analiz etmektir.

# Son 1000 istek içinde yavaş response time'ları bul (Nginx)
# Not: $request_time için log formatını özelleştirmen gerekir
tail -1000 /var/log/nginx/access.log | 
  awk '{if ($NF > 3.0) print $0}' | 
  sort -k$NF -rn | head -30

# En çok istek alan endpoint'leri bul
awk '{print $7}' /var/log/nginx/access.log | 
  cut -d'?' -f1 | sort | uniq -c | sort -rn | head -20

# Belirli bir zaman diliminde saniye başına düşen istek sayısını hesapla
awk '{print $4}' /var/log/nginx/access.log | 
  cut -d: -f2,3 | sort | uniq -c | sort -rn | head -20

Bu analizden şunu bulduk diyelim: Gece 02:15 ile 02:45 arasında bir endpoint anormal derecede fazla istek almış. Bir sonraki adım bu isteklerin kaynağını bulmaktır. Bot trafiği mi, gerçek kullanıcı mı, yoksa internal bir job mu? IP adreslerini ve User-Agent bilgilerini çapraz sorguladığında genellikle suçlu ortaya çıkar.

Nginx için özel log formatı eklemek performans analizini kolaylaştırır:

Nginx konfigürasyonuna şunu ekle:

log_format performance '$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/performance.log performance;

Bu format sayesinde upstream bağlantı süresi, header süresi ve toplam response time’ı ayrı ayrı görebilirsin. Upstream response time yüksekse sorun Nginx’te değil backend uygulamada veya veritabanındadır.

Gerçek Dünya Senaryosu 2: Veritabanı Performans Sorunları

MySQL veya PostgreSQL kaynaklı yavaşlamalar en sık karşılaşılan performans sorunlarından biridir. MySQL’de yavaş sorgu logunu aktif etmek için:

# MySQL yavaş sorgu logunu etkinleştir (my.cnf veya runtime)
mysql -u root -p -e "
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
SET GLOBAL log_queries_not_using_indexes = 'ON';
"

# mysqldumpslow ile analiz et
mysqldumpslow -s t -t 20 /var/log/mysql/slow.log

# pt-query-digest ile daha detaylı analiz (Percona Toolkit)
pt-query-digest /var/log/mysql/slow.log | head -100

PostgreSQL tarafında ise pg_log dizinindeki loglar benzer bilgileri sunar:

# postgresql.conf ayarları
# log_min_duration_statement = 1000  # 1 saniyeden uzun sorguları logla
# log_checkpoints = on
# log_connections = on
# log_lock_waits = on

# Yavaş sorguları filtrele
grep "duration:" /var/log/postgresql/postgresql-*.log | 
  awk '{print $NF, $0}' | sort -rn | head -20

# Kilit bekleme sorunlarını bul
grep "lock|deadlock|wait" /var/log/postgresql/postgresql-*.log | 
  grep -i "error|warning" | tail -50

Gerçek bir vakada, bir e-ticaret müşterisinin sistemi her gün saat 14:00-15:00 arasında yavaşlıyordu. MySQL yavaş sorgu logu incelendiğinde, ERP entegrasyon sistemi tarafından tetiklenen ve index kullanmayan bir JOIN sorgusunun tüm tabloyu taradığı görüldü. Sorgu başına 45 saniye süren bu işlem, mesai saatlerinin en yoğun dönemine denk geliyordu. Index eklenmesiyle bu süre 0.3 saniyeye düştü.

OOM Killer ve Bellek Sorunlarını Tespit Etme

Linux kernel’inin OOM (Out of Memory) Killer mekanizması, sistem belleği tükendiğinde process’leri öldürür. Bu olaylar syslog ve kernel loglarına yazılır:

# OOM killer olaylarını bul
grep -i "out of memory|oom killer|killed process" /var/log/kern.log | 
  awk '{print $1, $2, $3, $NF}' | tail -30

# Hangi process'lerin öldürüldüğünü göster
journalctl -k | grep -A 5 "Out of memory"

# OOM olaylarının zaman dağılımını analiz et
grep "Out of memory" /var/log/kern.log | 
  awk '{print $1, $2}' | uniq -c | sort -rn

OOM olaylarını tespit ettiğinde yapman gereken şey sırasıyla şunlardır:

  • Hangi process’in ne zaman öldürüldüğünü not et
  • O process’in normal bellek tüketimini başka kaynaklardan doğrula
  • Memory leak olup olmadığını kontrol et
  • Swap kullanımını ve swap aktivasyonunu loglardan takip et

Disk I/O Sorunlarını Log ile Takip Etme

Disk sorunları genellikle sessiz sedasız gelir ve çoğu zaman fark edildiğinde iş işten geçmiş olur. Kernel logları disk problemleri için kritik bir kaynaktır:

# Disk I/O hatalarını tara
journalctl -k | grep -iE "I/O error|sector|hard resetting|failed command|blk_update"

# SMART hatalarını kontrol et (smartd log)
grep -i "error|failure|reallocated" /var/log/syslog | grep -i "smartd"

# Yüksek I/O wait'e neden olan process'leri historical loglardan bul
# (sysstat/sar kurulu olmalı)
sar -d -f /var/log/sysstat/sa$(date +%d) | 
  awk '$NF > 50 {print $0}'  # %util > 50 olan diskler

# iostat ile anlık + log karşılaştırması
iostat -x 5 3 | tee -a /var/log/custom/iostat_$(date +%Y%m%d).log

sysstat paketini kurmak ve yapılandırmak performans analizinde büyük avantaj sağlar. Bu paket sar, iostat, mpstat gibi araçları içerir ve sistem metriklerini düzenli aralıklarla loglar:

# Kurulum
apt install sysstat  # Debian/Ubuntu

# /etc/default/sysstat dosyasında ENABLED="true" yap
sed -i 's/ENABLED="false"/ENABLED="true"/' /etc/default/sysstat
systemctl restart sysstat

# Geçmiş CPU kullanımını analiz et
sar -u -f /var/log/sysstat/sa15  # 15. günün CPU verisi

# Geçmiş memory kullanımı
sar -r -f /var/log/sysstat/sa15

# En yüksek yük zamanlarını bul
sar -q -f /var/log/sysstat/sa15 | sort -k5 -rn | head -10

Otomatik Log Analiz Script’i

Tüm bu komutları her seferinde çalıştırmak yorucu olur. Aşağıdaki script, günlük performans analizi için bir başlangıç noktası sunar:

#!/bin/bash
# perf_check.sh - Günlük performans log analizi
# Kullanim: ./perf_check.sh [tarih: YYYY-MM-DD]

DATE=${1:-$(date +%Y-%m-%d)}
LOGDIR="/var/log"
REPORT="/tmp/perf_report_${DATE}.txt"

echo "=== Performans Raporu: $DATE ===" > $REPORT
echo "Olusturulma: $(date)" >> $REPORT
echo "" >> $REPORT

# OOM olayları
echo "--- OOM Killer Olaylari ---" >> $REPORT
journalctl -k --since "$DATE 00:00:00" --until "$DATE 23:59:59" | 
  grep -i "out of memory" >> $REPORT 2>/dev/null || echo "OOM olayi yok" >> $REPORT

echo "" >> $REPORT

# Disk hataları
echo "--- Disk I/O Hatalari ---" >> $REPORT
journalctl -k --since "$DATE 00:00:00" --until "$DATE 23:59:59" | 
  grep -iE "I/O error|failed|error" | head -20 >> $REPORT

echo "" >> $REPORT

# Nginx 5xx hatalar
echo "--- Nginx 5xx Hatalari ---" >> $REPORT
if [ -f "$LOGDIR/nginx/access.log" ]; then
  grep "$(echo $DATE | sed 's/-///g')|$(date -d $DATE '+%d/%b/%Y')" 
    $LOGDIR/nginx/access.log | grep " 5[0-9][0-9] " | 
    awk '{print $1, $7, $9}' | sort | uniq -c | sort -rn | head -20 >> $REPORT
fi

echo "" >> $REPORT

# En yüksek CPU zamanları (sysstat varsa)
echo "--- Yuksek CPU Kullanim Zamanlari ---" >> $REPORT
SAFILE="$LOGDIR/sysstat/sa$(date -d $DATE '+%d')"
if [ -f "$SAFILE" ]; then
  sar -u -f $SAFILE | awk 'NR>3 && $NF < 50 {print $0}' | 
    sort -k$NF | head -10 >> $REPORT
fi

cat $REPORT
echo ""
echo "Rapor kaydedildi: $REPORT"

Bu script’i cron’a ekleyerek her sabah mail ile almak mümkündür:

# Crontab'a ekle
0 7 * * * /usr/local/bin/perf_check.sh | mail -s "Gunluk Performans Raporu $(date +%Y-%m-%d)" [email protected]

ELK Stack ile Merkezi Log Analizi

Tek bir sunucu için yukarıdaki yöntemler yeterli olabilir. Ancak onlarca veya yüzlerce sunucu varsa merkezi bir log sistemi zorunlu hale gelir. Elasticsearch, Logstash ve Kibana üçlüsünden oluşan ELK stack bu ihtiyaca cevap verir.

Filebeat ile sunucudan log göndermek için temel bir konfigürasyon:

# /etc/filebeat/filebeat.yml
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /var/log/nginx/access.log
    fields:
      log_type: nginx_access
      server: web01

  - type: log
    enabled: true
    paths:
      - /var/log/mysql/slow.log
    fields:
      log_type: mysql_slow
      server: db01
    multiline.pattern: '^# Time'
    multiline.negate: true
    multiline.match: after

output.elasticsearch:
  hosts: ["elk-server:9200"]
  index: "syslog-%{+yyyy.MM.dd}"

Kibana üzerinden oluşturacağın dashboard sayesinde tüm sunucuların log verilerini tek ekrandan görebilir, zaman bazlı korelasyonları hızlıca yapabilirsin.

Loki ve Grafana ile Modern Yaklaşım

ELK stack kaynak tüketimi fazla olan ortamlar için Grafana Loki daha hafif bir alternatiftir. Prometheus ile birlikte kullandığında hem metrik hem de log korelasyonu yapabilirsin.

# Promtail konfigürasyonu (Loki'ye log gönderir)
# /etc/promtail/config.yml
scrape_configs:
  - job_name: system
    static_configs:
      - targets:
          - localhost
        labels:
          job: varlogs
          host: web01
          __path__: /var/log/*log

  - job_name: nginx
    static_configs:
      - targets:
          - localhost
        labels:
          job: nginx
          host: web01
          __path__: /var/log/nginx/*.log
    pipeline_stages:
      - regex:
          expression: '(?P<ip>S+) .* [(?P<timestamp>.*)] "(?P<method>S+) (?P<path>S+) .*" (?P<status>d+) (?P<size>d+)'
      - labels:
          status:
          method:

Grafana’da LogQL sorgusuyla Nginx 500 hatalarını şöyle sorgulayabilirsin:

{job="nginx"} |= "500" | logfmt | line_format "{{.ip}} - {{.path}} - {{.status}}"

Log Rotasyonu ve Arşivleme

Log analizi yapabilmek için önce logların düzgün saklanması gerekir. logrotate konfigürasyonunu performans analizi ihtiyaçlarına göre ayarlamak önemlidir:

# /etc/logrotate.d/nginx örneği
/var/log/nginx/*.log {
    daily
    missingok
    rotate 30          # 30 günlük log tut
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        nginx -s reopen
    endscript
}

# Logrotate durumunu kontrol et
logrotate -d /etc/logrotate.d/nginx  # dry-run
logrotate -f /etc/logrotate.d/nginx  # zorla çalıştır

# Mevcut log arşivlerini listele
ls -lh /var/log/nginx/ | grep ".gz"

Uzun vadeli analiz için logları S3 veya benzeri bir object storage’a arşivlemek, hem disk alanı kazandırır hem de gerektiğinde erişim imkanı sunar.

Pratik İpuçları ve Sık Yapılan Hatalar

Yıllar içinde öğrendiğim bazı pratik noktalar:

  • Zaman dilimi tutarsızlıklarına dikkat et: Sunucular farklı timezone’da olabilir. timedatectl ile tüm sunucuların UTC kullandığından emin ol.
  • Log seviyelerini doğru ayarla: Production’da DEBUG seviyesi log yazmak hem performansı düşürür hem de gerçek hataları gürültü içinde saklar.
  • Structured logging kullan: JSON formatında log yazan uygulamalar için analiz çok daha kolaydır.
  • Korelasyon ID ekle: Microservice mimarilerinde bir isteği tüm servisler boyunca takip etmek için her isteğe unique bir ID atanmalıdır.
  • Log yazmak da I/O’dur: Çok fazla ve sık log yazan uygulama, bizzat kendisi performans sorunu yaratabilir. Özellikle döngü içindeki log satırları tehlikelidir.

Sonuç

Log analizi, sistem yöneticiliğinin en değerli ama en az sevileni becerilerinden biridir. grep ile başlayıp ELK Stack veya Grafana Loki’ye uzanan bu yolculuk, sana sistemini gerçekten anlamanın kapısını açar. Önemli olan mükemmel bir araç seti kurmak değil, mevcut loglardan anlamlı bilgi çıkarmayı alışkanlık haline getirmektir.

Her ciddi performans sorununda şu sırayı takip etmeyi öneriyorum: Önce zaman damgasını bul, sonra o zaman diliminde tüm bileşenlerin loglarını karşılaştır, tekrarlayan örüntüleri tespit et ve köke in. Çoğu zaman “sunucu yavaş” gibi muğlak bir şikayet, birkaç grep komutu sonrasında “gece yarısı çalışan backup job’ı disk I/O’sunu doyuruyordu” gibi somut bir bulguya dönüşür. Ve o an, sysadmin olmayı hatırlıyorsun.

Benzer Konular

Bir yanıt yazın

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