Tutorial

Log Management untuk Home Server — Mengumpulkan Log dari journald, rsyslog, Sampai Loki

Log Management untuk Home Server — Mengumpulkan Log dari journald, rsyslog, Sampai Loki

Ada momen di mana sebuah layanan di home server tiba-tiba down, tapi aku tidak tahu harus mulai mencari dari mana. Buka terminal, ketik systemctl status, lalu teringat bahwa log mungkin ada di /var/log, mungkin juga di journalctl, atau malah terkubur di dalam container Docker yang sudah dihapus. Rasanya seperti mencari kunci rumah di tengah malam dengan senter yang baterainya lemah: setiap sudut menyimpan kemungkinan, tapi tidak ada yang pasti.

Di sinilah log management masuk. Bukan sekadar menyimpan catatan error, tapi menyusunnya jadi sistem yang bisa dibaca, dicari, dan diandalkan saat sesuatu bermasalah. Artikel ini adalah catatan dari perjalananku menyusun log di home server, dari cara paling sederhana pakai journald, lalu ke rsyslog, sampai akhirnya bermain dengan Loki dan Grafana.

Kenapa Log Itu Lebih Penting daripada yang Terlihat

Log adalah jejak digital dari setiap keputusan yang dibuat sistem. Aplikasi mengatakan "aku menerima request ini", kernel berkata "ada hardware yang aneh", firewall mencatat "paket dari IP ini aku tolak". Tanpa log, kita hanya melihat gejala akhir: layanan mati, website 500, koneksi lambat. Dengan log, kita bisa menelusuri rantai sebab-akibat hingga ke akar masalah.

Saya suka analogikan log seperti rekam medis. Seorang dokter tidak mungkin mendiagnosis hanya dengan melihat pasien batuk; dia butuh riwayat, hasil pemeriksaan, dan tren dari waktu ke waktu. Log memberikan riwayat itu pada sistem kita. Semakin rapi rekam medisnya, semakin cepat kita tahu apa yang salah.

Masalahnya, di home server yang menjalankan banyak layanan, log bisa tersebar di banyak tempat: file teks di /var/log, output systemd di journald, log aplikasi di dalam container, atau bahkan output dari custom script yang kita tulis sendiri. Tanpa strategi, mencari satu kejadian bisa menghabiskan waktu berjam-jam.

journald — Log Pertama dari systemd

Kalau kamu pakai distribusi Linux modern seperti Debian, Ubuntu, atau Fedora, systemd sudah menangani banyak proses. Setiap unit yang dijalankan systemd — baik service, timer, maupun socket — akan mencatat output standarnya ke journald. Ini adalah log pusat pertama yang hampir selalu tersedia.

Perintah paling sering aku pakai adalah ini:

# Lihat log suatu service secara real-time
journalctl -u nginx.service -f

# Lihat log dari boot terakhir
journalctl -b

# Lihat log dalam rentang waktu tertentu
journalctl --since "1 hour ago"

# Cari log yang mengandung kata tertentu
journalctl -u myapp.service | grep "error"

Salah satu kekuatan journald adalah structured logging bawaan. Setiap pesan log disertai metadata seperti timestamp presisi mikrodetik, unit systemd, PID, dan bahkan beberapa field tambahan dari aplikasi itu sendiri. Pencarian jadi lebih kaya dibanding grep file teks biasa.

Tapi journald juga punya keterbatasan. Secara default, log disimpan dalam format biner di /var/log/journal. Meski efisien, format ini tidak bisa dibuka dengan cat atau tail biasa. Selain itu, log hanya tersimpan di satu mesin. Kalau kita punya beberapa server, kita harus masuk satu per satu untuk mencari masalah.

Untuk home server satu mesin, journald sudah cukup andal. Aku biasanya atur retensi log agar disk tidak penuh:

# Edit konfigurasi journald
sudo nano /etc/systemd/journald.conf

# Tambahkan atau ubah baris berikut
[System]
Storage=persistent
MaxFileSec=1week
SystemMaxUse=500M
SystemMaxFiles=5

