Logging Terpusat

Logging Terpusat

Bitnesia Aug 27, 2026 2 EN

Bab 38 ditutup dengan satu batasan penting soal metrik: angka CPU yang melonjak atau target yang berstatus down hanya menjawab pertanyaan apa yang terjadi, bukan mengapa itu terjadi. Menjawab pertanyaan mengapa itulah tugas log. Skenario ini sangat nyata bagi Sysadmin yang mengelola lebih dari satu server. Saat aplikasi di app01 tiba-tiba melempar error 500, dashboard Grafana dari Bab 38 memang langsung menunjukkan lonjakan error rate, tetapi baris log aplikasi yang menjelaskan stack trace penyebabnya tetap tersimpan lokal di server yang bersangkutan. Jika server itu ada sepuluh, Sysadmin harus SSH satu per satu untuk menemukan baris yang tepat, pekerjaan yang jelas tidak efisien di tengah insiden yang sedang berjalan.

Ada alasan kedua yang tidak kalah penting, yaitu keamanan. Attacker yang berhasil membobol satu server nyaris selalu menempuh langkah lanjutan, yaitu menghapus atau mengedit log lokal supaya jejaknya hilang. Jika log hanya tersimpan di server yang sama, penghapusan itu berjalan mulus tanpa hambatan. Log yang sudah dikirim dan tersimpan di server terpisah jauh lebih sulit dimanipulasi, karena Attacker perlu membobol dua sistem sekaligus, bukan satu. Bab ini membahas empat hal yang saling melengkapi untuk menjawab kedua kebutuhan tersebut: meninjau kembali journalctl secara lebih mendalam dari yang sudah disinggung di Bab 5, mengonfigurasi rsyslog agar meneruskan log ke server pusat, mengatur rotasi log dengan logrotate supaya disk tidak penuh, dan menyusun strategi retensi log yang menyeimbangkan kebutuhan investigasi dengan kapasitas storage.

39.1 Review journalctl: Membaca dan Mengelola Log Systemd Lebih Dalam

39.1.1 Journald sebagai Sumber Log Utama di Ubuntu Server

systemd-journald adalah daemon yang mengumpulkan log dari seluruh service systemd, kernel, dan proses lain di satu tempat terstruktur, sudah aktif secara default sejak instalasi dasar Ubuntu Server pada Bab 2. Bab 5 sudah memperkenalkan journalctl -u nama.service untuk membaca log satu service dan opsi -f untuk mengikuti log secara real-time, dua perintah yang paling sering dipakai sehari-hari. Bagian ini melangkah lebih jauh: memfilter log berdasarkan kombinasi unit, rentang waktu, dan tingkat keparahan (priority) sekaligus, lalu mengatur berapa lama dan seberapa besar journal lokal boleh menyimpan data sebelum data lama itu ikut diteruskan ke server pusat melalui rsyslog pada Bagian 39.2.

39.1.2 Memfilter Log Berdasarkan Unit, Waktu, dan Priority

Log mentah yang menumpuk dari puluhan service dalam semalam nyaris tidak berguna tanpa kemampuan menyaring. journalctl menyediakan filter kombinasi yang mempersempit pencarian langsung dari command line, jauh lebih cepat dibandingkan dengan membuka file log satu per satu seperti kebiasaan lama di /var/log.

Langkah Praktik

  1. Tampilkan log service Nginx dari Bab 12 dalam satu jam terakhir saja, memakai opsi --since dengan format waktu relatif.
    journalctl -u nginx.service --since "1 hour ago"
  2. Persempit ke rentang waktu spesifik dengan --since dan --until sekaligus, berguna saat menelusuri insiden yang sudah diketahui jam kejadiannya, misalnya lonjakan error yang terekam Grafana pukul 02.00 dini hari.
    journalctl --since "2026-08-28 02:00:00" --until "2026-08-28 02:30:00"
  3. Tampilkan hanya pesan dengan tingkat keparahan err ke atas (mencakup err, crit, alert, dan emerg) sejak boot terakhir, memakai opsi -p dan -b. Delapan level priority syslog berurutan dari paling ringan ke paling kritis adalah debug, info, notice, warning, err, crit, alert, dan emerg, urutan yang sama seperti level error_log Nginx yang sudah dibahas di Bagian 12.4.2.
    journalctl -p err -b
  4. Gabungkan filter unit dan priority sekaligus untuk mempersempit lebih jauh, misalnya mencari peringatan SSH yang berpotensi jadi indikasi percobaan brute force dari Attacker.
    journalctl -u ssh.service -p warning --since today

