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.
  • dateext direktifini her zaman kullanın. app.log.1, app.log.2 yerine app.log-20240115 gibi anlamlı isimler sorun gidermeyi kolaylaştırır.
  • missingok ve notifempty kombinasyonunu ihmal etmeyin. Özellikle servis henüz log üretmemişse gereksiz hata almamak için gerekli.
  • Yeni log dosyası oluştururken create direktifini doğru izin ve sahiplikle belirtin. Yanlış izinler servisin log dosyasına yazamamasına yol açar.
  • Rotate sonrası mutlaka test edin. logrotate -d ile 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.

Similar Posts

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir