Pemrograman & Development

Observability-Driven Development: Menulis Kode dengan Asumsi Akan Gagal

Pendahuluan: Paradigma yang Terbalik Selama puluhan tahun, pengembang perangkat lunak diajarkan untuk berpikir tentang bagaimana kode mereka bekerja . Test ditulis untuk memvalida…

Pendahuluan: Paradigma yang Terbalik

Selama puluhan tahun, pengembang perangkat lunak diajarkan untuk berpikir tentang bagaimana kode mereka bekerja. Test ditulis untuk memvalidasi kebenaran, code review dilakukan untuk mencegah bug, dan dokumentasi dibuat untuk menjelaskan perilaku yang diharapkan. Namun ada satu kenyataan yang sering diabaikan: di produksi, yang paling menentukan kesuksesan sebuah sistem bukanlah seberapa baik ia bekerja saat semuanya normal, melainkan seberapa cepat tim bisa memahami apa yang salah ketika ada yang tidak beres.

Di sinilah Observability-Driven Development (ODD) masuk sebagai pergeseran cara berpikir. Alih-alih memperlakukan observability sebagai lapisan tambahan yang dipasang setelah sistem jadi, ODD menempatkannya di awal siklus pengembangan. Kode ditulis dengan asumsi bahwa ia akan gagal, dan pertanyaan utamanya bukan "apakah ini berfungsi?" melainkan "ketika ini rusak, apakah saya bisa tahu mengapa dalam hitungan menit?"

Tiga Pilar yang Sering Disalahpahami

Observability umumnya dijelaskan melalui tiga pilar: logs, metrics, dan traces. Masalahnya, banyak tim berhenti di pemahaman bahwa "kami sudah punya ketiganya" lalu menganggap pekerjaan selesai. Padahal ketiganya hanya alat; yang menentukan adalah kualitas sinyal yang dihasilkan.

Log yang penuh dengan pesan generik seperti "error occurred" tanpa konteks justru menjadi noise. Metrics yang mengukur hal-hal tidak relevan hanya menghabiskan biaya penyimpanan. Traces yang tidak dikorelasikan dengan identitas pengguna atau request tertentu kehilangan nilai investigasinya. ODD menuntut pengembang untuk bertanya sejak awal: sinyal apa yang benar-benar saya butuhkan untuk menjawab pertanyaan "mengapa ini gagal?" pada pukul tiga pagi?

Structured Logging sebagai Kontrak, Bukan Catatan Sampingan

Salah satu praktik paling konkret dalam ODD adalah memperlakukan log sebagai bagian dari kontrak sistem, sama seperti API. Setiap log yang ditulis harus menjawab minimal tiga hal: apa yang terjadi, konteks apa yang menyertainya, dan bagaimana korelasinya dengan request atau transaksi lain.

Contoh sederhana: daripada menulis logger.info("user logged in"), tulis logger.info("user_login_success", user_id=u.id, session_id=s.id, latency_ms=elapsed, region=req.region). Perbedaannya terasa ketika ada insiden. Log pertama hanya memberi tahu bahwa sesuatu terjadi; log kedua memberi kemampuan untuk memfilter, mengagregasi, dan menyusun hipotesis dalam hitungan detik.

Di sinilah ODD menyentuh desain, bukan sekadar operasional. Pengembang dipaksa memikirkan dimensi-dimensi apa yang akan berguna saat investigasi, dan dimensi itu harus diputuskan sebelum insiden terjadi, bukan saat panik.

Distributed Tracing dan Kebenaran yang Terfragmentasi

Di sistem monolitik, satu stack trace biasanya cukup untuk memahami alur eksekusi. Di arsitektur microservices, kebenaran menjadi terfragmentasi: satu request pengguna bisa melewati lima belas service, masing-masing dengan log sendiri. Tanpa korelasi, tim akan menghabiskan berjam-jam mencocokkan timestamp antar log yang berbeda zona waktu.