Verifikasi dan Troubleshooting

  • Format --since menerima banyak variasi, mulai dari kata kunci relatif seperti "yesterday" dan "1 hour ago" hingga format absolut "YYYY-MM-DD HH:MM:SS". Gunakan format absolut saat presisi waktu sangat penting, misalnya mencocokkan timestamp alert dari Grafana pada Bagian 38.4.
  • Jika hasil filter -p err kosong padahal Sysadmin yakin ada error, periksa terlebih dahulu apakah aplikasi memang menulis log melalui stderr dengan priority yang sesuai. Banyak aplikasi web menulis error ke stdout dengan priority info default, sehingga tidak pernah tertangkap filter priority tinggi.
  • Jalankan journalctl -u nginx.service -p err -b | wc -l untuk menghitung jumlah baris error tanpa perlu membaca satu per satu, cara cepat menilai tingkat keparahan sebelum masuk ke investigasi detail.

39.1.3 Mengatur Persistensi dan Batas Ukuran Journal Lokal

Konfigurasi journald ada di /etc/systemd/journald.conf, dan parameter Storage= di dalamnya menentukan apakah log tersimpan permanen atau hanya di memory. Pada Ubuntu Server 26.04, nilai default Storage= adalah persistent, yang secara otomatis membuat direktori /var/log/journal sejak awal dan menyimpan log di sana, melewati reboot tanpa perlu campur tangan manual. Hal ini berbeda dari sebagian tutorial lama yang masih mengajarkan langkah manual membuat direktori /var/log/journal supaya persistensi aktif, langkah yang sekarang sudah tidak diperlukan lagi di versi Ubuntu Server ini.

Langkah Praktik

  1. Cek terlebih dahulu berapa banyak disk yang sudah dipakai journal saat ini.
    journalctl --disk-usage
  2. Buka file konfigurasi journald.
    sudo nano /etc/systemd/journald.conf
  3. Tambahkan atau ubah baris SystemMaxUse di dalam blok [Journal] untuk membatasi ukuran maksimum journal persisten, misalnya 500 MB. Tanpa batas eksplisit ini, journald memakai default 10% dari kapasitas filesystem /var (dibatasi maksimum 4 GB), yang dapat menjadi terlalu besar untuk server dengan disk kecil.
    [Journal]
    SystemMaxUse=500M
  4. Restart systemd-journald agar konfigurasi baru berlaku.
    sudo systemctl restart systemd-journald

Verifikasi dan Troubleshooting

  • Konfirmasi batas baru sudah berlaku dengan mengulangi journalctl --disk-usage. Angkanya tidak langsung turun ke bawah batas baru jika ukuran journal sebelumnya masih di bawah batas tersebut. Batas ini hanya mencegah pertumbuhan lebih lanjut, bukan langsung memangkas data lama.
  • Untuk memangkas journal secara paksa tanpa menunggu batas otomatis tercapai, gunakan --vacuum-size atau --vacuum-time. Perintah berikut membuang data journal yang lebih tua dari dua minggu.
    sudo journalctl --vacuum-time=2weeks
  • Catatan jujur dari lapangan: membatasi journal lokal terlalu ketat berisiko kehilangan jejak investigasi jika server belum sempat meneruskan log ke server pusat pada Bagian 39.2 saat insiden terjadi. Pertimbangkan SystemMaxUse yang cukup longgar untuk lokal, karena strategi retensi jangka panjang yang sesungguhnya tetap dibahas tuntas di Bagian 39.4.

