File log tumbuh tanpa batas sampai memenuhi disk Anda dan mematikan server. Di API NestJS yang sibuk di Commsult Indonesia, satu hari logging verbose dapat menghasilkan beberapa gigabyte file log. Direktori /var/log yang tidak dikelola di DigitalOcean Droplet telah mengakhiri layanan produksi bagi banyak developer. Logrotate, alat rotasi log standar Linux, mencegah hal ini sepenuhnya dan hanya membutuhkan sekitar 10 menit untuk dikonfigurasi dengan benar.
Logrotate adalah utilitas yang dirancang untuk memudahkan administrasi sistem yang menghasilkan sejumlah besar file log. Ia berjalan sebagai pekerjaan cron harian (melalui /etc/cron.daily/logrotate) dan memproses file konfigurasi di /etc/logrotate.d/. Untuk setiap file log, ia menerapkan kebijakan rotasi yang dikonfigurasi: mengganti nama log saat ini, membuat yang baru yang kosong, opsional mengompresi rotasi lama, dan menghapus rotasi lama di luar hitungan retensi.
Opsi logrotate utama: daily/weekly/monthly (frekuensi rotasi), rotate N (simpan N salinan yang dirotasi), compress (gzip log lama, biasanya pengurangan ukuran 5–10x), delaycompress (kompres rotasi sebelumnya namun bukan yang terbaru — penting untuk layanan yang mungkin masih menulis ke file yang dirotasi), copytruncate (salin lalu potong alih-alih ganti nama/buat).
Tempatkan konfigurasi logrotate per-aplikasi di /etc/logrotate.d/. Untuk aplikasi NestJS yang menulis ke /var/log/nestjs/app.log: konfigurasikan rotasi harian, simpan 30 hari rotasi, kompres semua kecuali yang terbaru, dan kirim SIGUSR1 ke proses Node.js untuk membuka kembali file log (menggunakan direktif postrotate). Tanpa sinyal SIGUSR1, Node.js terus menulis ke handle file lama (yang diganti nama) dan file log baru tetap kosong.
┌─────────────────────────────────────────────────────┐
│ LOG ROTATION LIFECYCLE │
└─────────────────────────────────────────────────────┘
app.log (current, 500MB)
│
▼ [logrotate triggers]
app.log.1 (renamed) ← app writes here briefly
app.log (new, empty) ← postrotate: send SIGUSR1
│
▼ [next day]
app.log.2.gz (compressed) ← delaycompress kicks in
app.log.1 (yesterday)
app.log (current)
│
▼ [after rotate 30]
app.log.30.gz (oldest)
... older files DELETED
/var/lib/logrotate/status tracks last rotation timeDari pengalaman saya mengelola rotasi log di server Commsult Indonesia, selalu gunakan rotasi berbasis ukuran selain rotasi berbasis waktu untuk layanan traffic tinggi. Rotasi harian baik untuk log 10 MB/hari, namun jika traffic melonjak dan Anda menghasilkan 2 GB/hari, Anda menginginkan rotasi pada 500MB terlepas dari waktu. Gunakan size 500M di konfigurasi logrotate Anda sebagai pemicu batas atas.
Selalu uji konfigurasi logrotate sebelum mengandalkannya dalam produksi. Jalankan logrotate -d /etc/logrotate.d/your-app untuk dry run yang menunjukkan persis apa yang akan terjadi tanpa melakukan tindakan apa pun. Paksa rotasi segera dengan logrotate -vf /etc/logrotate.d/your-app. Periksa bahwa file log dirotasi, dikompres (setelah delaycompress berjalan di siklus berikutnya), dan bahwa aplikasi Anda menulis ke file log baru dengan benar.
Container Docker menulis log ke driver log Docker sendiri, bukan ke file yang dapat dikelola logrotate. Konfigurasikan driver log file JSON Docker dengan batas ukuran dan rotasi di /etc/docker/daemon.json: atur log-driver ke json-file dengan log-opts max-size 50m dan max-file 5. Ini memberi tahu Docker untuk merotasi log container saat mencapai 50MB dan menyimpan 5 rotasi.
# /etc/logrotate.d/nestjs-app
/var/log/nestjs/app.log {
daily
size 500M # rotate if exceeds 500MB regardless of time
rotate 30
compress
delaycompress
missingok
notifempty
create 0644 nestjs nestjs
postrotate
kill -USR1 $(cat /var/run/nestjs-app.pid) 2>/dev/null || true
endscript
}
# /etc/docker/daemon.json — Docker log limits
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "5"
}
}
# Test configuration (dry run)
logrotate -d /etc/logrotate.d/nestjs-app
# Force immediate rotation
logrotate -vf /etc/logrotate.d/nestjs-app
# Emergency: disk full recovery
du -sh /var/log/* | sort -rh | head -10
truncate -s 0 /var/log/nestjs/app.logKegagalan rotasi log diam secara default — logrotate tidak mengirim alert ketika sesuatu berjalan salah. Tambahkan pemantauan: periksa /var/lib/logrotate/status untuk melihat kapan setiap file log terakhir dirotasi, siapkan pekerjaan cron atau timer systemd yang memeriksa ukuran file log dan alert jika ada file log tunggal yang melebihi 1GB.
Saya pernah mengonfigurasi copytruncate untuk layanan NestJS karena saya tidak ingin mengimplementasikan handler SIGUSR1. Copytruncate bekerja dengan menyalin file log ke nama baru lalu memotong yang asli — namun ada kondisi balapan di mana baris log yang ditulis antara salinan dan pemotongan hilang. Untuk API traffic tinggi yang mencatat setiap permintaan, Anda bisa kehilangan ribuan entri log per rotasi.
Logrotate mengelola rotasi tingkat file namun praktik logging aplikasi yang baik mengurangi volume yang perlu dirotasi. Gunakan logging JSON terstruktur (Winston, Pino) dengan level log yang sesuai — log debug tidak boleh ada dalam produksi. Rutekan tingkat keparahan yang berbeda ke file yang berbeda: info ke access.log, kesalahan ke error.log.
Ketika disk Anda penuh dan layanan crash, langkah segera: temukan file terbesar dengan du -sh /var/log/* yang diurutkan berdasarkan ukuran, potong (jangan hapus) file log terbesar dengan truncate -s 0 /path/to/huge.log (memotong mempertahankan file descriptor sehingga aplikasi yang berjalan tidak crash), lalu paksa logrotate segera untuk menangani rotasi dengan benar.