Observability-Driven Development mendorong penyebaran trace context sejak awal. Setiap request membawa identifier yang konsisten dari pintu masuk hingga pintu keluar, memungkinkan tim merekonstruksi perjalanan lengkap sebuah transaksi. Nilainya bukan hanya teknis, tapi juga organisasional: ketika setiap tim bisa melihat kontribusi service-nya dalam konteks keseluruhan, muncul rasa tanggung jawab kolektif terhadap pengalaman pengguna akhir.

SLO sebagai Kompas Pengembangan

Praktik lain yang berakar pada ODD adalah merumuskan Service Level Objectives (SLO) sebagai bagian dari proses desain fitur, bukan setelah sistem berjalan. SLO memaksa tim menjawab pertanyaan sulit: seberapa cepat sistem ini perlu merespons agar pengguna tidak kecewa? Berapa persen error yang masih bisa kita toleransi?

Ketika SLO sudah ada, keputusan pengembangan menjadi lebih terarah. Fitur dengan dampak langsung pada SLO mendapat prioritas perhatian observability yang lebih tinggi. Sebaliknya, fitur yang jarang digunakan tapi kompleks tidak perlu diinstrumentasi secara berlebihan. Ini adalah bentuk alokasi perhatian yang cerdas di tengah keterbatasan waktu engineering.

Error Budget dan Percakapan yang Berubah

Salah satu efek samping paling menarik dari ODD adalah perubahan kualitas percakapan antara tim produk dan tim engineering. Ketika ada error budget yang terukur, diskusi tentang rilis fitur menjadi lebih objektif. Tim tidak lagi berdebat soal "apakah ini aman dirilis?" tapi "berapa error budget yang kita miliki, dan apakah fitur ini layak mengonsumsinya?"

Namun ada jebakan di sini yang perlu diwaspadai. Error budget bukan alat untuk menghukum tim ketika insiden terjadi. Jika diperlakukan sebagai senjata, ia akan mendorong perilaku tertutup dan pelaporan yang tidak jujur. Ketika diperlakukan sebagai alat belajar bersama, ia menjadi dasar untuk keputusan investasi yang lebih baik dalam reliability.

Instrumentasi sebagai Bagian Definition of Done

Salah satu perubahan paling praktis dalam adopsi ODD adalah memperbarui definisi "selesai". Sebuah fitur tidak dianggap selesai ketika kodenya lolos test dan di-merge, tapi ketika ia sudah terinstrumentasi dengan benar: memiliki log yang bermakna, metrics yang relevan, dan trace yang terhubung dengan alur sistem secara keseluruhan.

Ini menuntut disiplin yang tidak mudah, terutama ketika tenggat waktu mendesak. Tapi justru di sinilah investasi jangka panjangnya terasa. Setiap fitur yang diluncurkan tanpa observabilitas yang memadai adalah utang teknis yang akan dibayar saat insiden pertama terjadi, dan biasanya dengan bunga yang mahal.

Kesimpulan: Membangun Sistem yang Jujur

Observability-Driven Development bukan sekadar tren tools atau framework baru. Ia adalah perubahan cara berpikir tentang perangkat lunak yang kita bangun. Ia mengakui bahwa sistem yang kompleks akan selalu punya mode kegagalan yang tidak bisa diprediksi sepenuhnya, dan bahwa kesiapan menghadapinya adalah bagian dari kualitas engineering, bukan hal tambahan.

Di era di mana downtime selama lima menit bisa menghabiskan kepercayaan yang dibangun berbulan-bulan, kemampuan untuk memahami sistem secara mendalam bukan lagi kemewahan bagi tim yang mapan. Ia adalah kompetensi dasar. Dan seperti halnya kompetensi lain, ia dibangun bukan di saat krisis, melainkan melalui keputusan-keputusan kecil yang diambil jauh sebelum krisis datang.