Bir web sunucusu yönetiyorsanız ve log dosyalarınızın disk alanını yuttuğunu fark ettiyseniz, bu yazı tam size göre. Apache access ve error logları özellikle yüksek trafikli sitelerde inanılmaz hızla büyüyebiliyor. Gece yarısı “disk full” alarmıyla uyanmak istemiyorsanız, log yönetimini düzgün kurmak şart. Bu yazıda Apache’nin kendi aracı olan rotatelogs ile sisteme entegre logrotate araçlarını karşılaştırmalı olarak ele alacağız ve her ikisini de production ortamında nasıl kullanacağınızı göstereceğiz.
Log Yönetimi Neden Bu Kadar Önemli?
Basit bir örnek verelim: Günde 100.000 istek alan bir Apache sunucusunda access log yaklaşık 20-50 MB büyüyebiliyor. Bu, ayda 600 MB ile 1.5 GB arasında demek. Error logları da cabası. 6 ay sonra tek bir log dosyasının 10 GB’a ulaştığını gören sysadmin’lerin sayısı hiç de az değil.
Büyük log dosyalarının getirdiği sorunlar sadece disk dolması değil:
tail -fveyagrepgibi komutlar 10 GB dosyada dakikalar sürebiliyor- Log analiz araçları (AWStats, GoAccess) devasa dosyaları işleyemiyor
- Backup süreçleri yavaşlıyor
- İncident sırasında hızlı log araması yapılamıyor
Çözüm: Logları düzenli olarak döndürmek (rotate), sıkıştırmak ve belirli bir süre sonra silmek.
rotatelogs: Apache’nin Yerleşik Log Döndürme Aracı
rotatelogs, Apache ile birlikte gelen ve pipe (|) mekanizmasıyla çalışan bir araçtır. Apache’nin CustomLog veya ErrorLog direktifine doğrudan bağlanır, yani log döndürme işlemi Apache sürecinin içinde gerçekleşir.
rotatelogs Temel Kullanımı
Apache yapılandırma dosyanızda (httpd.conf veya sanal host konfigürasyonu) şu şekilde kullanılır:
# /etc/apache2/sites-available/example.conf veya /etc/httpd/conf.d/example.conf
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/html
# Zaman bazlı rotasyon: Her 24 saatte bir (86400 saniye)
CustomLog "|/usr/bin/rotatelogs /var/log/apache2/access_%Y%m%d.log 86400" combined
# Error log da rotate edilebilir
ErrorLog "|/usr/bin/rotatelogs /var/log/apache2/error_%Y%m%d.log 86400"
</VirtualHost>
Bu yapılandırmada %Y%m%d format string’i sayesinde loglar access_20240115.log gibi isimlendirilir. Her gün gece yarısı otomatik olarak yeni bir dosya oluşturulur.
rotatelogs Parametre Referansı
-l: UTC yerine yerel saat kullanır. Timezone farkından kaynaklanan karışıklıkları önler, Türkiye’deki sunucularda mutlaka kullanın.
-L link: Belirtilen path’e sembolik link oluşturur, böylece “en güncel log” her zaman sabit bir isimde erişilebilir olur.
-n sayı: Tutulacak maksimum dosya sayısını belirler. Bu sayıyı aştığında eski dosyalar silinir.
-f: Başlangıçta hemen dosya oluşturur, ilk log satırı gelene kadar beklemez.
-D: Log dizini yoksa otomatik oluşturur.
-e: Logları hem dosyaya yazar hem de stdout’a yönlendirir.
-t: Rotate sırasında dosyayı kesmek (truncate) yerine yeni dosya oluşturur. Varsayılan davranış zaten budur ama bazı sürümlerde fark yaratabilir.
Boyut Bazlı Rotasyon
Zaman yerine boyut bazlı da çalışabilirsiniz. Özellikle trafiği çok değişken olan siteler için faydalı:
# 100 MB'a ulaşınca rotate et (104857600 byte = 100 MB)
CustomLog "|/usr/bin/rotatelogs -l /var/log/apache2/access_%Y%m%d_%H%M%S.log 104857600" combined
Sembolik Link ile Kombinasyon
Production ortamında çok kullanışlı bir yapılandırma:
# -L parametresi ile her zaman güncel loga sabit bir path üzerinden erişim
CustomLog "|/usr/bin/rotatelogs -l -L /var/log/apache2/access.log /var/log/apache2/access_%Y%m%d.log 86400" combined
ErrorLog "|/usr/bin/rotatelogs -l -L /var/log/apache2/error.log /var/log/apache2/error_%Y%m%d.log 86400"
Artık monitoring araçlarınız veya tail -f komutunuz hep /var/log/apache2/access.log‘u takip edebilir. Rotate olduğunda bu sembolik link otomatik yeni dosyaya işaret eder.
Dosya Sayısını Sınırlama
# Son 7 günün logunu tut, eskileri sil
CustomLog "|/usr/bin/rotatelogs -l -n 7 /var/log/apache2/access_%Y%m%d.log 86400" combined
Bu yapılandırmayla disk dolma riskini tamamen ortadan kaldırırsınız. 7 günlük log tutulur, daha eskisi otomatik silinir.
logrotate: Sistem Geneli Log Yönetimi
logrotate, Apache’ye özgü değil, sistem genelinde tüm log dosyalarını yönetmek için kullanılan bir araçtır. Cron veya systemd timer aracılığıyla düzenli çalışır. Apache log yönetiminde rotatelogs‘a göre daha fazla esneklik sunar çünkü sıkıştırma, e-posta bildirimi, özel scriptler gibi özellikler içerir.
logrotate’in Çalışma Mantığı
logrotate varsayılan olarak /etc/logrotate.conf ana konfigürasyonunu okur ve /etc/logrotate.d/ dizinindeki tüm dosyaları işler. Apache için genellikle /etc/logrotate.d/apache2 (Debian/Ubuntu) veya /etc/logrotate.d/httpd (RHEL/CentOS) dosyası mevcuttur.
Varsayılan Apache logrotate Konfigürasyonu
Çoğu sistemde gelen varsayılan konfigurasyon şu şekildedir:
# /etc/logrotate.d/apache2 (Debian/Ubuntu)
/var/log/apache2/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
if invoke-rc.d apache2 status > /dev/null 2>&1; then
invoke-rc.d apache2 reload > /dev/null 2>&1;
fi
endscript
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then
run-parts /etc/logrotate.d/httpd-prerotate;
fi
endscript
}
Özelleştirilmiş logrotate Konfigürasyonu
Gerçek bir production senaryosu için daha detaylı bir yapılandırma:
# /etc/logrotate.d/apache2-custom
/var/log/apache2/access.log
/var/log/apache2/error.log {
# Her gün rotate et
daily
# Log dosyası yoksa hata verme
missingok
# 30 gün tut
rotate 30
# Rotate edilen dosyaları gzip ile sıkıştır
compress
# Sıkıştırmayı bir gün geciktir (bir önceki günün logu açık kalabilir)
delaycompress
# Boş dosyaları rotate etme
notifempty
# Rotate sonrası dosyaları bu izin ve sahiplikle oluştur
create 644 www-data adm
# Tüm scriptleri bir kez çalıştır (birden fazla log dosyası varsa)
sharedscripts
# Rotate SONRASI Apache'ye USR1 sinyali gönder
postrotate
/usr/sbin/apachectl graceful > /dev/null 2>&1 || true
endscript
}
logrotate Direktif Referansı
daily / weekly / monthly / yearly: Rotasyon sıklığını belirler.
rotate N: Kaç eski dosya tutulacağını belirler. rotate 14 ile 14 günlük log tutulur.
size N: Belirli boyuta ulaşınca rotate et. size 100M veya size 1G şeklinde kullanılır.
compress: Eski logları gzip ile sıkıştırır, disk tasarrufu için şart.
delaycompress: Son rotate edilmiş dosyayı bir sonraki rotate’e kadar sıkıştırmadan bekletir. Apache hala eski dosyaya yazıyor olabilir, bu direktif veri kaybını önler.
missingok: Log dosyası bulunamazsa logrotate hata vermez, sessizce devam eder.
notifempty: Boş log dosyalarını rotate etmez.
create mode owner group: Rotate sonrasında yeni dosyayı belirtilen izin ve sahiplikle oluşturur.
sharedscripts: prerotate ve postrotate scriptlerini birden fazla eşleşen dosya için tek seferinde çalıştırır.
copytruncate: Dosyayı kopyalayıp orijinalini sıfırlar. Apache’ye sinyal göndermeden çalışır ama küçük bir veri kaybı riski taşır. Zorunlu olmadıkça kullanmayın.
postrotate / endscript: Rotate işleminden sonra çalıştırılacak komutlar.
prerotate / endscript: Rotate işleminden önce çalıştırılacak komutlar.
olddir /path: Eski log dosyalarını belirtilen dizine taşır, ana log dizinini temiz tutar.
dateext: Rotated dosya ismine sayısal suffix yerine tarih ekler (access.log-20240115 gibi).
dateformat format: dateext için format belirler. dateformat -%Y%m%d ile access.log-20240115 elde edersiniz.
Sanal Host Bazlı logrotate
Birden fazla sanal host yönetiyorsanız, her sitenin loglarını ayrı tutmak iyi bir pratik:
# /etc/logrotate.d/apache2-vhosts
/var/log/apache2/site1.example.com-access.log
/var/log/apache2/site1.example.com-error.log {
weekly
rotate 8
compress
delaycompress
missingok
notifempty
create 644 www-data adm
dateext
dateformat -%Y%m%d
olddir /var/log/apache2/site1-archive
sharedscripts
postrotate
/usr/sbin/apachectl graceful > /dev/null 2>&1 || true
endscript
}
/var/log/apache2/site2.example.com-access.log
/var/log/apache2/site2.example.com-error.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 644 www-data adm
dateext
sharedscripts
postrotate
/usr/sbin/apachectl graceful > /dev/null 2>&1 || true
endscript
}
logrotate’i Manuel Test Etme
Yeni bir konfigürasyon yazdıktan sonra test etmeden production’a almayın:
# Syntax kontrolü (debug modda, gerçekten çalıştırmaz)
logrotate -d /etc/logrotate.d/apache2-custom
# Zorla bir kez çalıştır (verbose çıktı ile)
logrotate -vf /etc/logrotate.d/apache2-custom
# Sadece belirli bir dosya için test
logrotate --debug --verbose /etc/logrotate.d/apache2-vhosts
# Son çalışma zamanını kontrol et
cat /var/lib/logrotate/status | grep apache
rotatelogs ile logrotate: Hangisini Seçmeli?
İkisi arasında seçim yaparken birkaç kritik farka dikkat etmek gerekiyor.
rotatelogs Apache sürecinin bir parçası olarak çalışır. Apache restart gerektirmez, rotasyon tam zamanında olur. Özellikle gerçek zamanlı log izleme ve anlık boyut kontrolü için idealdir. Ancak sıkıştırma özelliği yoktur, eski dosyaları kendiniz temizlemeniz gerekebilir.
logrotate ise sistemin cron altyapısını kullanır, sıkıştırma yapar, postrotate scriptiyle entegrasyon sağlar ve merkezi yönetim sunar. Dezavantajı: Cron çalışana kadar rotasyon gerçekleşmez ve Apache’ye graceful reload sinyali gönderilmesi gerekir.
Önerim: Yüksek trafikli sitelerde ikisini birlikte kullanmak mantıklı. rotatelogs ile günlük dosya oluşturun, logrotate ile sıkıştırın ve eski dosyaları temizleyin.
İkisini Birlikte Kullanma
# Apache konfigürasyonu: rotatelogs ile günlük dosya oluştur
# /etc/apache2/sites-available/example.conf
<VirtualHost *:80>
ServerName example.com
CustomLog "|/usr/bin/rotatelogs -l /var/log/apache2/access_%Y%m%d.log 86400" combined
ErrorLog "|/usr/bin/rotatelogs -l /var/log/apache2/error_%Y%m%d.log 86400"
</VirtualHost>
# logrotate konfigürasyonu: Sadece sıkıştırma ve temizlik yap
# /etc/logrotate.d/apache2-rotatelogs
/var/log/apache2/access_*.log
/var/log/apache2/error_*.log {
# Günlük dosyalar zaten rotatelogs tarafından oluşturuluyor
# logrotate sadece sıkıştırma ve silme yapacak
daily
rotate 30
compress
delaycompress
missingok
notifempty
# Apache'ye sinyal göndermeye gerek yok, rotatelogs halleder
sharedscripts
postrotate
# Sadece 30 günden eski sıkıştırılmış dosyaları sil
find /var/log/apache2/ -name "*.log.gz" -mtime +30 -delete
endscript
}
Gerçek Dünya Senaryosu: Yüksek Trafikli E-ticaret Sitesi
Diyelim ki günde 500.000 istek alan bir e-ticaret sitesi yönetiyorsunuz. Access log günde 100 MB büyüyor, compliance gereksinimi 90 gün log saklama gerektiriyor. İşte bu senaryo için production-ready konfigürasyon:
# /etc/apache2/sites-available/ecommerce.conf
<VirtualHost *:443>
ServerName shop.example.com
# rotatelogs: Saatlik dosya (yoğun trafik için daha yönetilebilir)
CustomLog "|/usr/bin/rotatelogs -l -n 2400 -L /var/log/apache2/ecommerce-access.log /var/log/apache2/ecommerce/access_%Y%m%d_%H.log 3600" combined
# Error log günlük rotate
ErrorLog "|/usr/bin/rotatelogs -l -L /var/log/apache2/ecommerce-error.log /var/log/apache2/ecommerce/error_%Y%m%d.log 86400"
</VirtualHost>
# /etc/logrotate.d/ecommerce-apache
/var/log/apache2/ecommerce/access_*.log
/var/log/apache2/ecommerce/error_*.log {
daily
rotate 90
compress
compresscmd /usr/bin/pigz
compressext .gz
compressoptions -9
delaycompress
missingok
notifempty
dateext
dateformat -%Y%m%d
olddir /var/log/apache2/ecommerce/archive
sharedscripts
prerotate
# Rotate öncesi log analiz scriptini çalıştır
/usr/local/bin/parse-access-logs.sh > /dev/null 2>&1 || true
endscript
postrotate
# Sadece 90 günden eski arşivleri temizle
find /var/log/apache2/ecommerce/archive/ -name "*.gz" -mtime +90 -delete
endscript
}
logrotate Cron ve systemd Entegrasyonu
Debian/Ubuntu sistemlerde logrotate günlük cron ile çalışır:
# /etc/cron.daily/logrotate içeriğini kontrol et
cat /etc/cron.daily/logrotate
# systemd kullanan sistemlerde timer ile çalışır
systemctl status logrotate.timer
systemctl list-timers | grep logrotate
Eğer logrotate’in tam olarak belirli bir saatte çalışmasını istiyorsanız, timer’ı özelleştirebilirsiniz:
# /etc/systemd/system/logrotate.timer (override için)
[Unit]
Description=Daily rotation of log files
Documentation=man:logrotate(8)
[Timer]
OnCalendar=*-*-* 01:00:00
AccuracySec=1h
Persistent=true
[Install]
WantedBy=timers.target
# Timer'ı etkinleştir
systemctl daemon-reload
systemctl enable --now logrotate.timer
systemctl status logrotate.timer
Sık Yapılan Hatalar ve Çözümleri
Apache log dosyasını kilitleme sorunu: logrotate dosyayı rotate ettikten sonra Apache yeni dosyaya yazmaya devam etmez, eski dosyanın file descriptor’ını tutar. Bu yüzden postrotate‘de mutlaka apachectl graceful veya kill -USR1 kullanılmalıdır.
delaycompress’i atlamak: Eğer delaycompress kullanmazsanız, Apache hala açık tuttuğu log dosyası sıkıştırılmaya çalışılır. Bu veri kaybına neden olabilir.
rotatelogs’ta timezone sorunu: -l flag’ini unutursanız loglar UTC zaman damgasıyla açılır ama sunucu yerel saatteyse dosya isimleri karışır.
# Hatalı: UTC kullanır
CustomLog "|/usr/bin/rotatelogs /var/log/apache2/access_%Y%m%d.log 86400" combined
# Doğru: Yerel saat kullanır
CustomLog "|/usr/bin/rotatelogs -l /var/log/apache2/access_%Y%m%d.log 86400" combined
Disk dolduğunda log kaybı: Disk dolduğunda hem rotatelogs hem de logrotate log yazmayı durdurur. Bunu önlemek için disk kullanım monitörinüzü doğru kurun ve rotate sayısını gerçekçi tutun.
Sonuç
Apache log yönetiminde rotatelogs ve logrotate‘in birbirini tamamlayan araçlar olduğunu gördük. rotatelogs, Apache’nin doğal bir parçası olarak gerçek zamanlı log döndürme sağlar; logrotate ise sıkıştırma, arşivleme ve temizlik konusunda çok daha güçlüdür.
Production ortamı için önerim şu şekilde özetlenebilir: Yüksek trafikli sitelerde rotatelogs ile saatlik veya günlük dosya oluşturun, logrotate ile sıkıştırın ve eski dosyaları temizleyin. Düşük trafikli sitelerde ise sadece logrotate yeterlidir, sadelik her zaman kazanır.
Konfigürasyonları yazdıktan sonra -d ve -vf parametreleriyle test etmeyi, sistemin cron/timer çalışmasını kontrol etmeyi ve en az bir kez manuel tetikleyerek çalışmayı doğrulamayı ihmal etmeyin. Log yönetimi tek seferlik bir iş değil, periyodik olarak disk kullanımını ve konfigürasyonun düzgün çalışıp çalışmadığını kontrol etmeniz gereken bir bakım rutinidir.