Bir sabah sunucunuzun diski dolmuş ve suçlu tek bir dosya: haftalardır büyüyen 30 GB'lık bir uygulama logu. Linux'ta bu sorunun standart çözümü logrotate'tir. logrotate, log dosyalarını belirli aralıklarla veya belirli bir boyutu aşınca arşivler, isterseniz sıkıştırır ve belirlediğiniz sayıdan eski arşivleri siler. systemd journal ise kendi boyut sınırlarıyla ayrıca yönetilir.

Bu rehberde logrotate'in nasıl çalıştığını, yapılandırma sözdizimini, copytruncate ile create + postrotate arasındaki kritik farkı, yeni bir kuralı -d ve -f ile nasıl test edeceğinizi ve journal'ı journald.conf içindeki SystemMaxUse ile nasıl sınırlayacağınızı Ubuntu 24.04 üzerinde adım adım anlatıyoruz. Logların nerede tutulduğunu ve nasıl okunduğunu Linux loglarını okuma yazısında bulabilirsiniz.

Önce Ölçün: Disk Gerçekten Loglarla mı Doldu?

Önce Ölçün: Disk Gerçekten Loglarla mı Doldu?
bash
# Genel doluluk
df -h

# /var/log altında en büyük 15 öğe
sudo du -xh /var/log 2>/dev/null | sort -h | tail -15

# Journal ne kadar yer kaplıyor?
journalctl --disk-usage

journalctl --disk-usage, arşivlenmiş ve aktif tüm journal dosyalarının toplamını gösterir. Büyük dosya düz metin bir logsa logrotate kuralına, journal ise journald.conf ayarlarına bakacaksınız. Disk loglar dışında bir nedenle dolduysa disk doldu hatası, dosya sayısı yüzünden dolduysa inode doldu hatası rehberi daha uygundur.

logrotate Ubuntu'da Nasıl Çalışır?

Ubuntu 24.04'teki logrotate paketi; programı (/usr/sbin/logrotate), ana yapılandırmayı (/etc/logrotate.conf), kural dizinini (/etc/logrotate.d/), bir logrotate.timer / logrotate.service çiftini ve /etc/cron.daily/logrotate dosyasını kurar. Kılavuz sayfasının belirttiği gibi logrotate normalde günde bir kez çalıştırılır (cron ile veya systemd kullanılan sistemlerde logrotate.timer ile). Hangi dosyanın en son ne zaman döndürüldüğü varsayılan olarak /var/lib/logrotate/status durum dosyasında tutulur.

bash
# Zamanlayıcı etkin mi, en son ve bir sonraki çalışma ne zaman?
systemctl list-timers logrotate.timer
systemctl status logrotate.service

# Ana yapılandırma ve paketlerin kurduğu kurallar
cat /etc/logrotate.conf
ls /etc/logrotate.d/

Nginx, PHP-FPM ve rsyslog gibi paketler kendi kurallarını /etc/logrotate.d/ altına kendileri ekler; örneğin Ubuntu'nun php8.3-fpm paketi /etc/logrotate.d/php8.3-fpm dosyasını kurar. Sorun genellikle paket dışında kurduğunuz uygulamaların kendi log dosyalarında çıkar: bunlar için kuralı siz yazmalısınız.

Yapılandırma Sözdizimi

Yapılandırma Sözdizimi: daily / weekly / monthly, rotate N, compress, delaycompress

Bir kural, bir veya daha fazla dosya yolu (joker karakter kullanılabilir) ve süslü parantez içindeki yönergelerden oluşur. Aşağıdaki tablo en sık kullanılan yönergeleri, kılavuz sayfasındaki anlamlarıyla özetler:

YönergeNe yapar?
daily / weekly / monthlyDöndürme sıklığı: her gün, haftada bir, ayda bir
rotate NSilinmeden önce kaç arşivin saklanacağı
compressEski sürümleri varsayılan olarak gzip ile sıkıştırır
delaycompressBir önceki arşivin sıkıştırılmasını bir sonraki döngüye erteler
missingokDosya yoksa hata vermeden geçer
notifemptyBoş dosyayı döndürmez
size / maxsize / minsizesize: yalnızca boyut aşılınca döndürür; maxsize: süre dolmasa da boyut aşılınca döndürür; minsize: süre dolsa bile boyut aşılmadan döndürmez
maxage NN günden eski arşivleri siler
dateextArşive sayı yerine tarih uzantısı ekler (varsayılan biçim -%Y%m%d)
create mod sahip grupDöndürmeden hemen sonra (postrotate çalışmadan önce) yeni boş log dosyasını oluşturur
copytruncateDosyanın kopyasını alıp orijinali yerinde sıfır boyuta indirir
postrotate ... endscriptDöndürmeden sonra çalışan betik
sharedscriptsJoker karakterle eşleşen tüm dosyalar için betiği yalnızca bir kez çalıştırır
su kullanıcı grupDöndürmeyi root yerine belirtilen kullanıcı ve grupla yapar