39.2 rsyslog: Forwarding Log ke Server Terpusat

39.2.1 Kenapa Log Perlu Dipusatkan

rsyslog adalah implementasi syslog modern yang sudah terpasang default di Ubuntu Server, bertugas menangkap log dari journald dan menuliskannya ke file klasik seperti /var/log/syslog dan /var/log/auth.log melalui aturan di /etc/rsyslog.d/50-default.conf. Kemampuan rsyslog yang membuatnya relevan untuk bab ini adalah forwarding, yaitu meneruskan salinan log tersebut ke server lain melalui jaringan, mengubah rsyslog dari sekadar pencatat lokal menjadi tulang punggung centralized logging. Bagian ini mempraktikkan skenario nyata: server app01 (192.168.1.40) yang sudah diperkenalkan sejak Bab 36 untuk latihan Ansible, sekarang meneruskan seluruh lognya ke server utama (192.168.1.10) yang berperan sebagai pusat pengumpulan log.

39.2.2 Menyiapkan Server Penerima Log

Langkah Praktik

  1. Dari server utama (192.168.1.10), buat direktori tempat log dari client tersimpan, lalu samakan kepemilikannya dengan user syslog dan group adm, sesuai dengan konfigurasi $PrivDropToUser dan $PrivDropToGroup yang sudah ditetapkan default di /etc/rsyslog.conf.
    sudo mkdir -p /var/log/remote
    sudo chown syslog:adm /var/log/remote
  2. Buat file konfigurasi baru khusus untuk menerima koneksi dari client.
    sudo nano /etc/rsyslog.d/10-remote-server.conf
  3. Isi dengan modul imtcp untuk mengaktifkan listener TCP, lalu definisikan template yang menyimpan log tiap client ke file terpisah berdasarkan hostname pengirimnya. Listener ini sengaja diikat ke ruleset khusus bernama remote-ruleset, bukan dibiarkan memakai ruleset default.
    module(load="imtcp")
    
    $template RemoteLogs,"/var/log/remote/%HOSTNAME%.log"
    
    ruleset(name="remote-ruleset") {
    	action(type="omfile" dynaFile="RemoteLogs")
    }
    
    input(type="imtcp" port="514" ruleset="remote-ruleset")
    Pengikatan ke ruleset terpisah ini bukan sekadar gaya penulisan, melainkan poin krusial yang sering jadi jebakan di lapangan. Tanpa parameter ruleset="remote-ruleset", log yang masuk lewat port 514 akan diproses lewat ruleset default yang sama dengan log lokal server itu sendiri, sehingga log milik server utama ikut tertulis ke /var/log/remote/ dan berpotensi tidak lagi sampai ke /var/log/syslog serta /var/log/auth.log versi lokalnya. Ruleset terpisah ini membuat log yang datang dari client lewat imtcp diproses sendiri tanpa menyentuh alur log lokal sama sekali, sehingga tidak perlu ada instruksi stop tambahan.
  4. Restart rsyslog agar konfigurasi baru terbaca.
    sudo systemctl restart rsyslog
  5. Buka port 514/tcp di UFW, dibatasi hanya untuk subnet lokal mengikuti pola pembatasan yang sama seperti PostgreSQL di Bagian 18.4.2 dan Netdata di Bagian 38.2.3.
    sudo ufw allow from 192.168.1.0/24 to any port 514 proto tcp

Verifikasi dan Troubleshooting

  • Pastikan rsyslog benar-benar mendengarkan di port 514.
    sudo ss -tlnp | grep 514
  • Jika service gagal restart, periksa syntax konfigurasi terlebih dahulu sebelum menebak-nebak penyebabnya.
    sudo rsyslogd -N1
  • Konfirmasi log lokal server utama sendiri tetap normal setelah perubahan ini, bukan cuma log dari client yang berhasil masuk. Kirim satu pesan uji dari server utama itu sendiri, lalu pastikan pesan tersebut tetap muncul di /var/log/syslog, bukan malah nyasar ke /var/log/remote/.
    logger "Pesan uji log lokal server utama"
    sudo tail -n 5 /var/log/syslog
    Kalau pesan ini malah muncul di /var/log/remote/, berarti parameter ruleset pada baris input() belum terpasang dengan benar.

