Büyük Log Dosyalarında Hızlı Arama Teknikleri

Sabah 3’te uyandıran o acı veren alarm sesini hepimiz biliriz. Uygulama çökmüş, ekip panikliyor ve senin elinde gigabyte’larca log dosyası var. O anda “grep neydi ya parametreleri” diye düşünmek istemezsin. Bu yazıda, büyük log dosyalarında hızlı ve etkili arama yapmanın tüm inceliklerini ele alacağız. Hem temel komutları hem de gerçek dünya senaryolarında işe yarayan ileri seviye teknikleri inceleyeceğiz.

Neden Büyük Log Dosyaları Sorun Olur?

Bir web sunucusunda nginx access log’u günlük 2-3 GB büyüyebilir. Bir haftalık log dosyası 20 GB’ı geçtiğinde, basit bir cat komutu bile sistemi kasabilir. vim ile açmaya çalışmak felaket olur. İşte bu yüzden doğru araçları doğru kullanmak kritik.

Önce şunu anlayalım: Log dosyaları sıralı yazıldığı için disk üzerinde ardışık bloklarda bulunur. Bu durum, arama algoritmalarının işini kolaylaştırır ama dosya boyutu büyüdükçe yine de ciddi zaman kaybı yaşanabilir. 10 GB’lık bir dosyada naif bir arama dakikalar alabilir.

grep: Temel Ama Güçlü

grep muhtemelen her gün kullandığın komut. Ama çoğu kişi kapasitesinin yüzde onunu kullanıyor.

Temel Kullanım ve Önemli Parametreler

-i: Büyük/küçük harf duyarsız arama yapar -n: Satır numarasını gösterir -c: Eşleşen satır sayısını verir -v: Eşleşmeyen satırları gösterir (ters arama) -r: Alt dizinlere özyinelemeli arama yapar -l: Sadece eşleşen dosya adlarını listeler -o: Sadece eşleşen kısmı gösterir -A [n]: Eşleşmeden sonra n satır gösterir (after) -B [n]: Eşleşmeden önce n satır gösterir (before) -C [n]: Eşleşme etrafında n satır gösterir (context)

# 500 hata kodlarını bul, 3 satır bağlam ile göster
grep -n "HTTP/1.1" 5[0-9][0-9]" /var/log/nginx/access.log -A 3 -B 1

# Birden fazla paterni aynı anda ara
grep -E "(ERROR|CRITICAL|FATAL)" /var/log/app/application.log

# Hata sayısını öğren
grep -c "ERROR" /var/log/app/application.log

grep’i Hızlandırmak: –fixed-strings ve Binary Optimizasyonlar

Regex kullanmıyorsan -F (sabit string) seçeneği grep’i ciddi ölçüde hızlandırır. Regex motoru devreye girmez, düz string karşılaştırması yapılır.

# Regex gereksizse -F kullan, çok daha hızlı çalışır
grep -F "NullPointerException" /var/log/tomcat/catalina.out

# Büyük dosyalarda paralel işlem için split + grep kombinasyonu
# 10 GB log dosyasını 4 parçaya böl ve paralel ara
split -n l/4 /var/log/huge_app.log /tmp/chunk_
ls /tmp/chunk_* | xargs -P 4 -I {} grep "OutOfMemoryError" {} > /tmp/results.txt

Çok Dosyada Arama ve Sıkıştırılmış Loglarda grep

Logrotate genellikle eski logları gzip’ler. zgrep sıkıştırılmış dosyalarda normal grep gibi çalışır.

# Sıkıştırılmış log dosyalarında ara
zgrep "DatabaseException" /var/log/app/application.log.*.gz

# Tüm log dosyalarında (sıkıştırılmış dahil) belirli bir IP ara
zgrep -h "192.168.1.105" /var/log/nginx/access.log* | wc -l

awk: Log Analizinin İsviçre Çakısı

awk sadece arama değil, log verilerini işlemek ve analiz etmek için de kullanılır. Nginx log formatını düşün: IP adresi, tarih, istek, durum kodu, byte boyutu. awk bu alanları kolayca ayırabilir.

Temel awk Mantığı

awk her satırı işlerken alanları boşluğa göre böler. $1 birinci alan, $2 ikinci alan, $NF son alandır. Bu basit mantıkla çok güçlü şeyler yapabilirsin.

# Nginx logunda sadece 500 hata veren IP adreslerini listele
# Log formatı: IP - - [tarih] "istek" durum_kodu byte_boyutu
awk '$9 == 500 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# Belirli saat aralığındaki hataları filtrele
# [10/Jan/2024:14:30:00 formatında tarih var]
awk '$4 >= "[10/Jan/2024:14:00:00" && $4 <= "[10/Jan/2024:15:00:00"' /var/log/nginx/access.log

Gerçek Dünya Senaryosu: Yavaş Sorgu Analizi

