# Membangun Observability Menyeluruh dengan Prometheus, Grafana, dan Loki

> Diterbitkan oleh Literally Web ID pada 21 Oct 2026
> Sumber: https://literally.web.id/articles/membangun-observability-menyeluruh-dengan-prometheus-grafana-dan-loki

---

## 1. Alarm Tengah Malam: Saat Layanan Produksi Mulai Tumbang

Pukul 02:45 WIB. Ponsel saya bergetar liar di atas nakas, memecah keheningan malam dengan nada dering PagerDuty yang paling mematikan. Layar menyala terang, menampilkan notifikasi merah menyala: `High5xxErrorRate` pada layanan utama e-commerce kita. Belum sempat nyawa terkumpul sepenuhnya, Slack channel insiden sudah dibanjiri keluhan dari tim customer support bahwa ribuan transaksi checkout gagal total, sementara gateway pembayaran melaporkan timeout masif. Sebagai Principal SRE yang bertugas on-call minggu ini, detik-detik awal seperti ini selalu memacu adrenalin hingga titik maksimal.

Sistem backend kita berjalan di atas klaster Kubernetes dengan arsitektur microservices berbasis Node.js dan Go, dibungkus oleh Nginx Ingress Controller dan dilindungi oleh Cloudflare di sisi edge. Ketika saya membuka terminal, grafik latensi di Grafana mendadak melompat vertikal seperti roket SpaceX, dari rata-rata 45 milidetik langsung menembus angka 4,8 detik sebelum akhirnya terputus karena connection timeout. Ada sesuatu yang sangat masif sedang mencekik infrastruktur kita, dan jika kita tidak segera menemukannya dalam hitungan menit, kerugian finansial perusahaan akan meroket tajam.

Namun, kepanikan bukanlah strategi mitigasi. Menatap layar terminal yang berkedip-kedip, saya tahu persis bahwa modal utama kita malam ini bukanlah asumsi, melainkan data. Mari kita mulai investigasi digital ini dengan menelusuri jejak yang ditinggalkan oleh sistem.

## 2. Jejak Digital: Menelusuri Anomali Log & Lonjakan Metrik

Langkah pertama dalam menghadapi misteri infrastruktur skala besar adalah mengikuti aliran data mentah. Saya langsung melompat ke Prometheus untuk melihat metrik tingkat makro dari klaster kita. Kueri PromQL sederhana langsung saya eksekusi untuk memantau penggunaan resource CPU dan Memory pada pod-pod backend Node.js kita:

```promql
sum(rate(container_cpu_usage_seconds_total{namespace="production", container="api-backend"}[5m])) by (pod)
```

Hasilnya mengejutkan: tidak ada lonjakan CPU yang tidak wajar. Penggunaan CPU pod-pod tersebut stabil di kisaran 40%. Namun, ketika saya beralih memeriksa metrik penggunaan memori lewat kueri `container_memory_working_set_bytes`, kurvanya menunjukkan garis lurus ke atas yang agresif, merayap mendekati batas limit 2 Gigabyte per pod sebelum akhirnya kernel Linux melakukan OOM (Out Of Memory) Killer dan merestart pod secara paksa. Ah, pola klasik *memory leak*!

> [!WARNING]
> Jangan pernah berasumsi lonjakan error 502 atau 504 selalu disebabkan oleh masalah jaringan atau database. Seringkali, pod backend yang mati mendadak akibat OOM Killer oleh kernel akan memutus koneksi upstream secara kasar, meninggalkan Nginx kebingungan dan melontarkan error gateway.

Tetapi metrik makro dari Prometheus saja tidak cukup untuk memberi tahu *siapa* atau *apa* yang memicu kebocoran memori ini. Di sinilah kekuatan Grafana Loki masuk sebagai penyelamat. Saya membuka dashboard Loki dan menulis kueri LogQL untuk menyaring baris log akses dari Nginx dan error log dari aplikasi Node.js yang mengandung status kode 500 dalam 15 menit terakhir:

```logql
{namespace="production", app="api-backend"} |= "error" | json | status_code >= 500
```