39.2.3 Mengonfigurasi Client agar Meneruskan Log

Langkah Praktik

  1. Dari app01 (192.168.1.40), buat file konfigurasi forwarding.
    sudo nano /etc/rsyslog.d/60-forward.conf
  2. Isi dengan satu baris yang meneruskan seluruh facility dan priority (*.*) ke server utama melalui TCP. Tanda @@ ganda menunjukkan protokol TCP yang lebih andal, sedangkan satu @ berarti UDP yang lebih ringan tetapi tidak menjamin pesan sampai.
    *.* @@192.168.1.10:514
  3. Restart rsyslog di app01.
    sudo systemctl restart rsyslog
  4. Kirim satu pesan uji dari app01 memakai logger, tool bawaan untuk menulis pesan langsung ke syslog dari command line.
    logger -t forwarding-test "Pesan uji forwarding ke server pusat log"

Verifikasi dan Troubleshooting

  • Kembali ke server utama, periksa apakah file log app01 sudah muncul dan berisi pesan uji tadi.
    sudo tail -f /var/log/remote/app01.log
    Output semestinya menampilkan baris berisi tag forwarding-test beserta pesan yang baru dikirim.
  • Jika file app01.log tidak pernah muncul, urutan pengecekan yang paling efektif: pastikan terlebih dahulu UFW di server utama sudah mengizinkan port 514 (Bagian 39.2.2), lalu cek konektivitas jaringan mentah dari app01 tanpa melibatkan rsyslog sama sekali.
    nc -zv 192.168.1.10 514
  • Catatan jujur soal keamanan: konfigurasi di atas mengirim log dalam bentuk teks polos (plaintext) tanpa enkripsi, cukup aman untuk lab ini karena berjalan di jaringan lokal tepercaya seperti 192.168.1.0/24. Untuk forwarding lintas jaringan publik atau data center berbeda, rsyslog mendukung transport TLS melalui modul gtls, topik lanjutan yang tidak dibahas mendalam di sini karena memerlukan sertifikat tersendiri di luar Let's Encrypt yang sudah dipakai untuk web di Bab 17.
  • Log yang sudah tersimpan di server utama sekarang lebih tahan dari upaya penghapusan jejak oleh Attacker yang membobol app01, karena salinannya sudah aman di server terpisah begitu baris log terkirim, sekalipun app01 sendiri kemudian dikuasai penuh.

39.3 Log Rotation dengan logrotate

39.3.1 Cara Kerja logrotate dan Jadwal Eksekusinya

logrotate adalah tool bawaan Ubuntu yang memutus, mengompres, lalu menghapus file log lama secara terjadwal, mencegah file seperti /var/log/syslog bertumbuh tanpa batas hingga menghabiskan seluruh disk. Konfigurasi globalnya ada di /etc/logrotate.conf, berisi aturan default seperti rotasi weekly dan menyimpan rotate 4 generasi backlog, sementara tiap package yang butuh aturan berbeda meletakkan file konfigurasinya sendiri di direktori /etc/logrotate.d/, persis seperti konfigurasi Nginx yang sudah disinggung di Bagian 12.4.2 dan konfigurasi rsyslog bawaan yang mengatur rotasi /var/log/syslog serta /var/log/auth.log. Eksekusinya sendiri tidak lagi bergantung pada cron.daily seperti kebiasaan lama, melainkan dijalankan melalui systemd timer logrotate.timer yang berjalan harian dengan jeda acak (RandomizedDelaySec) supaya tidak semua server di jaringan yang sama menjalankan rotasi tepat pada detik yang sama.

Verifikasi dan Troubleshooting

  • Konfirmasi timer ini aktif dan lihat kapan eksekusi berikutnya dijadwalkan.
    systemctl list-timers logrotate.timer

39.3.2 Membuat Konfigurasi logrotate Kustom

