On this page10 sections
Setelah server OpenClaw saya berjalan cukup lama, saya sadar saya cuma cek kondisinya lewat SSH setiap kali "kepikiran" — tidak ideal. Jadi saya bikin dashboard monitoring sendiri: ringan, tanpa dependency berat, dan bisa diakses dari subdomain kapan saja.
1. Kenapa Perlu Dashboard Monitoring Sendiri?
Ada banyak tools monitoring siap pakai seperti Netdata atau Grafana, tapi untuk kebutuhan server pribadi skala kecil, saya lebih suka sesuatu yang:
- Tidak butuh database atau agent berat terpisah
- Bisa saya kontrol tampilannya sendiri, sesuai identitas visual situs
- Cukup untuk memantau hal-hal penting: CPU, RAM, disk, jaringan, dan aktivitas mencurigakan dari fail2ban
Solusinya: satu file Node.js kecil yang membaca data langsung dari sistem (/proc, systemctl, fail2ban-client), tanpa dependency eksternal.
2. Arsitektur Singkat
Agent menyajikan dua hal: file dashboard statis di /, dan endpoint JSON di /api/metrics plus live log stream di /api/logs/stream. Apache tinggal meneruskan trafik dari subdomain publik ke port lokal ini.
3. Agent: Membaca Metrics Asli dari Server
Beberapa metrik yang paling sering salah dihitung kalau asal pakai library adalah CPU usage dan free memory. Untuk CPU, saya ambil dua snapshot waktu idle/total dari os.cpus() dengan jeda singkat, lalu hitung selisihnya:
function getCpuUsage() {
return new Promise(resolve => {
const start = cpuSnapshot();
setTimeout(() => {
const end = cpuSnapshot();
const idleDiff = end.idle - start.idle;
const totalDiff = end.total - start.total;
resolve(100 - (100 * idleDiff / totalDiff));
}, 250);
});
}
Untuk RAM, saya tidak pakai os.freemem() karena di Linux angka itu tidak memperhitungkan cache/buffer yang sebenarnya bisa dilepas. Lebih akurat baca MemAvailable langsung dari /proc/meminfo.
Untuk disk dan status service, agent memanggil df dan systemctl is-active lewat execSync. Untuk IP yang diban, agent memanggil fail2ban-client status sshd dan parsing baris Banned IP list.
4. Live Log Stream dengan Server-Sent Events
Untuk log yang mengalir real-time seperti journalctl -f, saya pakai Server-Sent Events (SSE) daripada WebSocket — lebih sederhana untuk kasus satu arah seperti ini. Agent men-spawn proses journalctl -f per koneksi, lalu setiap baris baru langsung dikirim ke browser:
const tail = spawn('journalctl', ['-f','-n','0','-o','short-iso', ...units]);
tail.stdout.on('data', chunk => {
chunk.toString().split('\n').filter(Boolean).forEach(line => {
res.write(`data: ${JSON.stringify(line)}\n\n`);
});
});
Kalau browser tidak mendukung SSE atau koneksi terputus, dashboard otomatis jatuh ke polling biasa lewat endpoint /api/logs.
5. Dashboard: UI dengan Mode Live & Demo Fallback
Hal yang saya anggap penting: dashboard tidak boleh terlihat "rusak" kalau agent sedang restart atau belum terpasang. Jadi ada dua mode:
- LIVE — data asli dari
/api/metrics, badge hijau - DEMO — kalau fetch gagal, dashboard otomatis pindah ke data simulasi dengan banner peringatan kuning, supaya tetap enak dilihat
Statusnya juga reaktif — ring status di panel kiri berubah dari SECURE ke ELEVATED atau CRITICAL tergantung beban CPU/RAM dan jumlah failed login.
6. Menjalankan Agent sebagai Service
Supaya agent tetap hidup setelah SSH ditutup dan otomatis restart kalau crash, saya daftarkan sebagai systemd service:
sudo cp server-watch.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now server-watch
sudo systemctl status server-watch
7. Reverse Proxy dengan Apache
Karena server saya pakai Apache (bukan Nginx), konfigurasinya sedikit berbeda — terutama untuk endpoint SSE yang butuh buffering dimatikan supaya log tidak "macet" dulu sebelum sampai ke browser.
sudo a2enmod proxy proxy_http headers
sudo cp apache-status.conf /etc/apache2/sites-available/status.nanjarbudiman.com.conf
sudo a2ensite status.nanjarbudiman.com
sudo apache2ctl configtest && sudo systemctl reload apache2
sudo certbot --apache -d status.nanjarbudiman.com
Bagian pentingnya ada di blok <Location "/api/logs/stream">, di mana SetEnv no-gzip 1 dan ProxyTimeout 3600 mencegah Apache memotong koneksi streaming sebelum waktunya.
8. Mengamankan Endpoint Publik
Karena dashboard ini akhirnya diakses lewat subdomain publik, dan menampilkan hostname, IP yang diban, serta jumlah percobaan login gagal, saya tidak mau membiarkannya benar-benar terbuka. Tiga opsi yang saya pakai bergantian:
- API key — set
STATUS_API_KEYdi environment variable service - Basic auth di Apache — lewat
htpasswd, paling simpel untuk dipasang - Publik apa adanya — cocok kalau memang mau dijadikan status page terbuka seperti milik provider hosting
9. Demo Live
Dashboard ini sudah aktif dan bisa dilihat langsung:
Buka status.nanjarbudiman.com →Kalau tampil badge DEMO, artinya agent sedang tidak terhubung — dashboard tetap menampilkan data simulasi agar halaman tidak kosong.