MySQL slow query log’u düşün. Her sorgu birden fazla satır kaplar. Belirli bir eşiğin üzerindeki sorguları bulmak istiyorsun.

# MySQL slow query log'da 5 saniyeden uzun süren sorguları bul
awk '/^# Query_time:/ { 
    split($3, a, "."); 
    if (a[1]+0 >= 5) print $0 
}' /var/log/mysql/slow.log

# Uygulama logunda ortalama response time hesapla
# Log formatı: [tarih] [seviye] request completed in XXXms
awk '/request completed/ {
    gsub("ms", "", $NF)
    total += $NF
    count++
} 
END {
    if (count > 0) printf "Ortalama: %.2f ms, Toplam istek: %dn", total/count, count
}' /var/log/app/application.log

awk ile Log Özeti Çıkarma

Büyük bir log dosyasında hangi hataların ne kadar sıklıkla çıktığını görmek isteyebilirsin. Bunu elle saymak imkansız, ama awk ile saniyeler içinde yapabilirsin.

# Hata türlerini say ve sırala
awk '/ERROR/ {
    match($0, /ERROR [A-Za-z]+Exception/, arr)
    if (arr[0] != "") errors[arr[0]]++
} 
END {
    for (e in errors) print errors[e], e
}' /var/log/app/application.log | sort -rn | head -10

sed: Akıllı Akış Editörü

sed genellikle metin değiştirme için kullanılır, ama log analizinde de çok işe yarar. Özellikle belirli satır aralıklarını almak veya karmaşık çıktıları temizlemek için güçlüdür.

Satır Numarasına Göre Hızlı Kesit Alma

Büyük bir log dosyasında “hata satır 458392’de” bilgisini aldın. O satırın etrafını görmek istiyorsun ama dosya 8 GB. sed bu işi mükemmel yapar.

# 458392. satırdan 458420. satıra kadar göster
sed -n '458392,458420p' /var/log/app/huge_application.log

# Belirli bir pattern'dan sonraki 50 satırı al
sed -n '/OutOfMemoryError/,+50p' /var/log/tomcat/catalina.out

# İlk eşleşmeden sonra dur (büyük dosyalarda performans kazancı)
sed -n '/CRITICAL ERROR/{p;q}' /var/log/app/application.log

sed ile Log Temizleme

Bazen log dosyalarında ANSI renk kodları veya gereksiz karakterler bulunur. Bunları temizleyerek diğer araçlarla daha kolay işleyebilirsin.

# ANSI renk kodlarını temizle
sed 's/x1b[[0-9;]*m//g' /var/log/app/colored.log | grep "ERROR"

# Tarih formatını normalleştir ve ardından işle
sed 's/[//g; s/]//g' /var/log/nginx/access.log | awk '{print $4}' | cut -d: -f2 | sort | uniq -c

Kombinasyon Güçleri: Pipeline Sanatı

Gerçek dünyada bu araçları tek başına değil, birlikte kullanırsın. İyi bir pipeline, saatler sürebilecek manuel analizi dakikalara indirir.

Senaryo 1: DDoS Saldırısı Tespiti

Gece uygulaman yavaşladı. Access log’una bakman gerekiyor. En çok istek atan IP’leri bulmak ve hangi endpoint’leri hedef aldıklarını anlamak istiyorsun.

# Son 1 saatin logunu al ve en aktif IP'leri bul
# Önce hangi satırdan itibaren 1 saat öncesine ait olduğunu bul
grep "$(date -d '1 hour ago' +'%d/%b/%Y:%H')" /var/log/nginx/access.log | 
    awk '{print $1}' | 
    sort | 
    uniq -c | 
    sort -rn | 
    head -20

# En çok 429 (rate limit) alan endpoint'leri bul
awk '$9 == 429 {print $7}' /var/log/nginx/access.log | 
    sort | 
    uniq -c | 
    sort -rn | 
    head -10

Senaryo 2: Java Uygulama Hatası Stack Trace Toplama

Java uygulamalarında bir exception oluştuğunda onlarca satırlık stack trace gelir. Bu stack trace’leri toplamak ve gruplayabilmek büyük değer taşır.

# Exception başlangıçlarını ve ilk 10 satırını topla
grep -n "Exception|Error" /var/log/tomcat/catalina.out | 
    awk -F: '{print $1}' | 
    while read linenum; do
        sed -n "${linenum},$((linenum+10))p" /var/log/tomcat/catalina.out
        echo "---"
    done 2>/dev/null | head -200

Senaryo 3: Belirli Bir Kullanıcının Tüm Aktivitelerini Takip Etme

Güvenlik incelemesi yapıyorsun. Belirli bir kullanıcı ID’sinin log dosyalarında ne yaptığını kronolojik sırayla görmek istiyorsun.

# Birden fazla log dosyasında kullanıcı aktivitesini kronolojik sırala
grep -h "user_id=12345" /var/log/app/application.log* | 
    sed 's/[//' | 
    sort -k1 | 
    grep -oP 'd{4}-d{2}-d{2} d{2}:d{2}:d{2}.*' | 
    head -50

