Episode ini membahas memantau aplikasi WebSocket di production: metrik koneksi dan pesan, strategi logging, ekspos metrik ke Prometheus, Grafana, distributed tracing dengan OpenTelemetry, serta alerting.

Aplikasi yang berjalan baik di laptop bisa hancur di production tanpa kita sadari. Koneksi menumpuk, latensi naik perlahan, memori bocor — dan pengguna pergi satu per satu sebelum ada yang curiga. Monitoring adalah mata yang mengawasi aplikasi 24 jam.
Episode 18 membahas monitoring: mengumpulkan angka, dan observability: memahami keadaan sistem dari sinyal-sinyalnya. Kalian akan belajar metrik penting WebSocket, logging yang efektif, integrasi Prometheus dan Grafana, serta distributed tracing.
Beberapa angka sangat penting untuk aplikasi WebSocket:
// contoh metrik yang dicatat
const metrik = {
koneksiAktif: 0,
totalPesan: 0,
pesanPerDetik: 0,
errorTerakhir: null,
totalKoneksi: 0,
};Metrik inti aplikasi WebSocket meliputi:
Koneksi yang tumbuh tanpa batas menandakan kebocoran — klien tidak pernah menutup koneksi dengan benar.
Log yang baik menceritakan apa yang terjadi pada koneksi.
wss.on("connection", (ws, req) => {
console.log("koneksi baru:", {
ip: req.socket.remoteAddress,
waktu: new Date().toISOString(),
total: wss.clients.size,
});
ws.on("message", (data) => {
console.log("pesan masuk:", data.length, "byte");
});
ws.on("close", (code, reason) => {
console.log("koneksi ditutup:", code, reason.toString());
});
});Log koneksi baru, pesan, dan penutupan memberi garis waktu lengkap setiap koneksi. Log error harus menyertakan konteks: kode penutup, identitas klien, dan stack trace.
Jangan log semuanya setiap saat — banjir log justru menyembunyikan masalah. Gunakan level: debug untuk pengembangan, info untuk peristiwa penting, warn untuk anomali, dan error untuk kegagalan. Di production, batasi debug dan rotasi log agar disk tidak penuh.
Prometheus menarik metrik dari endpoint HTTP aplikasi.
const prometheus = require("prom-client");
const koneksiAktif = new prometheus.Gauge({
name: "websocket_koneksi_aktif",
help: "Jumlah koneksi WebSocket aktif",
});
const totalPesan = new prometheus.Counter({
name: "websocket_pesan_total",
help: "Total pesan diproses",
});
wss.on("connection", (ws) => {
koneksiAktif.inc();
ws.on("message", () => totalPesan.inc());
ws.on("close", () => koneksiAktif.dec());
});
http.createServer(async (req, res) => {
if (req.url === "/metrics") {
res.setHeader("Content-Type", prometheus.register.contentType);
res.end(await prometheus.register.metrics());
}
}).listen(9100);Gauge merepresentasikan nilai yang naik turun seperti jumlah koneksi, Counter nilai yang hanya bertambah seperti total pesan. Endpoint /metrics di port 9100 dibaca Prometheus secara berkala.
Prometheus menjadwalkan pengambilan metrik dengan konfigurasi scrape.
scrape_configs:
- job_name: "websocket-server"
scrape_interval: 15s
static_configs:
- targets: ["server-1:9100", "server-2:9100"]scrape_interval: 15s menentukan frekuensi pengambilan. Setiap instance server diekspos sebagai target terpisah, dan Prometheus menyatukan semuanya.
Grafana mengubah angka menjadi visual. Dashboard WebSocket biasanya menampilkan panel koneksi aktif, throughput pesan, latensi persentil, dan error rate. Alerting di Grafana bisa memicu notifikasi saat metrik melewati ambang, misalnya koneksi aktif menembus 80 persen kapasitas.
Distributed tracing melacak satu event melintasi banyak layanan.
const tracer = opentelemetry.trace.getTracer("websocket-server");
socket.on("message:send", async (pesan) => {
const span = tracer.startSpan("proses-pesan");
span.setAttribute("pesan.id", pesan.id);
try {
await simpanDanKirim(pesan);
span.setStatus({ code: 1 });
} catch (err) {
span.recordException(err);
span.setStatus({ code: 2 });
} finally {
span.end();
}
});tracer.startSpan(...) menandai mulai dan akhir satu operasi. Dengan konteks propagasi, kalian melihat pesan yang lambat di layanan mana ia tersangkut.
Alert harus bermakna dan bisa ditindaklanjuti.
Satu aturan penting: alert yang tidak bisa ditindaklanjuti adalah noise. Setiap alert harus punya playbook — langkah konkret untuk merespons.
Episode 18 memberi kalian penglihatan terhadap aplikasi yang berjalan: metrik kunci, log yang bermakna, dashboard Grafana, dan alert yang bisa ditindaklanjuti.
Inti yang harus dibawa pulang:
Di episode 19 berikutnya kita membahas security best practices: TLS dengan wss, autentikasi dan validasi input, proteksi dari CSWSH dan DoS, CORS, serta security header.