Cron log temizleme, eski kayıtları saklama süresine göre kaldırmak ve büyüyen dosyaları kontrol altında tutmak için kullanılır. Disk dolduğunda yalnızca log yazımı durmaz; uygulama geçici dosya oluşturamayabilir, veritabanı işlemleri başarısız olabilir. Buna rağmen bütün log dizinini silmek doğru başlangıç değildir: sorunu araştırmak için gereken kayıtları da kaybedebilirsiniz.
Bu rehber Linux sunucusunda kendi uygulamasının loglarını yöneten kişiler içindir. Önce arşivleri aktif dosyalardan ayıracak, silinecekleri önizleyecek, ardından işi zamanlayacaksınız. Aktif logda sıfırlama ile düzenli döndürmenin farkını da göreceksiniz. Sistem kayıtlarının yerini bilmiyorsanız /var/log/cron rehberini inceleyin; systemd journal kayıtları sıradan metin dosyaları gibi temizlenmez.
Otomatik temizlik öncesinde kapsam ve saklama süresi
Saklama süresini hata araştırması, kurum politikası ve varsa hukuki yükümlülüklere göre belirleyin. Aşağıdaki otuz günlük süre yalnızca örnektir. Silmeden önce gerekli kayıtları ayrı depolamaya aktarın ve arşivin okunabildiğini doğrulayın. Uygulamanın hâlâ yazdığı dosyayı tarihine bakarak eski kabul etmeyin; dosya yaşı tek başına kullanımda olmadığını göstermez.
Önce df -h /var/log/app ile dosya sistemini, ardından du -sh /var/log/app ile uygulama dizinini ölçün. Başka bölümün dolması bu dizini temizleyerek çözülmez. df -i ile inode kullanımını da kontrol edin: çok sayıda küçük dosya, boş gigabayt bulunsa bile yeni dosya oluşturulmasını engelleyebilir. Temizlikten sonra aynı ölçümleri karşılaştırın.
rm sonrası disk neden boşalmayabilir?
Linux'ta silme işlemi dosyanın dizindeki adını kaldırır. Bir süreç dosyayı açık tutuyorsa veri blokları son açık başvuru kapanana kadar kullanımda kalabilir. Uygulama silinmiş dosyaya yazmayı sürdürebilir. Aynı adla yeni dosya oluşturmanız eski tanıtıcıyı değiştirmez; bu nedenle dizinde dosya görünmezken disk dolu kalabilir.
sudo lsof +L1
# Alternatif inceleme:
sudo lsof | grep deleted
Çıktıda süreç adını, PID değerini ve dosya yolunu birlikte değerlendirin. +L1, bağlantı sayısı birden küçük açık dosyaları arar. Servisin belgelenmiş log yeniden açma işlemini uygulayın; her serviste reload komutu logu yeniden açmaz. Gerekirse bakım planıyla yeniden başlatın. Rastgele PID sonlandırmak yerine uygulamanın düzgün kapanış prosedürünü izleyin.
Adım adım find ile eski arşivleri temizleme
Güvenli find temizliği, aktif logu değil yalnızca kapatılmış arşivleri hedefler ve silme komutundan önce aynı filtreyle önizleme yapar. Kapsamı dizin, dosya türü, ad ve yaş ile daraltın; listede beklenmeyen tek bir dosya bile varsa görevi zamanlamayın.
- Kapsamı ayırın: Örnekte yalnızca kapatılmış ve sıkıştırılmış .log.gz dosyaları seçilir. Aktif app.log dosyası kapsam dışındadır. Dizinin başka uygulamalarla paylaşılmadığını doğrulayın.
- Önizleyin: İlk komutu temizlik görevini çalıştıracak kullanıcıyla yürütün. Korunması gereken bir kayıt görünüyorsa tarih ve dosya adı filtresini düzeltin.
- Scripti kaydedin: İçeriği /usr/local/sbin/app-log-cleanup.sh dosyasına yerleştirin. Script ve üst dizini yetkisiz kullanıcıların değiştirememesini sağlayın.
- Deneyin ve zamanlayın: Önce scriptte -delete yerine -print kullanın. Sonuç doğruysa silmeyi etkinleştirin; manuel kontrolden sonra crontab -e ile son satırı ekleyin.
/usr/bin/find /var/log/app -mindepth 1 -maxdepth 1 -type f -name '*.log.gz' -mtime +30 -print
# /usr/local/sbin/app-log-cleanup.sh
#!/bin/sh
set -eu
LOG_DIR='/var/log/app'
[ -d "$LOG_DIR" ] || { echo 'Log dizini bulunamadı' >&2; exit 1; }
/usr/bin/find "$LOG_DIR" -mindepth 1 -maxdepth 1 -type f -name '*.log.gz' -mtime +30 -print -delete
# Kullanıcı crontab kaydı; çıktı yolu önceden yazılabilir olmalı:
0 3 * * * /bin/sh /usr/local/sbin/app-log-cleanup.sh >> /var/log/app-cleanup.log 2>&1
-mindepth 1 başlangıç noktasını işlem dışında bırakır; yanlış kök seçimini güvenli hale getirmez. -maxdepth 1 alt dizinlere inmeyi önler. -type f yalnızca normal dosyaları seçer. Varsayılan find davranışı sembolik bağlantıları takip etmez. GNU find yaş hesabında tamamlanmış yirmi dört saatlik dönemleri kullanır: -mtime +30, yuvarlanmış yaşın otuzdan büyük olmasıdır; tam otuz gün dolduğu anda silme anlamına gelmez.
İlk gerçek senaryoda günlük 03:00 çalışması, düşük trafik saatinde eski arşivleri kaldırır. Sunucunun saat dilimini kontrol edin; script yollarını kendi sisteminizde doğrulayın. Kurulum ayrıntıları Linux cron rehberindedir. Temizlik çıktısının yazıldığı app-cleanup.log dosyasına da rotasyon tanımlayın. Hataları /dev/null yönlendirmesiyle saklamak yerine ilk çalışmaları inceleyin.
truncate ile aktif logu yerinde sıfırlama
Acil durumda içeriğinden vazgeçebildiğiniz tek bir aktif dosyayı sıfırlayabilirsiniz. -c dosya yoksa yenisini oluşturmayı önler. Dosyanın adı ve mevcut açık tanıtıcıları korunur; eski kayıtlar geri alınamaz. Araştırma için gerekli satırları önce güvenli depolamaya alın ve dosyanın doğru uygulamaya ait olduğunu doğrulayın.
sudo truncate -c -s 0 /var/log/app/app.log
# Kabuk yönlendirmesinde yetki kabuğa verilmelidir:
sudo sh -c ': > /var/log/app/app.log'
Sıfırlama, yazıcı sürecin mevcut dosya konumunu başa almaz. Uygulama append kipinde yazmıyorsa eski konumdan devam ederek seyrek dosya oluşturabilir. Bu işlemi bütün servislerde kayıpsız çözüm kabul etmeyin. Boyut değiştirme seçenekleri GNU truncate belgesinde açıklanır; düzenli işletimde uygulamanın döndürme desteği daha uygundur.
logrotate ile boyuta göre döndürme
İkinci senaryoda app.log gün içinde hızla büyür ve bir ay beklemek uygun değildir. Aşağıdaki kuralı /etc/logrotate.d/custom-app içine koyabilirsiniz. Boyut denetim anında 500M sınırını geçtiğinde dosya döndürülür. Bu yapılandırma dosyayı sürekli izlemez; logrotate yalnızca çağrıldığında kontrol eder ve dosya arada sınırı aşabilir.
/var/log/app/app.log {
size 500M
rotate 7
compress
missingok
notifempty
copytruncate
}
# Değişiklik yapmadan tüm yapılandırmayı inceleyin:
sudo logrotate -d /etc/logrotate.conf
copytruncate dosyayı arşive kopyalar ve özgün dosyayı yerinde sıfırlar. Servisin dosyayı yeniden açmasını gerektirmez; fakat kopyalama ile sıfırlama arasında yazılan satırlar kaybolabilir. Yeniden açmayı destekleyen uygulamalarda yeniden adlandırma ve belgelenmiş reopen işlemi tercih edilebilir. rotate 7 yedi arşiv tutar; boyuta göre döndürmede mutlaka yedi gün demek değildir.
Önce dağıtımınızdaki logrotate timer veya cron.daily düzenini inceleyin. Daha sık boyut kontrolü gerekiyorsa ortak durum dosyasını ve mevcut zamanlamayı dikkate alarak tek çalışma düzeni seçin; çakışan ikinci görev eklemeyin. Kopya ve sıkıştırma için boş alan gerektiğini hesaba katın. Direktifler ve kayıt kaybı uyarısı logrotate projesinin kılavuzunda bulunur.
Gerçek senaryo: create ve postrotate ile kayıp penceresini kapatmak
Uygulamanın belgeleri SIGHUP sonrasında log dosyalarını yeniden açtığını söylüyorsa copytruncate yerine create kullanabilirsiniz. Bu yöntemde eski dosya yeniden adlandırılır, yeni ve boş bir dosya doğru sahiplikle oluşturulur; postrotate adımı da servise yeni dosyaya geçmesi için sinyal gönderir. Böylece büyük bir dosyayı kopyalama maliyeti ve kopyalama-sıfırlama arasındaki kayıp penceresi ortadan kalkar, fakat sinyalin gerçekten işlenmesi zorunlu hale gelir.
- Uygulamanın SIGHUP davranışını belgesinden doğrulayın. Servisin systemd üzerindeki gerçek adını ve ana sürecini
systemctl show custom-app.service -p MainPID --valueile kontrol edin; örnekteki custom-app adını kendi servisinizle değiştirin. - create satırındaki app kullanıcı ve grubunun sistemde bulunduğunu
id appile doğrulayın. İzin ve sahipliği uygulamanın güvenlik gereksinimine göre değiştirin; aynı yapılandırmada copytruncate kullanmayın. - Kuralı /etc/logrotate.d/custom-app olarak kaydedin ve önce debug çalıştırın. Gerçek döndürmeden sonra bir deneme kaydı üretip yeni dosyaya yazıldığını, eski arşivin okunabildiğini ve servisin hata vermediğini kontrol edin.
/var/log/app/app.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 app app
sharedscripts
postrotate
/bin/systemctl kill --signal=HUP --kill-who=main custom-app.service
endscript
}
sudo logrotate -d /etc/logrotate.conf
sudo lsof /var/log/app/app.log /var/log/app/app.log.1
delaycompress, en son arşivin sıkıştırılmasını bir sonraki döndürmeye bırakır; yeniden açması yavaş süreçler için ek güvenlik payı sağlar, ancak diskte daha uzun süre sıkıştırılmamış kopya tutar. sharedscripts birden fazla dosya eşleştiğinde postrotate bloğunu tek çalışma içinde yürütür. postrotate komutunun sonuna || true ekleyerek hatayı gizlemeyin; sinyal başarısızsa servis eski dosyaya yazmaya devam edebilir ve bunu izlemeniz gerekir. Uygulama log yeniden açmayı desteklemiyorsa bu yapılandırmayı kullanmayın.
Doğrulama ve sorun giderme
Log temizliğini yalnızca cron'un çalışmasıyla değil, doğru dosyaların seçilmesi ve disk alanının gerçekten geri kazanılmasıyla doğrulayın. Önizleme çıktısını, logrotate kararını ve temizlik sonrası df ölçümünü aynı dosya sistemi için karşılaştırın.
| Belirti | Olası neden | Kontrol komutu | Çözüm |
|---|---|---|---|
| Dosyalar silindi ama disk boşalmadı | Bir süreç silinen dosyayı açık tutuyor | sudo lsof +L1 /var/log/app | Süreci bulun; belgelenmiş log yeniden açma adımını uygulayıp df ölçümünü tekrarlayın. |
| find beklenmeyen dosyaları seçiyor | Yol, derinlik veya tarih filtresi geniş | /usr/bin/find /var/log/app -mindepth 1 -maxdepth 1 -type f -name '*.log.gz' -mtime +30 -print | -delete olmadan listeyi inceleyin; deseni ve saklama sınırını daraltın. |
| find Permission denied veriyor | Üst dizinlerde geçiş veya silme yetkisi eksik | namei -l /var/log/app/app.log | Yolun her halkasındaki izinleri inceleyin; yalnız gerekli kullanıcıya dar yetki verin. |
| Boyut aşıldığı halde rotasyon yok | logrotate çağrılmıyor veya kural uygulanmıyor | sudo logrotate -d /etc/logrotate.conf | Debug çıktısında kuralı ve considering log satırını bulun; mevcut zamanlayıcıyı doğrulayın. |
| Günlük rotasyon hiç başlamıyor | Dağıtımın logrotate timer'ı çalışmıyor | systemctl status logrotate.timer | Timer ile cron.daily düzenini karşılaştırın; yalnız bir tetikleme düzenini etkin ve çalışır tutun. |
| create sonrası uygulama log yazamıyor | Yeni dosyanın sahibi veya kipi yanlış | ls -ld /var/log/app; ls -l /var/log/app/app.log | create satırındaki kullanıcı, grup ve izinleri servis hesabına göre düzeltin. |
| postrotate sonrası eski dosyaya yazım sürüyor | Sinyal işlenmedi veya yanlış servise gitti | sudo lsof /var/log/app/app.log /var/log/app/app.log.1 | Servis adını ve SIGHUP desteğini doğrulayın; postrotate hatasını gizlemeyin. |
| Boş alan var ama yeni dosya açılamıyor | inode sayısı tükenmiş olabilir | df -i /var/log/app | Küçük arşiv sayısını ve inode kullanımını azaltın; yalnız bayt boyutuna odaklanmayın. |
Debug kipi dosya döndürmez; karar çıktısını gerçek işlem sanmayın. Aşağıdaki ilk örnek silinecek tek arşivi gösterir, ikinci örnek ise silinmiş ama hâlâ açık bir dosyanın diskte yer tuttuğunu kanıtlar.
$ /usr/bin/find /var/log/app -mindepth 1 -maxdepth 1 -type f -name '*.log.gz' -mtime +30 -print
/var/log/app/app.log.20260927.gz
$ sudo lsof +L1 /var/log/app
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
python 842 app 3w REG 252,2 1073741824 0 131245 /var/log/app/app.log.1 (deleted)
İkinci durumda aynı adla yeni dosya oluşturmak açık tanıtıcıyı kapatmaz. Servisi belgelenmiş yöntemle yeni loga geçirdikten sonra lsof çıktısının temizlendiğini ve df değerinin düzeldiğini kontrol edin.
Sık karşılaşılan hatalar ve çözümleri
find: missing argument to '-exec'
Sonlandırıcı eksiktir veya kabuk noktalı virgülü tüketmiştir. -exec kullanıyorsanız sonuna kaçışlı noktalı virgül koyun. Basit silme işleminde -delete kullanmak bu ayrıştırma sorununu önler; önizlemeyi yine atlamayın.
Disk hâlâ dolu ama dosyalar silindi
Açık silinmiş dosyaları lsof +L1 ile bulun ve ilgili servisin logu yeniden açmasını sağlayın. Ardından aynı dosya sistemini df ile ölçün. Sonuç değişmiyorsa başka dizinleri, inode tüketimini ve depolama anlık görüntülerini araştırın.
logrotate: skipping because parent directory has insecure permissions
Üst dizinin sahipliği veya yazma izinleri güvenli kabul edilmiyordur. chmod 777 uygulamayın. Sahipliği ve grup izinlerini servisin gereksinimine göre düzeltin; 755 yalnızca uygun dizinler için örnektir. Uygulama kullanıcısıyla döndürme gerekiyorsa su kullanıcı grup direktifini değerlendirin.
find: No such file or directory
Uygulama yolu veya bağlama noktası değişmiş olabilir. Scriptin başındaki dizin kontrolünü koruyun; yol yoksa görev hata vermelidir. Eksik yolu daha geniş bir kökle otomatik değiştirmeyin.
Permission denied
Silme için üst dizinde gerekli yazma ve geçiş izinleri gerekir. Kullanıcı kimliğini, sahipliği ve güvenlik politikasını kontrol edin. Bütün işi root yapmak yerine yalnızca gerekli dizin için yetki tanımlayın.
cronjob.com.tr ile HTTP tabanlı alternatif
Uygulamanızda https://example.com/api/maintenance/purge-logs gibi kontrollü bir bakım uç noktası geliştirebilirsiniz. Bu adres yalnızca uygulamanın kapatılmış kayıtlarını veya veritabanındaki eski olayları temizlesin. İstemciden dosya yolu ve kabuk komutu kabul etmesin; saklama süresi sunucuda tanımlansın. Yerel sistem loglarının yönetimi ise sunucu içinde kalmalıdır.
- Uç noktayı POST kabul edecek ve X-Maintenance-Token header değerini sunucudaki gizli değerle doğrulayacak şekilde hazırlayın. Yanlış token için işlem başlamadan 401 veya 403 döndürün.
- Panelde HTTPS URL, POST metodu, özel header ve 0 3 * * * zamanlamasını girin. Saat dilimini seçin; localhost ve özel ağ adreslerine istek gönderilemez.
- Manuel çalıştırmayla uygulamadaki sonucu kontrol edin. Tekrarlanan istek güvenle karşılanmalı; uzun temizlikler küçük gruplarla işlenmelidir.
Cron ifadeli işlerde yanıt bekleme sınırı 290 saniyedir. Bağlantı hatası olmadan HTTP 200–399 başarı sayılır; bu sonuç bütün kayıtların temizlendiğini tek başına kanıtlamaz. Varsayılan üç ardışık hata eşiğinde erişim sorunu, düzelince düzelme e-postası gönderilir; aynı işin bildirimleri arasında en az altmış dakika vardır. Uygulama sonucunu HTTP kaydıyla birlikte değerlendirmek için cron loglama rehberini kullanın.
Sıkça Sorulan Sorular (SSS)
Çalışan servisin log dosyasını rm ile silersem ne olur?
Dosyanın dizindeki adı kaldırılır; süreç dosyayı açık tutuyorsa disk alanı son açık başvuru kapanana kadar kullanımda kalabilir.
Dosyayı silmeden içini nasıl boşaltırım?
truncate -c -s 0 /var/log/app/app.log komutu mevcut dosyayı sıfırlar. Önce gerekli kayıtları koruyun ve uygulamanın append kipinde yazdığını doğrulayın.
copytruncate kayıpsız mıdır?
Hayır. Kopyalama ile sıfırlama arasında yazılan log satırları kaybolabilir; logu yeniden açabilen servislerde uygun rotasyon yöntemini tercih edin.
Log temizleme cron'u ne sıklıkla çalışmalıdır?
Arşiv silme için günlük çalışma başlangıç olabilir. Sıklığı dosya üretim hızı, boş alan ve saklama ihtiyacına göre belirleyin; boyut kontrolünü ayrıca planlayın.
logrotate debug çıktısı dosyaları değiştirir mi?
Hayır. logrotate -d /etc/logrotate.conf komutu hata ayıklama kipinde yapılacakları gösterir; dosyaları döndürmez veya silmez. Yine de yanlış kapsamı gerçek çalıştırmadan önce bu çıktıda düzeltin.
create ile copytruncate arasında nasıl seçim yaparım?
Uygulama sinyal sonrası log dosyasını yeniden açabiliyorsa create ve uygun postrotate adımını tercih edin. Yeniden açma desteği yoksa copytruncate kullanılabilir; ancak kopyalama ile sıfırlama arasındaki satırların kaybolabileceğini kabul ederek test edin.
Bakım uç noktanızı zamanlayın
cronjob.com.tr ücretsizdir; kayıtta kredi kartı istenmez. HTTP üzerinden çalışan bakım işinizi zamanlayabilirsiniz.
Ücretsiz Başla →