Performans İpuçları: Büyük Dosyalarda Hız Kazanmak

less ile Akıllı Görüntüleme

less komutu dosyayı belleğe yüklemez, bu yüzden 50 GB’lık dosyayı bile anında açar.

# less içinde arama (/ ile)
less +/ERROR /var/log/app/huge.log

# less ile grep çıktısını sayfalama
grep "CRITICAL" /var/log/app/application.log | less

# Dosyanın sonundan başla ve canlı izle
less +F /var/log/app/application.log

tail ve head ile Akıllı Kesit Alma

Çoğu zaman tüm dosyayı aramanın gerekmez. Son X satır veya belirli bir zaman dilimi yeterlidir.

# Son 10000 satırda ara (tüm dosyayı okumak yerine)
tail -n 10000 /var/log/app/application.log | grep "ERROR" | tail -50

# Dosyanın ilk 1 GB'ını atla ve sonrasında ara
tail -c +1073741825 /var/log/huge_app.log | grep "DatabaseTimeout"

ripgrep: grep’in Turbo Versiyonu

Eğer sisteme ripgrep (rg) kurabilirsin, bu grep’ten 5-10 kat daha hızlı çalışır. Rust ile yazılmış, SIMD optimizasyonları kullanıyor.

# ripgrep kurulumu (Ubuntu/Debian)
# apt install ripgrep

# Temel kullanım grep ile neredeyse aynı
rg "OutOfMemoryError" /var/log/tomcat/

# Sadece log dosyalarında ara
rg -t log "CRITICAL" /var/log/

# Bağlam ile birlikte göster
rg -C 3 "DatabaseException" /var/log/app/application.log

Pratik Alias’lar ve Script’ler

Bu komutları her seferinde yazmak yerine hazır fonksiyonlar oluşturabilirsin. .bashrc veya .bash_profile dosyasına ekle:

# Hata özetini hızlıca görmek için
alias logerror='grep -E "ERROR|CRITICAL|FATAL" --color=always'
alias logwarn='grep -E "WARN|WARNING" --color=always'

# Son 1 saatin loglarını filtrele
lasthourlogs() {
    local logfile=$1
    local pattern=$2
    local onehourago=$(date -d '1 hour ago' +'%d/%b/%Y:%H')
    grep "$onehourago" "$logfile" | grep "$pattern"
}

# Stack trace toplayıcı
get_exceptions() {
    local logfile=$1
    grep -n "Exception|Error:" "$logfile" | 
    awk -F: '{print $1}' | 
    while read linenum; do
        echo "=== Satır $linenum ==="
        sed -n "${linenum},$((linenum+5))p" "$logfile"
    done
}

Loglar Arası Zaman Korelasyonu

Birden fazla servisin logunu aynı anda incelemen gerektiğinde zaman korelasyonu kritik önem taşır. Nginx’te 502 hatası gördüğünde aynı anda backend’de ne olduğunu anlamak istiyorsun.

# İki farklı log dosyasını zaman damgasına göre birleştir
# Her satıra kaynak dosya adını ekle
awk '{print FILENAME, $0}' 
    /var/log/nginx/error.log 
    /var/log/app/application.log | 
    sort -k3 | 
    grep "2024-01-10 14:3[0-5]"

Sonuç

Log analizi, sysadmin işinin en can sıkıcı ama aynı zamanda en kritik parçalarından biri. Doğru araçları doğru kullandığında, saatler sürebilecek bir analiz birkaç dakikaya iner.

Özetlemek gerekirse, günlük iş akışında şunları uygula:

  • Hız önceliği varsa grep -F kullan, regex motorunu devreye sokma
  • Büyük dosyalarda önce tail veya sed ile zaman aralığını daralt, sonra ara
  • Sıkıştırılmış loglarda zgrep ve zcat kombinasyonunu kullan
  • Yapısal analiz için awk‘a yatırım yap, birkaç saat harcayıp öğrenmesi kendini fazlasıyla amorti eder
  • Canlı izleme için tail -f veya less +F yeterli, syslog gibi araçlara gerek olmayabilir
  • Tekrarlayan analizler için alias ve fonksiyon yaz, her seferinde sıfırdan başlama

Ripgrep kurabilirsen kur. Modern sistemlerde paket depolarında mevcut ve performans farkı gerçekten hissedilir düzeyde. Özellikle CI/CD pipeline’larında veya otomatik hata toplama scriptlerinde bu fark kritik olabilir.

Bu teknikleri öğrenmek bir kerelik çaba gerektirir ama her alarm geldiğinde seni saatler kazandırır. Ve gece 3’te alarma kalktığında, elinde doğru araçlar varken panik yapmak yerine soğukkanlılıkla sorunu çözebilirsin.

Yorum yapın