Konfigurasi di atas memastikan log tetap tersimpan di disk, tapi tidak lebih dari 500 MB. File log dirotasi tiap minggu, jadi kita tidak perlu khawatir /var/log membengkak diam-diam.

rsyslog — Log Klasik yang Masih Andal

Sebelum journald hadir, rsyslog adalah raja log di dunia Linux. Sampai sekarang, dia masih banyak dipakai karena fleksibel dan berbasis file teks. Banyak aplikasi legacy dan perangkat jaringan — seperti router, switch, atau access point — masih mengirim log dalam format syslog ke port UDP 514.

Di home server, aku biasanya membiarkan rsyslog berjalan untuk menangkap log dari perangkat-perangkat tersebut. Konfigurasi sederhana untuk menerima log dari jaringan lokal seperti ini:

# File: /etc/rsyslog.conf atau /etc/rsyslog.d/10-server.conf
module(load="imudp")
input(type="imudp" port="514")

$template RemoteLogs,"/var/log/remote/%fromhost-ip%/%programname%.log"
if $fromhost-ip != '127.0.0.1' then ?RemoteLogs
& stop

Dengan konfigurasi itu, setiap perangkat yang mengirim log syslog akan memiliki folder sendiri di /var/log/remote/, diisi file sesuai nama program. Ini sangat membantu saat aku ingin melihat log router atau access point tanpa harus buka web admin-nya.

Keunggulan file teks adalah universalitasnya. Kita bisa membukanya dengan tail, grep, awk, atau bahkan tools seperti lnav. Tidak perlu database khusus. Tapi di sisi lain, file teks sulit dicari dalam skala besar. Bayangkan mencari satu baris error di antara jutaan baris log yang terpisah di puluhan file.

Loki — Log Terpusat untuk Home Server Modern

Ketika jumlah layanan mulai bertambah, aku merasa butuh tempat yang lebih nyaman untuk mencari log. Solusinya adalah Loki, log aggregation system dari Grafana Labs. Loki dirancang ringan, hemat resource, dan cocok untuk home server.

Berbeda dengan Elastic Stack yang menyimpan log sebagai dokumen JSON penuh, Loki hanya mengindeks label. Isi log tetap disimpan dalam format yang mirip object storage. Hasilnya, Loki jauh lebih hemat RAM dan CPU, sesuatu yang penting kalau home server kamu hanya pakai laptop bekas seperti milikku.

Setup paling sederhana bisa pakai Docker Compose seperti ini:

# File: docker-compose.yml
services:
  loki:
    image: grafana/loki:latest
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yml:/etc/loki/local-config.yaml
      - loki-data:/loki
    command: -config.file=/etc/loki/local-config.yaml

  promtail:
    image: grafana/promtail:latest
    volumes:
      - /var/log:/var/log:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - ./promtail-config.yml:/etc/promtail/config.yml:ro
    command: -config.file=/etc/promtail/config.yml

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana

volumes:
  loki-data:
  grafana-data:

Promtail adalah agent yang membaca log dari file lalu mengirimkannya ke Loki. Kita tinggal bilang ke Promtail: "baca file ini, kasih label itu". Nanti di Grafana, kita bisa filter log berdasarkan label seperti job, container, atau host.

Contoh konfigurasi Promtail untuk membaca log Docker dan syslog:

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push

