Refleksi Anak Penasaran dan Gejala Nyata

Saya pernah bertanya-tanya, seperti anak kecil yang melihat deretan kode dan bertanya apakah developer dulu menulis semuanya secara manual. Pertanyaan itu tidak lama kemudian terlontar dalam tim ketika antrean job berulang kali menumpuk dengan perilaku seperti "kode manual": tidak ada perubahan baru, tapi antrian layanan back-end tiba-tiba melemah.

Kasus yang dihadapi adalah antrean job pengiriman notifikasi push yang tiba-tiba bertahan selama 8-12 menit, padahal biasanya selesai di bawah 3 menit. Tidak ada error HTTP, tetapi tingginya waktu penyelesaian menyebabkan backlog dan pengalaman pengguna terdegradasi. Di sinilah observabilitas mengambil peran utama.

Metrik Observabilitas yang Menjawab Gejala

1. Monitoring Queue dan Service Latency

Dashboard sistem menunjukkan peningkatan queue depth dan spike dalam histogram latency worker. Metrik tersebut berasal dari Prometheus dan ditampilkan di Grafana: antrean Redis secara konsisten naik, sementara worker mengeksekusi job satu per satu dengan gap 200+ ms.

Observasi awal ini menyiratkan bottleneck pada eksekusi job, bukan pada pengiriman event atau API gateway.

2. Log dan Trace yang Menyambung Cerita

Log dari Loki/Loki-label menunjukkan pola berikut saat antrean menumpuk:

{job="notification-worker"} |= "Processing job" |~ "task_id="

Melacak log tersebut mengungkap bahwa job berhenti selama sekitar 9 detik antara langkah fetch data dan send payload, tetapi tidak menghasilkan exception. Trace Jaeger yang terkait menyorot span panjang pada operasi database tertentu.

Di sini terlihat pentingnya menyambungkan log ke trace: log memberi konteks per event, trace menunjukkan distribusi waktu.

Analisis Root Cause

Trace menunjukkan bahwa setiap job memanggil stored procedure yang membaca data user dan preferences berulang-ulang. Saat backlog meningkat, koneksi database tidak ditutup dengan baik, menghasilkan antrian pada connection pool. Koneksi yang tertahan menjelaskan gap 9 detik pada log.

Investigasi konfigurasi Express/worker mengungkap bahwa pooling client Postgres tidak menggunakan idleTimeoutMillis tertinggi dan tidak membuang koneksi rusak. Jumlah worker bertambah saat antrean panjang, mengikis jumlah koneksi yang tersedia.

Perlu dicatat bahwa ini bukan bug kode, tetapi desain yang mengandalkan koneksi terbuka lama. Tanpa observabilitas, kita akan menyalahkan queue atau network.

Langkah Perbaikan dan Pencegahan

  • Optimasi Connection Pooling: Set max sesuai kapasitas, tambahkan idleTimeout 30000 ms, dan pastikan worker menutup koneksi di block finally. Ini mengurangi risiko connection leak.
  • Batch Query dan Caching Sementara: Menggabungkan fetch user preferences untuk beberapa job sekaligus mengurangi frekuensi akses database. Caching dalam memori worker sementara meningkatkan throughput saat spike terjadi.
  • Alerting Observabilitas: Tambahkan alert jika queue length > 100 atau connection pool wait time > 2s. Alert akan menggerakkan tindakan sebelum pengguna merasakan degradasi.

Setiap perubahan diuji dengan beban sintetis: mengirim 200 job secara paralel ke worker observasi sambil menonton metrik latency dan connection usage.

Menyampaikan Temuan ke Tim yang Masih Penasaran

Ketika menjelaskan hasil ini kepada tim yang masih bertanya-tanya apakah ada "kode manual" berantakan, pendekatannya harus konkret:

  1. Tunjukkan dashboard: queue depth dan connection pool wait time menurun setelah penyesuaian.
  2. Jelaskan trace: span database memendek karena pooling dan batching.
  3. Sampaikan risiko jika perubahan tidak diterapkan (backlog, timeout, user churn), sehingga tim melihat nilai observabilitas dalam memancing akar masalah.

Berikan dokumentasi singkat atau template log query yang bisa digunakan ulang. Dengan begitu, rasa penasaran berubah menjadi referensi teknis—seperti anak kecil yang akhirnya memahami cara kerja mainan favoritnya.

Kesimpulan

Observabilitas memberi jawaban konkret untuk pertanyaan "apakah developer dulu menulis kode manual": bukan tentang siapa, tetapi tentang bagaimana kita bisa memahami dan memperbaiki sistem. Gejala, metrik, log, dan trace saling melengkapi untuk mengungkap akar masalah dan memastikan perbaikan terukur. Pendekatan ini bukan teori, melainkan praktik debugging terstruktur yang bisa direplikasi tim lain kapan pun antrian backend tampak bermasalah lagi.