Baris demi baris log mengalir deras di layar terminal Grafana Explore. Di antara ribuan tumpukan log tersebut, sebuah pola mulai terlihat jelas. Ada ribuan request bersamaan yang memanggil endpoint pencarian produk dengan parameter query string yang tidak biasa—sebuah payload JSON yang sangat bersarang (deeply nested) dan dirancang untuk memicu operasi rekursif berat di dalam kode parser backend kita. Ini bukan sekadar bug; ini adalah kombinasi antara celah efisiensi kueri database MySQL dan serangan *Denial of Service* tingkat aplikasi.

## 3. Membongkar Biang Kerok: Akar Masalah yang Sebenarnya

Setelah menarik korelasi antara metrik Prometheus, log Loki, dan melacak jejak request di sistem APM, akar masalah mulai terkuak dengan telanjang. Tiga minggu lalu, tim produk merilis fitur pencarian filter lanjutan. Fitur ini mengizinkan pengguna menyaring produk berdasarkan berbagai atribut dinamis yang disimpan di dalam kolom JSON bertipe LONGTEXT pada tabel MySQL MariaDB.

Masalahnya terletak pada cara backend Node.js memproses parameter tersebut. Ketika sebuah query dengan struktur JSON bersarang yang tidak wajar masuk, ORM yang kita gunakan melakukan deserialisasi objek secara rekursif tanpa batasan kedalaman (*depth limit*). Akibatnya, alokasi heap memory melonjak drastis hingga menghabiskan ruang V8 engine. Redis caching yang kitaandalkan di depan ternyata gagal menyelamatkan karena parameter query tersebut selalu unik (cache miss 100%), memaksa setiap request langsung menghantam database dan memicu *garbage collection* yang berjalan konstan namun gagal membebaskan memori.

```sql
-- Kueri SQL bermasalah yang mengeksekusi JSON_EXTRACT tanpa batasan indeks optimal
SELECT id, title, attributes FROM products 
WHERE JSON_EXTRACT(attributes, '$.filters.nested.criteria') LIKE '%target_value%';
```

Kueri SQL di atas melakukan *Full Table Scan* pada jutaan baris data karena kolom JSON tidak diindeks secara memadai dengan fitur *Generated Columns* di MySQL. Kombinasi antara *Full Table Scan* di database, lonjakan alokasi memori heap di Node.js, dan ketiadaan *rate limiting* yang ketat di level Nginx/Cloudflare menciptakan *domino effect* yang merubuhkan seluruh klaster dalam hitungan menit.

> [!TIP]
> Selalu terapkan validasi skema yang ketat menggunakan pustaka seperti Zoi atau Joi pada setiap payload input API, dan batasi kedalaman objek JSON maksimal 3 tingkat untuk mencegah serangan *JSON payload blowup*.

## 4. Tindakan Darurat: Menghidupkan Kembali Layanan dalam Hitungan Menit

Waktu menunjukkan pukul 03:15 WIB. Layanan masih down dan pelanggan terusmenerus mendapati halaman error. Kita tidak punya waktu untuk melakukan *hotfix* kode aplikasi secara utuh dan menjalankan proses *CI/CD pipeline* yang memakan waktu 15 menit. Kita butuh tindakan darurat tingkat infrastruktur sekarang juga!

Berikut adalah rangkaian perintah terminal one-liner siap salin yang saya eksekusi seketika untuk meredakan situasi:

```bash
# 1. Segera skala-up pod backend untuk mendistribusikan beban memori
kubectl scale deployment api-backend --replicas=10 -n production

# 2. Terapkan rate limiting sementara via Nginx Ingress annotation untuk memblokir IP penyerang
kubectl annotate ingress main-ingress nginx.ingress.kubernetes.io/limit-rps="10" -n production --overwrite

# 3. Hapus cache Redis yang kotor jika diperlukan, atau restart layanan queue Supervisor
sudo supervisorctl restart all
```