Log baru yang muncul di /var/log/remote/*.log hasil forwarding pada Bagian 39.2 belum memiliki aturan rotasi apa pun, karena file ini bukan bagian dari package mana pun yang sudah menyertakan konfigurasi logrotate bawaan. Tanpa aturan tambahan, file ini akan bertumbuh terus mengikuti volume log dari app01 tanpa pernah dirotasi.

Langkah Praktik

  1. Buat file konfigurasi baru di /etc/logrotate.d/.
    sudo nano /etc/logrotate.d/remote-logs
  2. Isi dengan aturan rotasi mingguan, menyimpan 12 generasi (kurang lebih tiga bulan), dan mengompres file lama untuk menghemat disk.
    /var/log/remote/*.log {
    	weekly
    	rotate 12
    	missingok
    	notifempty
    	compress
    	delaycompress
    	create 0640 syslog adm
    	sharedscripts
    	postrotate
    		/usr/lib/rsyslog/rsyslog-rotate
    	endscript
    }
    Baris postrotate memanggil script bawaan yang sama seperti dipakai konfigurasi /etc/logrotate.d/rsyslog milik package, memberi sinyal HUP ke service rsyslog supaya ia berhenti menulis ke file lama yang baru saja dipindahkan namanya dan mulai menulis ke file baru. Tanpa langkah ini, rsyslog akan terus menulis ke file handle lama yang sudah tidak punya nama di filesystem, dan file baru akan tetap kosong meski rotasi sudah dianggap selesai.

Verifikasi dan Troubleshooting

  • Opsi delaycompress sengaja menunda kompresi file yang baru saja dirotasi sampai giliran rotasi berikutnya. Hal ini menghindari kondisi rsyslog masih menulis ke file lama yang namanya sudah berubah, tetapi file tersebut keburu dikompresi sebelum proses tulisnya benar-benar berhenti.
  • Permission 0640 syslog adm pada baris create harus konsisten dengan permission asli file /var/log/remote/*.log. File baru dengan permission longgar setelah rotasi berarti aturan create keliru dan perlu disesuaikan.

39.3.3 Menguji Rotasi Tanpa Menunggu Jadwal

Menunggu jadwal mingguan hanya untuk memastikan konfigurasi baru bekerja jelas tidak praktis. logrotate menyediakan dua opsi untuk menguji konfigurasi kapan saja tanpa mengubah jadwal aslinya.

Langkah Praktik

  1. Jalankan terlebih dahulu dalam mode debug (-d), yang hanya menampilkan simulasi tindakan tanpa benar-benar mengeksekusinya, aman dijalankan kapan saja tanpa risiko.
    sudo logrotate -d /etc/logrotate.d/remote-logs
  2. Setelah output simulasi terlihat sesuai harapan, paksa rotasi benar-benar berjalan dengan opsi -f, mengabaikan jadwal dan ukuran file yang biasanya menjadi syarat rotasi.
    sudo logrotate -f /etc/logrotate.d/remote-logs

Verifikasi dan Troubleshooting

  • Pastikan file terkompresi baru sudah muncul di direktori tersebut.
    ls -la /var/log/remote/
    Hasilnya semestinya menampilkan file baru seperti app01.log.1.gz berdampingan dengan app01.log yang sudah kosong kembali dan siap menerima tulisan baru.
  • Catatan penting saat mengulang pengujian: logrotate mencatat waktu rotasi terakhir tiap file di state file /var/lib/logrotate/status. Rotasi paksa dengan -f tetap memperbarui catatan ini, sehingga rotasi mingguan berikutnya melalui logrotate.timer tetap terjadwal normal, bukan langsung berjalan lagi begitu timer berikutnya tiba.
    grep remote /var/lib/logrotate/status

39.4 Strategi Retensi Log

39.4.1 Menentukan Durasi Retensi Berdasarkan Kebutuhan

Retensi log adalah kebijakan yang menentukan berapa lama log disimpan sebelum dihapus permanen, keputusan yang jarang punya jawaban tunggal karena tiap jenis log punya kebutuhan berbeda. Log yang disimpan terlalu singkat berisiko kehilangan jejak justru saat dibutuhkan untuk investigasi insiden, sementara log yang disimpan tanpa batas membengkakkan biaya storage tanpa manfaat tambahan yang sepadan. Tiga faktor utama yang menentukan durasi retensi yang tepat adalah kebutuhan investigasi keamanan (berapa lama biasanya sebuah insiden baru terdeteksi sejak awal terjadi), kewajiban compliance (beberapa standar seperti PCI DSS mensyaratkan retensi log audit minimal 12 bulan, dengan beberapa bulan terakhir harus langsung bisa diakses tanpa perlu restore dari arsip), dan kapasitas storage yang tersedia.

Jenis LogRetensi Lokal yang UmumAlasan Utama
auth.log / log SSH90-365 hariInvestigasi keamanan dan jejak akses, sering jadi bukti utama saat audit compliance seperti dibahas di Bab 34
Access log web (Nginx/Apache)30-90 hariAnalisis trafik dan capacity planning, jarang dibutuhkan lebih dari tiga bulan ke belakang
Log aplikasi (debug/error)14-30 hariDebugging jangka pendek, volume biasanya besar sehingga retensi panjang mahal secara storage
Audit log auditd (Bab 34)Sesuai regulasi yang berlakuKewajiban compliance eksplisit, durasi ditentukan standar industri atau regulasi setempat, bukan preferensi teknis

Angka pada tabel di atas adalah titik awal yang lazim dipraktikkan, bukan aturan baku. Sysadmin tetap perlu mengonfirmasi kebutuhan retensi yang sesungguhnya bersama tim legal atau compliance organisasi, terutama untuk log yang berkaitan langsung dengan data User atau Client, sebelum menetapkannya sebagai kebijakan resmi.

39.4.2 Mengarsipkan Log Lama ke Storage Terpisah

Retensi panjang di server utama bukan satu-satunya pilihan. Pola yang lebih efisien adalah menyimpan log terbaru di server utama untuk kebutuhan investigasi cepat, lalu mengarsipkan log yang sudah dirotasi dan dikompresi ke storage terpisah untuk retensi jangka panjang, mengurangi beban disk server produksi sekaligus menambah lapisan perlindungan lagi dari upaya penghapusan jejak oleh Attacker.

Langkah Praktik

  1. Salin file log yang sudah terkompresi hasil rotasi Bagian 39.3.3 ke server arsip terpisah memakai rsync, tool yang akan dibahas lebih lengkap sebagai fondasi strategi backup di Bab 40.
    sudo rsync -az /var/log/remote/*.gz [email protected]:/archive/logs/

Verifikasi dan Troubleshooting

  • Jadwalkan perintah rsync di atas melalui pasangan .timer dan .service, mengikuti pola yang sama seperti unit backup-harian.timer yang sudah dipraktikkan di Bagian 5.3.1, supaya proses arsip berjalan otomatis tanpa perlu dijalankan manual tiap minggu.
  • Pastikan permission dan akses SSH ke server arsip sudah memakai autentikasi key-based, bukan password, mengikuti konfigurasi SSH key yang sudah dibahas sejak Bagian 3.2, supaya proses ini bisa berjalan otomatis melalui script tanpa input manual.

Sampai di sini, log yang tadinya tersebar dan rawan hilang di tiap server kini sudah tersentralisasi ke satu tempat melalui rsyslog, dirotasi otomatis oleh logrotate supaya disk tidak pernah penuh, dan punya kebijakan retensi yang jelas soal berapa lama tiap jenis log layak disimpan. Namun demikian, log pusat yang sudah rapi ini tetap sekadar data di satu server, sama rentannya terhadap kegagalan hardware atau bencana seperti data lain mana pun. Bab 40 melanjutkan topik ini dengan strategi backup server secara menyeluruh, termasuk mem-backup log terpusat yang baru saja dibangun di bab ini, supaya seluruh data penting, bukan cuma log, benar-benar aman dari risiko kehilangan permanen.