copytruncate mi, create + postrotate mi?

Bu, logrotate yapılandırmasındaki en önemli karardır. Çalışan bir süreç log dosyasını açık tutar ve dosyaya dosya tanıtıcısı (file descriptor) üzerinden yazar. Dosyayı yeniden adlandırdığınızda süreç, yeni adı verilen eski dosyaya yazmaya devam eder. Bu yüzden logrotate'in iki yolu vardır:

YöntemNasıl çalışır?Ne zaman?Dezavantaj
create + postrotateDosya yeniden adlandırılır, yenisi oluşturulur, ardından uygulamaya log dosyasını yeniden açması için sinyal veya komut gönderilirUygulama log dosyasını yeniden açmayı destekliyorsa (Nginx, PHP-FPM, rsyslog gibi)Doğru yeniden açma komutunu bilmeniz gerekir
copytruncateDosya kopyalanır, orijinal yerinde sıfırlanır; süreç aynı dosyaya yazmaya devam ederUygulamaya log dosyasını kapatması söylenemiyorsaKılavuza göre kopyalama ile sıfırlama arasındaki çok kısa aralıkta bazı log satırları kaybolabilir

Nginx için resmî belgeler, USR1 sinyalinin log dosyalarını yeniden açtığını belirtir; nginx -s reopen komutu da aynı işi yapar. Ubuntu'nun nginx-common paketi kendi kuralını /etc/logrotate.d/nginx olarak kurar; içeriğini cat ile inceleyin, genellikle elle değiştirmeniz gerekmez. Kendi uygulamanız dosyaya doğrudan yazıyor ve bir yeniden açma mekanizması sunmuyorsa copytruncate pratik bir çözümdür.

Adım Adım: Kendi Uygulamanız İçin Kural Yazın

Örnek senaryo: /var/www/uygulama/storage/logs/ altına www-data kullanıcısıyla log yazan bir PHP uygulaması ve /var/log/benim-api/ altına kendi dosyasına yazan, yeniden açma desteği olmayan bir Node.js servisi.

