logrotate ile Log Dosyalarını Otomatik Döndürme ve Arşivleme
Yıllar önce bir gece yarısı çağrı aldığımda disk dolmuştu. Sebep? Log dosyaları. O gece “logrotate neden varsayılan olarak her yere kurulmaz ki” diye homurdanırken, aslında sorunun logrotate’in yokluğunda değil, onu doğru yapılandırmamış olmamda yattığını fark ettim. O geceden bu yana log yönetimi konusunda epey deneyim biriktirdim ve bugün bu deneyimi sizinle paylaşmak istiyorum.
logrotate Nedir ve Neden Önemlidir
Log dosyaları, sistemlerin “siyah kutusu”dur. Bir sorun yaşandığında geriye dönüp bakabileceğiniz tek kaynaktır. Ancak denetlenmeden bırakıldıklarında, bu dosyalar disk alanınızı tüketir, okumayı zorlaştırır ve sistemin genel sağlığını tehdit eder. logrotate, Linux sistemlerde bu sorunu çözmek için tasarlanmış, onlarca yıllık olgunluğa sahip bir araçtır.
logrotate’in yaptığı iş özetle şudur: Belirli kurallara göre log dosyalarını döndürür (rotate eder), sıkıştırır, arşivler ve gerekirse belirli bir sayının üzerindeki eski kopyaları siler. Bütün bunları cron aracılığıyla otomatik olarak yapar; yani bir kez doğru yapılandırdıktan sonra işiniz biter.
logrotate Kurulumu ve Temel Yapısı
Çoğu dağıtımda logrotate zaten kurulu gelir. Kontrol etmek için:
which logrotate
logrotate --version
Eğer kurulu değilse:
# Debian/Ubuntu
sudo apt install logrotate
# RHEL/CentOS/AlmaLinux
sudo dnf install logrotate
logrotate’in yapılandırma dosyaları iki yerde bulunur:
- /etc/logrotate.conf: Ana yapılandırma dosyası, genel varsayılanlar burada tanımlanır
- /etc/logrotate.d/: Uygulama bazlı yapılandırmaların tutulduğu dizin
Ana yapılandırma dosyasına bakalım:
cat /etc/logrotate.conf
Tipik bir çıktı şöyle görünür:
# Haftalık döndür
weekly
# 4 hafta sakla
rotate 4
# Döndürme sonrası yeni log dosyası oluştur
create
# Tarihi dosya adına ekle
dateext
# Sıkıştır
compress
# Uygulama bazlı yapılandırmaları dahil et
include /etc/logrotate.d
Temel Direktifler ve Parametreler
logrotate yapılandırmasında kullanılan direktifleri iyi anlamak, güçlü kural setleri oluşturmanın temelidir.
daily: Log dosyasını her gün döndürür.
weekly: Haftada bir döndürür.
monthly: Ayda bir döndürür.
rotate N: N adet eski kopyayı saklar, fazlasını siler. rotate 7 ile 7 günlük arşiv tutulur.
compress: Eski log kopyalarını gzip ile sıkıştırır.
delaycompress: Sıkıştırmayı bir sonraki döngüye erteler. Aktif kullanılan log dosyaları için önemlidir.
missingok: Log dosyası yoksa hata vermez, sessizce geçer.
notifempty: Dosya boşsa döndürme işlemi yapmaz.
create MODE OWNER GROUP: Döndürme sonrası belirtilen izin ve sahiplikle yeni dosya oluşturur. Örneğin create 0640 www-data adm.
dateext: Eski dosyalara sayı yerine tarih eki ekler. access.log-20240115 gibi.
dateformat FORMAT: Tarih formatını özelleştirir. dateformat -%Y%m%d-%H%M%S şeklinde kullanılabilir.
size N: Dosya belirtilen boyuta ulaştığında döndür. size 100M, size 1G gibi kullanılır.
maxsize N: Döngüden bağımsız olarak bu boyuta ulaşınca döndür.
minsize N: Bu boyuta ulaşmadan döndürme.
copytruncate: Döndürme öncesi dosyayı kopyalar, sonra orijinali sıfırlar. Dosyayı açık tutan süreçler için kullanılır.
postrotate/endscript: Döndürme sonrası çalıştırılacak komutlar.
prerotate/endscript: Döndürme öncesi çalıştırılacak komutlar.
sharedscripts: Birden fazla dosya eşleşirse, postrotate/prerotate bloklarını sadece bir kez çalıştırır.
su USER GROUP: logrotate’i belirtilen kullanıcı olarak çalıştırır.
Gerçek Dünya Senaryosu 1: Nginx Log Yönetimi
Yoğun trafikli bir web sunucusunda Nginx log dosyaları günde birkaç GB büyüyebilir. /etc/logrotate.d/nginx dosyasını inceleyelim ve geliştirelim:
/var/log/nginx/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then
run-parts /etc/logrotate.d/httpd-prerotate;
fi
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
Buradaki kritik nokta delaycompress direktifidir. Nginx hâlâ aktif olarak log yazdığında anlık sıkıştırma sorun çıkarabilir. delaycompress ile döndürülen dosya bir gün bekler, bir sonraki döngüde sıkıştırılır.
Gerçek Dünya Senaryosu 2: PostgreSQL Log Arşivleme
Veritabanı logları özellikle ilgi gerektirir. Hem boyut hem de saklama süresi açısından dikkatli olmak gerekir:
/var/log/postgresql/postgresql-*.log {
weekly
rotate 12
compress
delaycompress
missingok
notifempty
create 0640 postgres postgres
su postgres postgres
postrotate
/bin/kill -HUP $(cat /var/run/postgresql/*.pid 2>/dev/null) 2>/dev/null || true
endscript
}
su postgres postgres direktifi önemlidir. PostgreSQL logları postgres kullanıcısına aittir ve root olarak bu dosyalara dokunmak izin sorunlarına yol açabilir. Bu direktif, döndürme işlemini postgres kullanıcısı kimliğiyle yapar.
Gerçek Dünya Senaryosu 3: Özel Uygulama Logları ile Boyut Bazlı Döndürme
Bazen tarih değil, dosya boyutu daha anlamlı bir tetikleyicidir. Özellikle yoğun yazma yapan Java uygulamaları veya API servisleri için:
/opt/myapp/logs/*.log
/opt/myapp/logs/*.log.* {
size 500M
rotate 10
compress
delaycompress
missingok
notifempty
copytruncate
dateext
dateformat -%Y%m%d-%H%M%S
su appuser appgroup
}
Burada copytruncate kullanıyoruz. Çünkü uygulama log dosyasını açık tutarak yazıyor ve biz onu yeniden başlatamıyoruz ya da SIGHUP sinyali göndermek istemiyoruz. copytruncate, dosyayı kopyalar ve orijinali boşaltır; uygulama aynı dosya tanımlayıcısıyla yazmaya devam eder. Dezavantajı, kopyalama ile truncate arasında geçen sürede yazılan birkaç satır kaybolabilir. Bu riski kabul edebiliyorsanız kullanabilirsiniz.
logrotate’i Manuel Çalıştırmak ve Test Etmek
Yapılandırmanızı test etmenin en güvenli yolu --debug ya da eski adıyla -d bayrağıdır:
# Yapılandırmayı test et, gerçekte hiçbir şey yapma
sudo logrotate --debug /etc/logrotate.d/nginx
# Zorla döndür (cron zamanını beklemeden)
sudo logrotate --force /etc/logrotate.d/nginx
# Tüm yapılandırmayı test et
sudo logrotate --debug /etc/logrotate.conf
# Detaylı çıktı ile çalıştır
sudo logrotate --verbose /etc/logrotate.conf
--debug çıktısını dikkatlice okuyun. Hangi dosyaların kapsama girdiğini, hangi işlemlerin yapılacağını ve herhangi bir hata olup olmadığını gösterir. Üretime almadan önce bu adımı atlamayın.
logrotate Durum Dosyası
logrotate, hangi dosyanın ne zaman döndürüldüğünü /var/lib/logrotate/status ya da /var/lib/logrotate.status dosyasında tutar:
cat /var/lib/logrotate/status
Çıktı şuna benzer:
logrotate state -- version 2
"/var/log/nginx/access.log" 2024-1-15-6:0:0
"/var/log/nginx/error.log" 2024-1-15-6:0:0
"/var/log/postgresql/postgresql-main.log" 2024-1-8-6:0:0
Bu dosya çok işe yarar. Bir dosyanın neden döndürülmediğini anlamaya çalışırken buraya bakmak gerekir. Bazen yapılandırmayı değiştirdiniz ama logrotate hâlâ eski tarihi görüyor ve “henüz zamanı gelmemiş” diye geçiyor. Bu durumda ilgili satırı düzenleyebilir ya da --force ile zorla çalıştırabilirsiniz.
Cron ile Otomatikleştirme
logrotate genellikle /etc/cron.daily/logrotate üzerinden günlük olarak çalışır. Bunu kontrol edin:
cat /etc/cron.daily/logrotate
Eğer daha sık çalıştırmanız gerekiyorsa, saatlik cron’a ekleyebilirsiniz:
# /etc/cron.hourly/logrotate dosyasını oluşturun
sudo tee /etc/cron.hourly/logrotate << 'EOF'
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit $EXITVALUE
EOF
sudo chmod +x /etc/cron.hourly/logrotate
Systemd kullanan sistemlerde ise logrotate’i timer ile yönetebilirsiniz:
# Mevcut timer'ı görüntüle
systemctl list-timers | grep logrotate
systemctl cat logrotate.timer
# Timer'ı özelleştirmek için override oluştur
sudo systemctl edit logrotate.timer
Gelişmiş Yapılandırma: Merkezi Log Arşivi
Birden fazla servisten gelen logları tek bir yapılandırmayla yönetmek ve arşivleri farklı bir konuma taşımak istiyorsanız:
# /etc/logrotate.d/all-services
/var/log/app1/*.log
/var/log/app2/*.log
/var/log/app3/*.log {
daily
rotate 7
compress
compresscmd /usr/bin/xz
compressext .xz
delaycompress
missingok
notifempty
sharedscripts
dateext
dateformat -%Y%m%d
olddir /archive/logs
createolddir 0750 root syslog
postrotate
# Arşivleri uzak sunucuya gönder
rsync -az --remove-source-files /archive/logs/*.xz backup-server:/logs/$(hostname)/
endscript
}
Burada birkaç yeni direktif göze çarpıyor:
compresscmd ve compressext: Varsayılan gzip yerine xz ile sıkıştırma. xz çok daha iyi sıkıştırma oranı sunar, ancak daha yavaştır. Log boyutlarınız büyükse ve disk alanı kritikse xz’yi tercih edebilirsiniz.
olddir: Döndürülen eski dosyaları başka bir dizine taşır. Log dosyaları ile arşivleri ayırmak istediğinizde kullanışlıdır.
createolddir: Olddir belirtilen dizin yoksa oluşturur.
Sorun Giderme: Yaygın Hatalar ve Çözümleri
Uygulamada en sık karşılaştığım sorunları paylaşayım.
“error: skipping … because parent directory has insecure permissions” hatası: logrotate, güvenlik nedeniyle log dosyasının parent dizini başkalarının yazabileceği şekildeyse çalışmaz. Çözüm:
# Dizin izinlerini kontrol et
ls -la /var/log/myapp/
# Gerekirse düzelt
chmod o-w /var/log/myapp/
# Ya da yapılandırmada su direktifi kullan
Log dosyası döndürüldükten sonra uygulama yazmayı bırakıyor: Uygulama eski dosya tanımlayıcısını tutuyordur. postrotate bloğuna uygulamayı sinyal gönderin:
postrotate
systemctl reload myapp 2>/dev/null || true
endscript
Döndürme sonrası dosya boyutu sıfırlanmıyor: copytruncate olmadan döndürme yaptığınızda ve uygulama yeniden başlatılmadığında bu olur. Uygulamayı reload edin ya da copytruncate kullanın.
logrotate’in çalışıp çalışmadığını kontrol etme:
# Son çalışma zamanını görüntüle
stat /var/lib/logrotate/status
# Sisteme ne zaman çalıştığını syslog'dan takip et
grep logrotate /var/log/syslog | tail -20
# journald kullanan sistemlerde
journalctl -u logrotate --since "1 week ago"
Disk Kullanımını İzleme ile Entegrasyon
logrotate’i sadece kurup bırakmak yetmez; etkinliğini ölçmek gerekir. Küçük bir izleme scripti:
#!/bin/bash
# /usr/local/bin/log-disk-check.sh
LOG_DIRS=("/var/log" "/opt/myapp/logs" "/archive/logs")
THRESHOLD=80
for dir in "${LOG_DIRS[@]}"; do
if [ -d "$dir" ]; then
USAGE=$(df "$dir" | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "UYARI: $dir disk kullanimi %$USAGE - Esik deger %$THRESHOLD"
logger -t log-monitor "ALERT: $dir disk usage at $USAGE%"
else
echo "OK: $dir disk kullanimi %$USAGE"
fi
fi
done
# En büyük log dosyalarını raporla
echo ""
echo "En buyuk log dosyalari:"
find /var/log -name "*.log" -type f -exec du -sh {} ; 2>/dev/null | sort -rh | head -10
Bu scripti de cron’a ekleyin:
sudo chmod +x /usr/local/bin/log-disk-check.sh
echo "0 */4 * * * root /usr/local/bin/log-disk-check.sh >> /var/log/log-monitor.log 2>&1" | sudo tee -a /etc/crontab
Sonuç
logrotate, doğru yapılandırıldığında tamamen arka planda çalışan ve hayat kurtaran bir araçtır. Yanlış yapılandırıldığında ya da hiç yapılandırılmadığında ise disk dolduğunda sizi gece yarısı uyandırır.
Önemli noktalara tekrar değinelim: Yapılandırmayı her değişiklikten sonra --debug ile test edin. delaycompress‘i aktif yazılan dosyalar için ihmal etmeyin. Dosya sahipliği sorunları yaşıyorsanız su direktifinden yardım alın. Durum dosyasını zaman zaman kontrol edin. Ve son olarak, disk kullanım izlemeyi logrotate ile paralel çalıştırın, çünkü logrotate tek başına her şeyin çözümü değildir; bir parçasıdır.
Log yönetimi can sıkıcı görünebilir ama bir sistem yöneticisinin en temel sorumluluklarından biridir. Bugün yapacağınız küçük bir yapılandırma çalışması, ileride saatlerce sürebilecek bir kriz yönetiminden sizi kurtarabilir.