scrape_configs:
  - job_name: system
    static_configs:
      - targets:
          - localhost
        labels:
          job: syslog
          __path__: /var/log/syslog

  - job_name: docker
    static_configs:
      - targets:
          - localhost
        labels:
          job: docker
          __path__: /var/lib/docker/containers/*/*.log

Di Grafana, query-nya mirip Prometheus tapi untuk log. Misalnya, mencari semua log yang mengandung kata error dari container Docker:

{job="docker"} |= "error"

Atau mencari log dari satu service systemd tertentu yang sudah di-forward ke file:

{job="syslog"} |= "nginx" |= "500"

Sintaksnya intuitif. Kita bisa chaining filter, regex, bahkan ekstrak field dari log dengan pattern atau regexp parser. Ini jauh lebih nyaman daripada membuka puluhan tab terminal.

Arsitektur Sederhana yang Bisa Kamu Terapkan

Kalau baru memulai, tidak perlu langsung memasang semuanya. Aku sendiri menjalankan evolusi seperti ini:

  • Tahap 1 — Satu mesin: Andalkan journalctl dan /var/log. Cukup untuk belajar dan debug masalah sederhana.
  • Tahap 2 — Beberapa layanan: Aktifkan rsyslog untuk menangkap log dari perangkat jaringan dan aplikasi yang masih pakai format syslog klasik.
  • Tahap 3 — Banyak container atau VM: Pasang Loki + Promtail + Grafana agar semua log bisa dicari dari satu dashboard.

Yang penting bukan seberapa canggih tools-nya, tapi seberapa konsisten log dikumpulkan. Aplikasi yang baru kamu deploy harus punya strategi log sejak hari pertama. Jangan menunggu incident pertama baru mikir soal log.

Untuk aplikasi yang aku tulis sendiri, aku biasanya menyusun log dengan format yang konsisten. Contoh sederhana dari aplikasi Python:

import logging
import sys

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(name)s: %(message)s",
    handlers=[
        logging.StreamHandler(sys.stdout),
        logging.FileHandler("/var/log/myapp/app.log")
    ]
)

logger = logging.getLogger("myapp")
logger.info("Server started on port 3001")

Output ke stdout akan ditangkap journald kalau aplikasi berjalan sebagai systemd service. Output ke file akan dibaca Promtail dan masuk ke Loki. Dengan begitu, log punya redundansi tanpa aku harus repot.

Praktik Terbaik yang Bisa Langsung Diterapkan

Setelah bermain dengan log beberapa lama, ada beberapa kebiasaan yang aku pelajari dan rekomendasikan:

  • Gunakan UTC atau zona waktu konsisten. Kalau log dari beberapa server punya zona waktu berbeda, mencari urutan kejadian jadi sulit. Sebaiknya semua log pakai UTC, atau paling tidak catat offset-nya.
  • Jangan log data sensitif. Password, token, dan informasi pribadi tidak boleh muncul di log. Log adalah file yang sering dibuka dan bisa lama tersimpan.
  • Tetapkan rotasi log. Baik pakai logrotate untuk file teks maupun konfigurasi retensi di journald dan Loki. Disk penuh karena log adalah masalah yang sangat bisa dicegah.
  • Beri label yang bermakna. Di Loki, label adalah kunci pencarian. Gunakan label seperti environment=production, service=api, atau host=server-lima.
  • Pantau log sekaligus metrik. Jangan hanya pasang Loki tapi tidak pernah dibuka. Buat dashboard sederhana di Grafana untuk melihat jumlah error per jam atau response time anomali.

Konfigurasi logrotate untuk aplikasi custom bisa seperti ini:

# File: /etc/logrotate.d/myapp
/var/log/myapp/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0644 www-data www-data
}

Rotasi harian dengan 14 file cadangan berarti kita menyimpan log selama dua minggu. Cukup untuk kebutuhan home server sekaligus tidak membebani storage.

Kesimpulan

Log management di home server bukan tentang memasang tools paling canggih. Ini tentang punya visibilitas. Saat sesuatu bermasalah, kita tidak perlu panik mencari jejak karena semuanya sudah tersusun rapi. Dari journald yang selalu ada, rsyslog yang andal untuk perangkat klasik, sampai Loki yang membuat pencarian log jadi nyaman — setiap tools punya perannya.

Mulai dari yang kecil. Pastikan setiap service yang kamu jalankan punya log yang bisa dibaca. Atur rotasi agar disk tidak penuh. Kalau sudah merasa butuh pencarian yang lebih cepat, baru pertimbangkan Loki. Yang terpenting, jangan menunggu masalah datang baru menyadari bahwa log yang seharusnya ada ternyata tidak pernah disimpan.

Kalau kamu punya pengalaman sendiri soal log management di home server, tulis di kolom komentar. Aku penasaran bagaimana kamu menyusun log dan tools apa yang paling sering dipakai. Jangan lupa share artikel ini kalau menurutmu bermanfaat.