Log Rotasyonu: logrotate Yapılandırması ve Örnekler
Disk doldu, servis cevap vermiyor, panik modunda log dosyalarını silerken yanlışlıkla önemli bir şeyi de siliyorsunuz. Tanıdık geldi mi? Log yönetimi, sysadmin’lerin en çok ihmal ettiği ama en kritik konulardan biri. logrotate ise bu sorunu sistematik ve otomatik olarak çözen, neredeyse her Linux dağıtımında hazır gelen bir araç. Bu yazıda logrotate’i sıfırdan yapılandırmayı, gerçek senaryolara göre özelleştirmeyi ve sorun gidermeyi ele alacağız.
logrotate Nedir ve Nasıl Çalışır?
logrotate, log dosyalarını belirli aralıklarla döndüren (rotate eden), sıkıştıran, arşivleyen ve eskiyen dosyaları silen bir araçtır. Daemon olarak çalışmaz, cron veya systemd timer aracılığıyla tetiklenir. Çoğu sistemde /etc/cron.daily/logrotate olarak günlük çalışır.
Temel çalışma mantığı şöyle: Belirlediğiniz kriterlere göre (boyut, zaman, satır sayısı vb.) mevcut log dosyasını yeniden adlandırır, yeni bir boş dosya oluşturur ve eski dosyaları belirttiğiniz sayıya göre saklar ya da siler. Sıkıştırma, pre/post-rotate script çalıştırma gibi ek özellikler de sunar.
Ana yapılandırma dosyası /etc/logrotate.conf olmakla birlikte, asıl tanımlamalar /etc/logrotate.d/ dizini altındaki dosyalarda tutulur. Her uygulama veya servis için ayrı bir yapılandırma dosyası oluşturmak hem yönetimi kolaylaştırır hem de paket güncellemelerinde çakışmaları önler.
Temel Yapılandırma Direktifleri
Yapılandırma dosyasına bakmadan önce sık kullanılan direktifleri anlamak gerekiyor:
Zaman direktifleri:
- daily: Her gün rotate et
- weekly: Her hafta rotate et
- monthly: Her ay rotate et
- yearly: Her yıl rotate et
Boyut direktifleri:
- size 100M: Dosya 100MB’a ulaşınca rotate et
- maxsize 200M: Zaman direktifiyle birlikte; hangisi önce gelirse
- minsize 10M: En az bu boyuta gelmedikçe rotate etme
Saklama direktifleri:
- rotate 7: Son 7 rotate edilmiş dosyayı sakla
- maxage 30: 30 günden eski dosyaları sil
Sıkıştırma direktifleri:
- compress: Eski log dosyalarını gzip ile sıkıştır
- delaycompress: Bir önceki rotate’i sıkıştırma, bir sonrakini bekle
- compresscmd xz: Farklı sıkıştırma aracı kullan
- compressoptions -9: Sıkıştırma seviyesi belirle
Davranış direktifleri:
- missingok: Log dosyası yoksa hata verme
- notifempty: Dosya boşsa rotate etme
- create 0640 root adm: Yeni log dosyasını belirtilen izin ve sahiplikle oluştur
- copytruncate: Dosyayı taşımak yerine kopyala ve orijinali sıfırla (pid olmayan servisler için)
- nocopytruncate: copytruncate’in tersi
- sharedscripts: Birden fazla dosya eşleşirse script’i yalnızca bir kez çalıştır
- su root syslog: Rotate işlemini belirtilen kullanıcı/grup olarak çalıştır
Temel Yapılandırma Dosyası İncelemesi
cat /etc/logrotate.conf
# /etc/logrotate.conf
# Varsayilan haftalik rotation
weekly
# 4 haftalik arsiv sakla
rotate 4
# Yeni log dosyasi olustur
create
# tarih son ekini kullan
dateext
# Sistem paketlerinin konfigurasyonlarini dahil et
include /etc/logrotate.d
# /var/log/wtmp icin ozel kural
/var/log/wtmp {
monthly
create 0664 root utmp
minsize 1M
rotate 1
}
# /var/log/btmp icin ozel kural
/var/log/btmp {
missingok
monthly
create 0600 root utmp
rotate 1
}
Bu varsayılan ayarlar genellikle yeterli değil. Uygulamaya özgü yapılandırmalar için /etc/logrotate.d/ altında kendi dosyalarımızı oluşturuyoruz.
Nginx için logrotate Yapılandırması
Nginx çok yoğun trafik alan bir sunucuda günde gigabyte’larca log üretebilir. İşte production’da kullandığım bir yapılandırma:
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
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
}
Burada delaycompress önemli bir detay. Nginx, eski log dosyasına yazmaya devam edebileceğinden hemen sıkıştırmak yerine bir sonraki rotate’e bırakıyoruz. sharedscripts ise access.log ve error.log gibi birden fazla dosya için postrotate script’ini sadece bir kez çalıştırmasını sağlıyor. Bu olmadan her dosya için ayrı ayrı nginx rotate sinyali gönderilir, gereksiz yük yaratır.
MySQL / MariaDB Log Rotasyonu
Veritabanı logları özellikle slow query log’lar ciddi boyutlara ulaşabilir. MySQL için dikkatli olmak gerekiyor çünkü veritabanı servisi log dosyasını kilitle tutabilir:
# /etc/logrotate.d/mysql-server
/var/log/mysql/*.log /var/log/mysql/*.err {
daily
rotate 7
missingok
create 640 mysql adm
compress
delaycompress
sharedscripts
postrotate
test -x /usr/bin/mysqladmin || exit 0
# MySQL root sifresi olmadan calistirmak icin
if [ -f /etc/mysql/debian.cnf ]; then
MYADMIN="/usr/bin/mysqladmin --defaults-file=/etc/mysql/debian.cnf"
else
MYADMIN="/usr/bin/mysqladmin --defaults-extra-file=/root/.my.cnf"
fi
if $MYADMIN ping &>/dev/null; then
$MYADMIN flush-logs
fi
endscript
}
MySQL binary log’larını bu şekilde rotate etmemelisiniz, onları expire_logs_days veya binlog_expire_logs_seconds parametresiyle MySQL’in kendi yönetimine bırakın.
Uygulama Logları için Özel Senaryo
Diyelim ki /opt/myapp/logs/ altında log üreten bir Java uygulamanız var. Uygulama log dosyasını tutmaya devam ediyor, dosyayı taşırsanız yazmayı durdurmuyor. Bu durumda copytruncate kullanmanız gerekiyor:
# /etc/logrotate.d/myapp
/opt/myapp/logs/application.log
/opt/myapp/logs/error.log {
size 50M
rotate 10
compress
delaycompress
missingok
notifempty
copytruncate
dateext
dateformat -%Y%m%d-%H%M%S
su myappuser myappgroup
}
Uyarı: copytruncate kısa bir zaman diliminde (kopyalama ile truncate arasında) log kaybına yol açabilir. Uygulamanız SIGHUP veya benzeri bir sinyalle log dosyasını yeniden açabiliyorsa copytruncate yerine o yöntemi tercih edin.
Boyut Bazlı Rotate ve Acil Durum Yapılandırması
Bazı durumlarda zaman değil boyut kritik olur. Bir hata ayıklama sürecinde debug logları açtığınızda disk çok hızlı dolabilir:
# /etc/logrotate.d/debug-app
/var/log/myapp/debug.log {
size 100M
rotate 3
compress
missingok
notifempty
copytruncate
postrotate
echo "$(date): Debug log rotated" >> /var/log/logrotate-audit.log
endscript
}
maxsize direktifi zaman bazlı rotation ile birlikte kullanışlı olur. Haftalık rotation yapılandırılmış ama dosya 500MB’a ulaşırsa haftayı beklemeden rotate etmek için:
/var/log/bigapp/app.log {
weekly
maxsize 500M
rotate 8
compress
delaycompress
missingok
notifempty
}
logrotate’i Manuel Çalıştırma ve Test Etme
Yapılandırmayı yazdınız ama gerçekten çalışıyor mu? Test etmek için:
# Dry-run (gercekten rotate etmeden ne yapacagini goster)
logrotate -d /etc/logrotate.d/nginx
# Belirli bir konfigurasyonu zorla calistir
logrotate -f /etc/logrotate.d/nginx
# Verbose modda tum konfigurasyonu calistir
logrotate -v /etc/logrotate.conf
# Hem verbose hem force
logrotate -vf /etc/logrotate.d/myapp
-d (debug/dry-run) modu production’da değişiklik yapmadan yapılandırmanızı doğrulamanın en güvenli yolu. Çıktıda hangi dosyaların rotate edileceğini, hangi script’lerin çalışacağını görebilirsiniz.
logrotate’in durumunu takip eden bir state dosyası var. Bu dosya son ne zaman rotate yapıldığını tutar:
# State dosyasini goruntule
cat /var/lib/logrotate/status
# veya eski sistemlerde
cat /var/lib/logrotate.status
Eğer test ortamında state dosyasını sıfırlamak isterseniz:
# Dikkatli olun, bu production'da yapilmamali
logrotate -f --state /tmp/logrotate-test.status /etc/logrotate.d/myapp
Systemd ile Entegrasyon
Modern sistemlerde cron yerine systemd timer kullanılabiliyor. Bazı dağıtımlarda (Arch Linux gibi) logrotate artık systemd timer ile geliyor:
# Systemd timer durumunu kontrol et
systemctl status logrotate.timer
# Timer detaylarini goster
systemctl cat logrotate.timer
# Manuel tetikle
systemctl start logrotate.service
# Logrotate servis ciktilarini goster
journalctl -u logrotate.service
Ubuntu ve Debian’da hala /etc/cron.daily/logrotate script’i kullanılıyor. Hangisinin aktif olduğunu kontrol etmek için:
# Cron job var mi?
ls -la /etc/cron.daily/logrotate
# Systemd timer aktif mi?
systemctl is-active logrotate.timer
Sık Karşılaşılan Sorunlar ve Çözümleri
“logrotate state file permission error” hatası
# State dosyasi sahipligini kontrol et
ls -la /var/lib/logrotate/status
# Gerekirse duzelt
chown root:root /var/lib/logrotate/status
chmod 644 /var/lib/logrotate/status
“error: skipping” hatası
Bu hata genellikle yapılandırma dosyasına world-write izni verildiğinde görülür. logrotate güvenlik amacıyla bu tür dosyaları reddeder:
# Konfigurasyonun izinlerini kontrol et
ls -la /etc/logrotate.d/
# Duzeltme
chmod 644 /etc/logrotate.d/myapp
chown root:root /etc/logrotate.d/myapp
Postrotate script çalışmıyor
sharedscripts yokken birden fazla dosya için script birden çok çalışıyor olabilir ya da script’in içindeki komut bulunamıyor olabilir:
# Script'i debug et
logrotate -d /etc/logrotate.d/nginx 2>&1 | grep -i script
# PATH sorununu asma
postrotate
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
/usr/sbin/nginx -s reopen
endscript
Disk dolu senaryosu
Logrotate compress yaparken geçici dosya oluşturur, disk doluysa bu da başarısız olur:
# Hemen yer ac
find /var/log -name "*.log" -size +100M -exec ls -lh {} ;
# En buyuk log dosyalarini bul
du -sh /var/log/* | sort -rh | head -20
# Acil durum icin bos bir dosya olusturup takas yap
cat /dev/null > /var/log/buyuk-uygulama.log
Merkezi Log Yönetimi ile Entegrasyon
Üretim ortamında logrotate’i rsyslog, Filebeat veya Fluentd gibi araçlarla birlikte kullanmak yaygın. Filebeat kullanıyorsanız dikkat etmeniz gereken önemli bir nokta var: Filebeat dosyayı inode ile takip eder, rotate sonrası yeni dosyayı otomatik algılar. Ancak copytruncate kullanıyorsanız Filebeat aynı inode’u takip etmeye devam eder, sorun çıkmaz.
rsyslog ile birlikte kullanırken:
# /etc/logrotate.d/rsyslog
/var/log/syslog
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages {
rotate 7
daily
missingok
notifempty
delaycompress
compress
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
Monitoring ve Alerting
logrotate sessizce çalışır, hata olduğunda çoğu zaman fark etmezsiniz. Bunu izlemek için basit bir wrapper script kullanabilirsiniz:
#!/bin/bash
# /usr/local/sbin/logrotate-monitored.sh
LOGROTATE_LOG="/var/log/logrotate-runs.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$DATE] Logrotate basliyor..." >> $LOGROTATE_LOG
if /usr/sbin/logrotate /etc/logrotate.conf 2>> $LOGROTATE_LOG; then
echo "[$DATE] Logrotate basariyla tamamlandi." >> $LOGROTATE_LOG
else
EXIT_CODE=$?
echo "[$DATE] HATA: Logrotate $EXIT_CODE kodu ile basarisiz oldu!" >> $LOGROTATE_LOG
# Slack, mail veya Telegram bildirimi gonder
echo "LOGROTATE HATASI: $(hostname) - Cikis kodu: $EXIT_CODE" |
mail -s "Logrotate Hatasi" [email protected]
fi
Bunu crontab’a eklemek için:
# Mevcut cron job'u devre disi birak
mv /etc/cron.daily/logrotate /etc/cron.daily/logrotate.disabled
# Kendi script'ini ekle
chmod +x /usr/local/sbin/logrotate-monitored.sh
echo "0 2 * * * root /usr/local/sbin/logrotate-monitored.sh" > /etc/cron.d/logrotate-monitored
En İyi Pratikler
Yıllarca production sistemleri yönetirken öğrendiklerimden derlediğim bazı önemli noktalar:
- Her uygulama için ayrı yapılandırma dosyası kullanın.
/etc/logrotate.d/altında düzenli tutmak, paket güncellemelerinde çakışmaları önler.
dateextdirektifini her zaman kullanın.app.log.1,app.log.2yerineapp.log-20240115gibi anlamlı isimler sorun gidermeyi kolaylaştırır.
missingokvenotifemptykombinasyonunu ihmal etmeyin. Özellikle servis henüz log üretmemişse gereksiz hata almamak için gerekli.
- Yeni log dosyası oluştururken
createdirektifini doğru izin ve sahiplikle belirtin. Yanlış izinler servisin log dosyasına yazamamasına yol açar.
- Rotate sonrası mutlaka test edin.
logrotate -dile dry-run yapıp çıktıyı gözden geçirin.
- Compress ile delaycompress’i birlikte kullanın aktif yazılan loglar için. Hemen sıkıştırmak veri kaybı veya corruption riskini artırır.
- State dosyasını yedekleyin. Özellikle sunucu göçü sırasında, logrotate’in ne zaman son çalıştığını bilmek önemli olabilir.
Sonuç
logrotate, doğru yapılandırıldığında disk dolması, log izini kaybetme ve servis kesintisi gibi sorunları önleyen bir araç. Ancak “kur ve unut” yaklaşımıyla değil, düzenli olarak gözden geçirerek kullanmak gerekiyor. Uygulamalarınızın log üretim hızı değişiyor, yeni servisler ekleniyor, trafik artıyor.
Her birkaç ayda bir şu kontrolleri yapmayı alışkanlık haline getirin: /var/log altındaki dosya boyutlarına bakın, logrotate state dosyasını kontrol edin, rotate edilmiş dosyaların gerçekten oluştuğunu doğrulayın ve disk kullanımının makul seviyelerde kaldığından emin olun.
Bir kez düzgün kurduğunuzda logrotate sizi pek çok gece yarısı panik senaryosundan kurtaracak. Disk dolu alarmı aldığınızda log dosyalarına bakıp “bunlar zaten yönetim altında” diyebilmek gerçekten değerli bir huzur.