Di sisi Cloudflare Edge, saya juga langsung mengaktifkan aturan *WAF Managed Rules* untuk menantang (challenge) setiap request yang membawa payload JSON mencurigakan dengan kedalaman argumen lebih dari 5 level. 

Dalam kurun waktu kurang dari 120 detik setelah eksekusi perintah tersebut, grafik metrik di Prometheus mulai menunjukkan penurunan latensi yang signifikan. Penggunaan memori pod stabil kembali di angka 45%, dan *error rate* terjun bebas dari 85% kembali ke angka normal di bawah 0.01%. Layanan hidup kembali, dan helaan nafas lega pun terdengar di ruang kerja virtual tim.

## 5. Kebijakan Retrospektif: Menambal Celah agar Tak Pernah Terulang

Insiden pukul 03:00 pagi ini memberikan pelajaran mahal. Memiliki tumpukan teknologi observability modern seperti Prometheus, Grafana, dan Loki tidak ada artinya jika kita tidak menutup celah arsitektural dari akarnya. Siang harinya, kami menggelar rapat *post-mortem* blameless bersama seluruh engineer.

Ada tiga keputusan arsitektural defensif mutlak yang langsung kita implementasikan hari itu juga:

1. **Optimalisasi Database & Indeks:** Kita mengubah kolom atribut JSON di MySQL menjadi *Virtual Generated Columns* yang kemudian diberi indeks B-Tree agar kueri pencarian tidak lagi melakukan *Full Table Scan*.
2. **Penerapan Validasi Payload Keras:** Tim backend menambahkan middleware validasi ketat di pintu masuk API Node.js untuk menolak mentah-mentah request dengan struktur JSON yang melebihi kedalaman tertentu.
3. **Arsitektur Caching Berlapis:** Menerapkan pembatasan *cache-control* yang agresif di Redis dan Edge Caching Cloudflare untuk mencegah *cache stampede* pada kueri pencarian populer.

> [!IMPORTANT]
> Observability bukanlah tujuan akhir, melainkan alat bantu investigasi. Perbaikan sejati selalu dimulai dari penulisan kode yang aman, perancangan indeks database yang tepat, dan penerapan prinsip *defense-in-depth* pada infrastruktur web.

## 6. Pasang Alarm: Otomasi Deteksi Dini untuk Tim On-Call

Agar insiden serupa tidak lagi membangunkan saya di tengah malam tanpa peringatan dini yang akurat, kami memperbarui aturan *Alertmanager* di Prometheus dan Grafana. Kita tidak lagi hanya memantau saat layanan *sudah mati*, melainkan mendeteksi gejala awal sebelum bencana terjadi.

Berikut adalah konfigurasi file `prometheus-alert-rules.yaml` valid yang kita pasang untuk mendeteksi potensi *memory leak* dan lonjakan latensi secara proaktif:

```yaml
groups:
  - name: production-infrastructure-alerts
    rules:
      - alert: HighMemoryConsumptionWarning
        expr: sum(container_memory_working_set_bytes{namespace="production", container="api-backend"}) by (pod) > 1.8 * 1024 * 1024 * 1024
        for: 3m
        labels:
          severity: warning
        annotations:
          summary: "Pod {{ $labels.pod }} mendekati batas memori kritis (OOM risk)"
          description: "Penggunaan memori melebihi 1.8GB selama lebih dari 3 menit. Segera investigasi potensi memory leak."

      - alert: APIHighLatencySpike
        expr: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{namespace="production"}[5m])) by (le)) > 2.0
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Latensi API P99 melonjak tinggi di atas 2 detik"
          description: "99% request pada endpoint backend mengalami kelambatan ekstrem. Periksa beban database atau network bottleneck."
```

Dengan aturan alert yang presisi ini, sistem kini dapat mengirimkan peringatan *warning* ke kanal Slack jauh sebelum kernel Linux sempat mengeksekusi OOM Killer. Kita telah mengubah tumpukan Prometheus, Grafana, dan Loki dari sekadar alat pemantau pasif menjadi perisai pertahanan proaktif yang menjaga kestabilan seluruh ekosistem infrastruktur web kita 24/7.