Sunucularda log analizi yaparken en can sıkıcı durumlardan biri, aradığın şeyin sıkıştırılmış bir dosyada olduğunu fark etmektir. Klasik yaklaşım şu olur: dosyayı açarsın, grep’i çalıştırırsın, sonucu alırsın, geçici dosyayı silersin. Ama bunu onlarca rotated log dosyası için yapmak zorunda kaldığında, iş gerçekten yorucu bir hal alır. İşte tam bu noktada zgrep ve zcat devreye girer. Bu iki araç, sıkıştırılmış dosyaları açmadan doğrudan içlerinde arama yapmanı ve içeriklerini okumanı sağlar. Sistem yöneticiliğinde saatler kazandıran bu komutları detaylıca ele alalım.
zcat ve zgrep Nedir?
zcat ve zgrep, GNU Gzip paketinin bir parçası olarak gelen yardımcı araçlardır. Temelde ne yaptıklarını anlamak için şu şekilde düşünebilirsin: zcat, sıkıştırılmış bir dosyayı bellekte açıp içeriğini standart çıktıya basar. zgrep ise bu işlemi grep ile birleştirir ve sıkıştırılmış dosya içinde doğrudan arama yapmanı sağlar.
Bu araçların güzelliği, disk üzerindeki dosyayı değiştirmemesidir. Dosya sıkıştırılmış halde kalır, sen sadece içeriğine bakarsın. Log rotation yapılandırmalarında genellikle eski loglar .gz formatında arşivlenir. Bir sunucuda /var/log/nginx/ altına baktığında şöyle bir manzarayla karşılaşırsın:
ls -la /var/log/nginx/
# access.log
# access.log.1
# access.log.2.gz
# access.log.3.gz
# access.log.4.gz
# error.log
# error.log.1
# error.log.2.gz
İşte bu .gz uzantılı dosyalar için zcat ve zgrep tam olarak ihtiyacın olan araçlardır.
Temel Kullanım
zcat ile Dosya İçeriğini Okumak
zcat kullanımı son derece basittir. Normal cat komutundan farkı yok neredeyse:
# Tek bir gz dosyasının içeriğini görüntüle
zcat /var/log/nginx/access.log.2.gz
# İçeriği less ile sayfalı görüntüle
zcat /var/log/nginx/access.log.2.gz | less
# Birden fazla dosyayı birleştirerek göster
zcat /var/log/nginx/access.log.2.gz /var/log/nginx/access.log.3.gz | less
zcat aslında gunzip -c komutunun bir takma adıdır. -c parametresi, dosyayı diske yazmak yerine stdout’a yazması anlamına gelir. Bunu bilmek, aracın nasıl çalıştığını anlamak açısından önemlidir.
zgrep ile Sıkıştırılmış Dosyada Arama
zgrep, normal grep ile birebir aynı parametreleri alır. Sadece gzip sıkıştırılmış dosyalar üzerinde çalışır:
# Basit kelime arama
zgrep "ERROR" /var/log/syslog.2.gz
# Büyük/küçük harf duyarsız arama
zgrep -i "error" /var/log/syslog.2.gz
# Satır numarasıyla birlikte göster
zgrep -n "connection refused" /var/log/syslog.2.gz
# Eşleşen satır sayısını göster
zgrep -c "404" /var/log/nginx/access.log.3.gz
Gerçek Dünya Senaryoları
Senaryo 1: Nginx Log Analizi
Geçen ay bir müşterinin sitesinde ani bir trafik artışı yaşandı. Sunucunun yavaşladığını fark ettik ama o anki loglar rotasyona uğramış ve sıkıştırılmıştı. İşte tam o sırada bu araçların değerini bir kez daha anladım.
# Belirli bir IP adresinden gelen tüm istekleri bul
zgrep "192.168.1.150" /var/log/nginx/access.log.3.gz
# 500 hata kodlarını tüm arşivlenmiş loglarda ara
zgrep " 500 " /var/log/nginx/access.log.*.gz
# Belirli bir endpoint'e yapılan POST isteklerini bul
zgrep "POST /api/login" /var/log/nginx/access.log.*.gz | wc -l
Son komut, login endpoint’ine kaç istek geldiğini sayar. Eğer bu sayı anormal derecede yüksekse, muhtemelen bir brute force saldırısıyla karşı karşıyasın demektir.
Senaryo 2: Sistem Loglarında Hata Takibi
Bir servisin belirli bir tarihte çöktüğünü varsayalım. O tarihe ait loglar artık sıkıştırılmış arşivlerde:
# Tüm gz loglarında "kernel panic" ara
zgrep -i "kernel panic" /var/log/kern.log.*.gz
# Zaman damgasıyla birlikte memory hatalarını bul
zgrep -h "Out of memory" /var/log/syslog.*.gz | sort
# Belirli bir servisin crash kayıtlarını bul
zgrep "segfault" /var/log/syslog.*.gz | grep "myapp"
-h parametresi, dosya adını çıktıya eklemez. Bu, birden fazla dosyada arama yaparken sadece içeriğe odaklanmak istediğinde kullanışlıdır.
Senaryo 3: Kullanıcı Aktivite Takibi
Audit logları genellikle hızla büyür ve sıkıştırılır. Belirli bir kullanıcının geçmişteki aktivitelerini araştırman gerektiğinde:
# Belirli kullanıcının sudo komutlarını bul
zgrep "sudo.*johndoe" /var/log/auth.log.*.gz
# Başarısız SSH girişlerini listele
zgrep "Failed password" /var/log/auth.log.*.gz | tail -50
# Belirli bir kullanıcının su komutunu kullandığı anları bul
zgrep "su[" /var/log/auth.log.*.gz | zgrep "johndoe"
Gelişmiş Kullanım Teknikleri
Wildcard ile Tüm Arşivleri Tarama
Sysadmin’in en sevdiği özelliklerden biri, wildcard kullanarak tüm arşivleri tek komutla tarayabilmektir:
# Tüm sıkıştırılmış nginx loglarında 404 hatalarını say
zgrep -c "" 404 " /var/log/nginx/access.log.*.gz
# Hem sıkıştırılmış hem sıkıştırılmamış dosyaları tara
grep "ERROR" /var/log/app/app.log* 2>/dev/null
zgrep "ERROR" /var/log/app/app.log.*.gz 2>/dev/null
zgrep ile Pipe Kullanımı
zgrep çıktısını diğer komutlarla birleştirerek güçlü analizler yapabilirsin:
# En çok 404 alan URL'leri bul
zgrep "" 404 " /var/log/nginx/access.log.*.gz |
awk '{print $7}' |
sort |
uniq -c |
sort -rn |
head -20
# Belirli saatler arasındaki hataları filtrele
zgrep "ERROR" /var/log/app/app.log.2.gz |
awk -F'[' '{print $2}' |
awk '{print $1}' |
grep "^2024:03:15:1[4-6]"
# IP adreslerine göre istek sayısını hesapla
zcat /var/log/nginx/access.log.*.gz |
awk '{print $1}' |
sort |
uniq -c |
sort -rn |
head -10
Son örnekte zcat kullanarak tüm içeriği stdout’a döktük ve ardından standart araçlarla işledik. Bu yaklaşım, zgrep‘in desteklemediği daha karmaşık işlemler için idealdir.
Regex ile Güçlü Aramalar
zgrep, tüm grep regex özelliklerini destekler:
# Extended regex ile birden fazla pattern ara
zgrep -E "ERROR|CRITICAL|FATAL" /var/log/app/app.log.*.gz
# Belirli bir IP aralığını ara
zgrep -E "192.168.(1|2).[0-9]+" /var/log/nginx/access.log.2.gz
# Tarih formatına göre filtrele
zgrep -E "2024-03-[0-9]{2} (14|15|16):[0-9]{2}" /var/log/app/app.log.2.gz
Parametre Referansı
zgrep için en sık kullandığım parametreler şunlar:
-i: Büyük/küçük harf duyarsız arama yapar. “error” yazsan da “ERROR” de yakalar.
-n: Eşleşen satırın dosya içindeki satır numarasını gösterir.
-c: Eşleşen satır sayısını verir, satırları değil.
-l: Eşleşme bulunan dosyaların sadece adlarını listeler.
-L: Eşleşme bulunmayan dosyaların adlarını listeler.
-v: Eşleşmeyen satırları gösterir, tersine filtreleme için kullanışlıdır.
-h: Çok dosya aramasında dosya adını çıktıya eklememek için kullanılır.
-r: Alt dizinleri de tarar (ancak gz dosyaları için dikkatli kullanılmalı).
-A [sayı]: Eşleşmeden sonraki N satırı da gösterir. Hata bağlamını anlamak için mükemmeldir.
-B [sayı]: Eşleşmeden önceki N satırı gösterir.
-E: Extended regular expression kullanır.
-F: Pattern’ı sabit string olarak kullanır, regex özel karakterlerini yorumlamaz.
-w: Tam kelime eşleşmesi arar.
-x: Tam satır eşleşmesi arar.
zcat Parametreleri
-f veya –force: Sıkıştırılmamış dosyaları da işler, hata vermez.
-l veya –list: Dosya hakkında bilgi gösterir (sıkıştırılmamış boyut, oran gibi).
-t veya –test: Dosyanın bütünlüğünü test eder, içeriği göstermez.
-v veya –verbose: İşlem sırasında ayrıntılı bilgi verir.
# Dosya bilgilerini görüntüle
zcat -l /var/log/nginx/access.log.3.gz
# Dosya bütünlüğünü kontrol et
zcat -t /var/log/nginx/access.log.3.gz && echo "Dosya sağlam"
Diğer Sıkıştırma Formatları için Alternatifler
zgrep ve zcat yalnızca gzip formatıyla çalışır. Peki ya diğer formatlar? Linux ekosistemi burada da seni yalnız bırakmıyor.
bzcat ve bzgrep: bzip2 formatı için kullanılır. Kullanımı tamamen aynıdır:
bzgrep "ERROR" /var/log/app/app.log.2.bz2
bzcat /var/log/app/app.log.2.bz2 | less
xzcat ve xzgrep: xz formatı için kullanılır. Modern sistemlerde giderek yaygınlaşıyor:
xzgrep "ERROR" /var/log/app/app.log.2.xz
xzcat /var/log/app/app.log.2.xz | head -100
zstdgrep ve zstdcat: Zstandard formatı için. Facebook’un geliştirdiği bu format, hız ve sıkıştırma oranı dengesi açısından mükemmeldir:
zstdgrep "ERROR" /var/log/app/app.log.2.zst
zstdcat /var/log/app/app.log.2.zst | grep -i "fatal"
Hangi formatla karşılaşacağını bilmiyorsan, file komutunu kullanarak formatı öğrenebilirsin:
file /var/log/app/app.log.2.gz
# Çıktı: /var/log/app/app.log.2.gz: gzip compressed data, ...
Pratik Script Örnekleri
Günlük Log Analiz Script’i
Sabah rutinine ekleyebileceğin, tüm arşivlenmiş loglarda hızlı analiz yapan bir script:
#!/bin/bash
# Dünün sıkıştırılmış loglarını analiz et
LOG_DIR="/var/log/nginx"
YESTERDAY=$(date -d "yesterday" +%Y%m%d)
echo "=== Nginx Log Analizi: $YESTERDAY ==="
echo ""
# Toplam istek sayısı
echo "Toplam İstek Sayısı:"
zcat ${LOG_DIR}/access.log.1.gz 2>/dev/null | wc -l
# HTTP hata kodları özeti
echo ""
echo "HTTP 4xx/5xx Hataları:"
zgrep -E '" [45][0-9]{2} ' ${LOG_DIR}/access.log.1.gz 2>/dev/null |
awk '{print $9}' |
sort |
uniq -c |
sort -rn
# En çok istek atan IP'ler
echo ""
echo "Top 10 IP Adresi:"
zcat ${LOG_DIR}/access.log.1.gz 2>/dev/null |
awk '{print $1}' |
sort |
uniq -c |
sort -rn |
head -10
Çoklu Format Destekleyen Arama Script’i
Hangi sıkıştırma formatı olursa olsun çalışan evrensel bir arama script’i:
#!/bin/bash
# Kullanım: ./search_logs.sh "aranacak_pattern" /var/log/app/
PATTERN="$1"
SEARCH_DIR="${2:-.}"
if [ -z "$PATTERN" ]; then
echo "Kullanim: $0 'pattern' [dizin]"
exit 1
fi
echo "Arama: '$PATTERN' -- Dizin: $SEARCH_DIR"
echo "================================"
# Sıkıştırılmamış dosyalar
find "$SEARCH_DIR" -name "*.log" -o -name "*.log.[0-9]" 2>/dev/null |
xargs grep -l "$PATTERN" 2>/dev/null | while read f; do
echo "--- $f ---"
grep "$PATTERN" "$f"
done
# gzip dosyalar
find "$SEARCH_DIR" -name "*.gz" 2>/dev/null | while read f; do
if zgrep -q "$PATTERN" "$f" 2>/dev/null; then
echo "--- $f ---"
zgrep "$PATTERN" "$f"
fi
done
# bzip2 dosyalar
find "$SEARCH_DIR" -name "*.bz2" 2>/dev/null | while read f; do
if bzgrep -q "$PATTERN" "$f" 2>/dev/null; then
echo "--- $f ---"
bzgrep "$PATTERN" "$f"
fi
done
Performans İpuçları
zgrep kullanırken dikkat etmen gereken bazı noktalar var:
Sıkıştırılmış dosyalarda arama her zaman açık dosyaya göre daha yavaştır. Bu kaçınılmaz bir durum. Sıkıştırma algoritması dosyayı bloklar halinde çözer ve grep pattern eşleşmesi arar. Yoğun log analizlerinde bunu göz önünde bulundur.
Birden fazla dosyada arama yaparken parallel kullanımını değerlendir:
# GNU parallel ile çoklu dosyada hızlı arama
find /var/log -name "*.gz" |
parallel "zgrep -l 'CRITICAL' {}" 2>/dev/null
Sonuçları önbelleğe almak mantıklı olabilir. Aynı arşivi birden fazla kez tarayacaksan, önce zcat ile açıp geçici bir dosyaya yazabilirsin. Ama bunu sadece gerçekten gerekli durumlarda yap, disk alanı her zaman değerlidir.
-m parametresiyle maksimum eşleşme sayısını sınırlandır. Büyük dosyalarda sadece ilk birkaç eşleşmeni bulmak yeterliyse bu parametre işi hızlandırır:
# İlk 5 eşleşmeyi bulduktan sonra dur
zgrep -m 5 "CRITICAL" /var/log/app/app.log.2.gz
Kurulum ve Erişilebilirlik
Neredeyse tüm modern Linux dağıtımlarında zgrep ve zcat varsayılan olarak gelir, çünkü gzip paketinin bir parçasıdır. Eğer eksikse:
# Debian/Ubuntu
sudo apt install gzip
# RHEL/CentOS/AlmaLinux
sudo dnf install gzip
# Arch Linux
sudo pacman -S gzip
# Kurulum kontrolü
which zgrep zcat
zgrep --version
Sonuç
zgrep ve zcat, sistem yöneticisinin araç kutusunda olması gereken araçlardan ikisidir. Özellikle log rotation yapılandırmalarında günler, haftalar, hatta aylar öncesine ait kayıtları araştırırken bu araçlar olmadan yaşamak ciddi anlamda zor olurdu.
Temel felsefe basit: dosyayı açmak, işlemek, sonucu almak ve dosyayı silmek yerine, tüm bu adımları tek bir komutla, hiç geçici dosya oluşturmadan yapıyorsun. Bu hem disk alanı hem de zaman açısından büyük bir avantaj sağlar.
Günlük sysadmin işlerinde bu araçları kullanmaya başladıktan sonra, sıkıştırılmış loglardan korktuğun günlere geri dönmek istemeyeceksin. Özellikle bir güvenlik olayını araştırırken veya bir servisin neden çöktüğünü anlamaya çalışırken, bu araçların sağladığı hız ve pratiklik paha biçilemez. Komutları ezberlemeni bile önermiyorum, sadece varlıklarını bil. Geri kalanını man zgrep halleder.