bash
sudo nano /etc/logrotate.d/uygulama
text
/var/www/uygulama/storage/logs/*.log {
    su www-data www-data
    daily
    rotate 14
    missingok
    notifempty
    compress
    delaycompress
    maxsize 200M
    create 0640 www-data www-data
}

/var/log/benim-api/*.log {
    weekly
    rotate 8
    missingok
    notifempty
    compress
    delaycompress
    maxsize 500M
    copytruncate
}
  • su www-data www-data: Log dizini root dışında bir kullanıcıya aitse logrotate döndürmeyi güvenli bulmayıp atlayabilir ve hata mesajında su yönergesini önerir. Bu satır döndürmeyi dizin sahibinin kimliğiyle yapar.
  • maxsize: Günlük döndürme ayarlı olsa bile logrotate yalnızca kendisi çalıştığında (normalde günde bir kez) boyutu kontrol eder. Saatte birkaç GB log üreten bir uygulama için zamanlayıcıyı daha sık çalıştırmanız gerekir; kılavuz, hourly için de bunun şart olduğunu belirtir.
  • delaycompress: Bir önceki arşivin hemen sıkıştırılmamasını sağlar; uygulama kısa bir süre eski dosyaya yazmaya devam etse bile satır kaybolmaz.

Kuralı Test Edin: -d ve -f

-d hata ayıklama kipidir: kılavuza göre loglarda hiçbir değişiklik yapılmaz ve durum dosyası güncellenmez. Yeni bir kuralı her zaman önce bu kiple çalıştırın:

bash
# Kuru çalıştırma: ne yapacağını gösterir, hiçbir şeyi değiştirmez
sudo logrotate -d /etc/logrotate.d/uygulama

# Zorla döndürme ve ayrıntılı çıktı (gerçekten döndürür)
sudo logrotate -v -f /etc/logrotate.d/uygulama

# Sonucu kontrol edin
ls -lh /var/www/uygulama/storage/logs/
sudo grep uygulama /var/lib/logrotate/status

-f, logrotate gerekli görmese bile döndürmeyi zorlar; canlı sistemde ilk denemeden sonra arşiv dosyalarının oluştuğunu ve uygulamanın yeni dosyaya yazdığını (tail -f ile) doğrulayın. Tüm yapılandırmayı birlikte test etmek için yol olarak /etc/logrotate.conf verin. Son olarak zamanlayıcının bir sonraki çalıştırmasında hata olmadığından emin olun:

bash
sudo systemctl start logrotate.service
sudo journalctl -u logrotate.service -n 30 --no-pager

systemd Journal Boyutunu Sınırlayın

journalctl ile okunan loglar logrotate ile değil, systemd-journald tarafından yönetilir. journald.conf belgesine göre Storage=auto, /var/log/journal dizini varsa kalıcı (diskte), yoksa yalnızca bellekte (/run/log/journal) saklama yapar. Kalıcı depolamada SystemMaxUse= journal'ın en fazla ne kadar disk kullanabileceğini, SystemKeepFree= ise diğer kullanımlar için ne kadar boş alan bırakılacağını belirler. Varsayılanlar dosya sisteminin sırasıyla %10'u ve %15'idir; hesaplanan her değer 4G ile sınırlanır. MaxRetentionSec= ile kayıtların en uzun saklama süresini de ayarlayabilirsiniz (varsayılan 0, yani kapalı).

Ana dosyayı düzenlemek yerine bir drop-in dosyası kullanmanız önerilir; belge, /etc/systemd/journald.conf.d/ altındaki .conf dosyalarının okunduğunu ve adların iki haneli sayıyla başlatılmasını önerir. Tüm seçenekler [Journal] bölümünde yer alır:

bash
sudo mkdir -p /etc/systemd/journald.conf.d
sudo nano /etc/systemd/journald.conf.d/50-boyut.conf
ini
[Journal]
SystemMaxUse=500M
SystemKeepFree=1G
MaxRetentionSec=1month
bash
# Ayarları uygula
sudo systemctl restart systemd-journald

# Mevcut fazlalığı hemen temizle (yalnızca arşivlenmiş dosyalara etki eder)
sudo journalctl --rotate
sudo journalctl --vacuum-size=500M

# Kontrol
journalctl --disk-usage

journalctl belgesine göre --vacuum-size, --vacuum-time ve --vacuum-files yalnızca arşivlenmiş journal dosyalarında çalışır; aktif dosyayı da kapsamak için önce --rotate çalıştırın. Bu temizlik tek seferliktir; kalıcı sınır SystemMaxUse ile sağlanır.

Sık Karşılaşılan Sorunlar

Sık Karşılaşılan Sorunlar: Arşiv oluşuyor ama uygulama hâlâ eski dosyaya (.1) yazıyor, parent directory has insecure permissions hatası, Kural hiç çalışmıyor gibi, Log günde bir...
BelirtiOlası nedenÇözüm
Arşiv oluşuyor ama uygulama hâlâ eski dosyaya (.1) yazıyorcreate kullanılmış ama uygulama dosyayı yeniden açmamışDoğru postrotate komutunu ekleyin veya copytruncate kullanın
parent directory has insecure permissions hatasıLog dizini root dışında bir kullanıcıya ya da gruba yazılabilirKurala su kullanıcı grup ekleyin
Kural hiç çalışmıyor gibiZamanlayıcı devre dışı veya kural dosyasında sözdizimi hatasısystemctl list-timers logrotate.timer ve logrotate -d çıktısını inceleyin
Log günde bir kez döndürülüyor ama arada disk doluyorlogrotate günde bir kez çalışıyormaxsize ekleyin ve zamanlayıcıyı daha sık çalıştırın; asıl çözüm aşırı log üreten hatayı düzeltmektir
Journal sınırı aşılıyor gibi görünüyorAyar uygulanmadı veya aktif dosya henüz arşivlenmedisystemd-journald servisini yeniden başlatın, --rotate ardından --vacuum-size çalıştırın

Loglar bir anda çok hızlı büyüyorsa genellikle bir uygulama hatayı döngü içinde tekrar tekrar yazıyordur. Bu durum CPU ve disk G/Ç üzerinde de baskı oluşturur; CPU %100 tespiti ve load average rehberleri nedenin izini sürmenize yardım eder.

Sık Sorulan Sorular

Büyük log dosyasını rm ile silsem olmaz mı?

Dosyayı açık tutan bir süreç varsa rm sonrası disk alanı süreç dosyayı kapatana kadar boşalmaz. Acil durumda dosyayı yerinde boşaltmak (sudo truncate -s 0 dosya.log) alanı hemen serbest bırakır; ardından kalıcı bir logrotate kuralı ekleyin.

daily ile maxsize birlikte kullanılabilir mi?

Evet. Kılavuza göre maxsize, belirtilen süre dolmadan bile boyut aşıldığında döndürmeyi sağlar. Ancak kontrol yalnızca logrotate çalıştığında yapılır.

Docker konteyner logları da logrotate ile mi döndürülür?

Docker'ın varsayılan json-file log sürücüsü kendi boyut seçeneklerine sahiptir ve bu seçenekler Docker tarafında ayarlanır; logrotate ile konteyner log dosyalarına müdahale etmek yerine Docker belgesindeki log sürücüsü ayarlarını kullanın. Compose tarafı için Docker Compose rehberine bakın.

Journal'ı tamamen kapatmalı mıyım?

Önerilmez. Servis hatalarını teşhis etmek için journal en hızlı kaynaktır. SystemMaxUse ile makul bir üst sınır koymak, hem diski korur hem de son kayıtları elinizde tutar. Belleğin kısıtlı olduğu durumlar için OOM killer rehberine de göz atın.

Yazılım ve hizmet adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen projeler veya şirketlerle ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Linux loglarını okuma · Disk doldu hatası · Inode doldu hatası · Load average nedir · OOM killer çözümü · systemd servis yönetimi · Cron job rehberi