Observability vs Monitoring #
Dalam pengelolaan sistem komputer skala besar, khususnya pada lingkungan komputasi cloud yang terdistribusi dan dinamis, kita sering kali mendengar istilah Monitoring dan Observability digunakan secara bergantian. Banyak pihak menganggap keduanya adalah hal yang sama dengan nama yang berbeda. Namun, pada kenyataannya, keduanya mewakili dua filosofi dan pendekatan yang sangat bertolak belakang tentang bagaimana kita memahami kesehatan serta perilaku sistem. Monitoring berfokus pada pengawasan metrik yang sudah ditentukan sebelumnya untuk mendeteksi kegagalan yang telah diantisipasi (known unknowns). Sebaliknya, observability memberikan kemampuan bagi kita untuk mengajukan pertanyaan baru yang belum pernah terpikirkan sebelumnya guna memecahkan masalah kompleks yang tidak terduga (unknown unknowns). Memahami perbedaan fundamental ini bukan sekadar perdebatan istilah, melainkan langkah krusial untuk membangun sistem yang tangguh, meminimalkan durasi pemadaman (downtime), dan meningkatkan efisiensi operasional tim insinyur kita.
Konsep Dasar dan Analogi #
Untuk memahami perbedaan antara monitoring dan observability secara intuitif, kita dapat menggunakan beberapa analogi dari kehidupan nyata.
1. Analogi Speedometer Mobil vs. Alat Pemindai Diagnostik (OBD Scanner) #
- Monitoring (Speedometer & Indikator Bahan Bakar): Di dalam dashboard mobil, terdapat indikator kecepatan, suhu mesin, dan sisa bahan bakar. Indikator ini memantau parameter statis yang sudah ditentukan oleh pabrik. Jika suhu mesin melebihi batas aman, lampu indikator merah akan menyala. Ini adalah monitoring. Kita tahu persis apa yang diawasi (suhu mesin) dan batasannya (ambang batas panas). Namun, ketika lampu indikator mesin menyala, dashboard tidak memberi tahu kita mengapa mesin tersebut bermasalah.
- Observability (OBD Scanner & Analisis Sensor Lengkap): Untuk mengetahui penyebab pasti kegagalan mesin, mekanik akan mencolokkan alat OBD Scanner ke komputer mobil. Alat ini membaca ratusan parameter sensor secara real-time — waktu pembakaran, rasio udara dan bahan bakar, tekanan injektor, hingga log riwayat kegagalan silinder. Dengan data yang melimpah dan saling terhubung ini, mekanik dapat menyimpulkan bahwa kegagalan disebabkan oleh penyumbatan pada injektor silinder nomor tiga akibat kualitas bahan bakar yang buruk. Kemampuan menyimpulkan kondisi internal mobil berdasarkan data mentah eksternal inilah yang disebut observability.
2. Sifat Pertanyaan yang Diajukan #
Perbedaan kedua konsep ini tercermin dari jenis pertanyaan yang ingin kita jawab:
- Pertanyaan Monitoring:
- Apakah server database masih hidup?
- Apakah penggunaan CPU melampaui 80%?
- Berapa tingkat error request HTTP saat ini?
- Apakah sertifikat SSL akan kedaluwarsa dalam 30 hari ke depan?
- Pertanyaan Observability:
- Mengapa transaksi checkout pengguna bermasalah setelah kita merilis fitur promosi baru, padahal metrik penggunaan CPU dan memori database terlihat normal?
- Mengapa latensi API meningkat hanya untuk pengguna yang mengakses dari region tertentu dengan perangkat Android tipe lama saat menggunakan metode pembayaran e-wallet?
- Layanan mikro (microservice) mana yang memicu efek domino keterlambatan (cascading delay) pada rantai pemanggilan API saat layanan keranjang belanja (cart-service) mengalami kelambatan?
3. Matriks Perbandingan Karakteristik #
| Faktor Pembanding | Monitoring | Observability |
|---|---|---|
| Fokus Utama | Mengawasi kondisi kesehatan sistem yang sudah diketahui (Known-Knowns & Known-Unknowns). | Menelusuri dan mendiagnosis perilaku sistem yang tidak terduga (Unknown-Unknowns). |
| Sifat Sistem | Pasif dan reaktif (menunggu ambang batas terlampaui baru mengirim alarm). | Aktif dan proaktif (menyediakan data mentah untuk dieksplorasi secara interaktif). |
| Struktur Data | Agregat metrik deret waktu (time-series metrics) yang telah diringkas sebelumnya. | Data telemetri mentah (log terstruktur, jejak terdistribusi, dan metrik terperinci). |
| Pertanyaan Inti | “Apakah sistem sedang bermasalah?” | “Mengapa sistem ini bisa berperilaku aneh?” |
| Metode Kerja | Dasbor statis dengan indikator warna (hijau/kuning/merah) dan alarm threshold. | Kueri interaktif, korelasi silang antar data telemetri, dan analisis grafik jejak. |
Keterbatasan Monitoring Tradisional di Era Cloud-Native #
Pendekatan monitoring tradisional dirancang pada era ketika aplikasi kita berjalan di atas server fisik tunggal atau mesin virtual (Virtual Machine / VM) statis dengan database monolitik. Karakteristik sistem seperti ini sangat mudah diprediksi: kegagalan biasanya disebabkan oleh disk penuh, memori habis, atau layanan web server yang mati.
Namun, di era cloud-native modern, arsitektur aplikasi telah berubah menjadi ratusan kontainer mikro yang tersebar di berbagai cluster Kubernetes, berjalan secara dinamis di atas infrastruktur autoscaling yang terus lahir dan mati. Monitoring tradisional gagal menghadapi realitas baru ini karena beberapa keterbatasan utama:
1. Hilangnya Konteks Akibat Agregasi Data #
Monitoring sangat bergantung pada metrik agregat (seperti rata-rata utilitas CPU per menit). Ketika kita menggabungkan performa ratusan instans kontainer menjadi satu angka rata-rata, kita kehilangan visibilitas terhadap kegagalan lokal. Sebagai contoh, rata-rata latensi API kita mungkin menunjukkan angka normal (200ms), namun di balik itu, 2% pengguna mengalami kegagalan total dengan latensi di atas 10 detik karena satu instans kontainer mengalami kebocoran memori.
2. Sifat Infrastruktur yang Sementara (Ephemeral) #
Di lingkungan cloud, alamat IP dan nama host bersifat sementara. Jika suatu kontainer Kubernetes mengalami crash atau dihentikan akibat proses scale-in, mesin monitoring tradisional yang hanya memantau kesehatan host akan kehilangan seluruh riwayat data terkait kontainer tersebut. Tanpa adanya data telemetri yang diunggah ke penyimpanan terpusat sebelum kontainer tersebut hancur, kita tidak akan pernah bisa menyelidiki penyebab crash kontainer tersebut.
3. Masalah Alarm Palsu (Alert Fatigue) #
Dalam sistem terdistribusi yang kompleks, dependensi antar komponen sangat tinggi. Ketika database utama mengalami penurunan performa secara mendadak, sistem monitoring tradisional akan mengirimkan puluhan alarm sekaligus: alarm penggunaan koneksi database penuh, alarm latensi API Gateway naik, alarm kegagalan transaksi pada layanan pembayaran, dan alarm timeout pada layanan antrean pesan. Insinyur kita akan dibanjiri oleh alarm (alert fatigue) yang menyulitkan mereka untuk menemukan akar masalah yang sebenarnya (root cause).
Spektrum Masalah: Known-Knowns vs Unknown-Unknowns #
Untuk membangun sistem pertahanan yang baik, kita harus memetakan kategori masalah berdasarkan tingkat pengetahuan kita terhadap masalah tersebut:
| Dimensi Pengetahuan / Masalah | Diketahui (Known) | Tidak Diketahui (Unknown) |
|---|---|---|
| Diketahui (Known) | 1. Known-Knowns (Kondisi Terpeta)- Server hidup/mati- Versi aplikasi berjalan–> SOLUSI: Monitoring | 2. Known-Unknowns (Anomali Terantisipasi)- CPU melewati batas 90%- Kapasitas disk menipis–> SOLUSI: Alerting |
| Tidak Diketahui (Unknown) | 3. Unknown-Knowns (Pengetahuan Terpendam)- Tim tahu perilaku aneh sistem, tapi belum ditulis di runbook.–> SOLUSI: Dokumentasi | 4. Unknown-Unknowns (Misteri Tak Terduga)- Bug race condition lintas tiga microservices.–> SOLUSI: Observability |
1. Known-Knowns (Hal yang Kita Ketahui) #
Kondisi dasar yang pasti benar dan mudah diperiksa secara berkala. Contoh: “Kita tahu bahwa layanan pembayaran berjalan di port 8080”. Kita cukup memantau port tersebut untuk memastikan layanan aktif.
2. Known-Unknowns (Hal yang Kita Tahu Bisa Gagal) #
Masalah yang sudah kita antisipasi jenis kegagalannya, namun kita tidak tahu kapan akan terjadi. Contoh: “Kita tahu bahwa penggunaan RAM server bisa penuh dan menyebabkan crash”. Solusinya adalah membuat visualisasi grafik metrik memori dan mengatur alert jika penggunaan RAM menyentuh batas 90%.
3. Unknown-Knowns (Hal yang Kita Ketahui tapi Tidak Kita Sadari) #
Informasi yang dimiliki oleh anggota tim senior secara intuitif tetapi tidak terdokumentasi atau tidak terintegrasi ke dalam sistem alarm otomatis. Contoh: “Kita tahu secara informal bahwa service A selalu melambat setiap hari Senin pukul 09:00 karena ada proses sinkronisasi cron job, namun belum ada runbook resmi untuk penanganannya”.
4. Unknown-Unknowns (Misteri yang Tidak Pernah Kita Bayangkan) #
Masalah kompleks yang timbul akibat interaksi dinamis antara kode aplikasi baru, lonjakan trafik pengguna, dependensi pihak ketiga, dan latensi jaringan cloud. Kita tidak pernah memprediksi masalah ini akan terjadi, sehingga kita tidak mungkin menyiapkan visualisasi dasbor statis atau alarm threshold sebelumnya.
Di sinilah observability memainkan peran vital. Observability berasumsi bahwa kegagalan dalam sistem terdistribusi adalah hal yang pasti terjadi dan wujud kegagalannya tidak bisa diprediksi. Dengan mengumpulkan data telemetri yang kaya dan kontekstual, kita dapat melakukan investigasi seperti detektif untuk merumuskan hipotesis baru saat insiden tak terduga melanda.
Tiga Pilar Observability dan Korelasinya #
Aktivitas observability ditopang oleh tiga pilar data telemetri utama: Metrics, Traces, dan Logs. Ketiganya tidak boleh berdiri sendiri secara terpisah; mereka harus dihubungkan melalui context propagation agar proses investigasi dapat berjalan mulus tanpa hambatan (context-switching).
flowchart TD
subgraph Pengguna ["Pengguna & Trafik"]
User["Pengguna (Mendapat Error 500)"]
end
subgraph Gerbang ["API Gateway & Routing"]
Gateway["API Gateway (Context Injection)"]
end
subgraph Layanan ["Microservices Layer"]
OrderService["Order Service (Context Propagation)"]
PaymentService["Payment Service (Error Occurs)"]
end
subgraph Telemetri ["Siklus Diagnosa Observability"]
direction LR
Metrics["1. METRICS (Deteksi)
- http_requests_total (5xx)
- http_request_duration_seconds"]
Traces["2. TRACES (Isolasi)
- trace_id: 8a9b1c...
- Span: payment-service (Failed)"]
Logs["3. LOGS (Identifikasi)
- Detail query timeout
- Stack trace error database"]
end
User -->|"1. Request checkout"| Gateway
Gateway -->|"2. Meneruskan request"| OrderService
OrderService -->|"3. Panggil API pembayaran"| PaymentService
PaymentService -->|"4. Koneksi terputus/gagal"| DB[("Database Engine")]
PaymentService -. "Kirim metrik error" .-> Metrics
PaymentService -. "Kirim span kegagalan" .-> Traces
PaymentService -. "Tulis JSON log error" .-> Logs
Metrics -. "Memicu Alert" .-> Alerting["Alert Manager (PagerDuty/Slack)"]
Alerting -. "Insinyur SRE menganalisis" .-> Traces
Traces -. "Korelasi via trace_id" .-> Logs
1. Siklus Korelasi Tiga Pilar saat Terjadi Insiden #
Ketika seorang pelanggan mengeluhkan kegagalan transaksi di aplikasi web kita, alur kerja pemecahan masalah yang efisien menggunakan tiga pilar observability adalah sebagai berikut:
- METRICS (Mendeteksi): Alarm di Slack berbunyi karena metrik tingkat kegagalan (error rate) pada API Gateway melonjak melewati batas toleransi SLO. Metrik memberi tahu kita KAPAN insiden terjadi dan SEBERAPA BESAR dampaknya terhadap pengguna.
- TRACES (Mengisolasi): Kita membuka visualisasi distributed tracing untuk periode waktu insiden tersebut. Kita mencari transaksi transaksi yang gagal (ditandai dengan warna merah). Dari diagram trace sekuensial, kita melihat bahwa request berjalan lancar melewati
api-gatewaydanorder-service, tetapi mengalami kegagalan 500 atau timeout panjang di dalampayment-service. Trace membantu kita melacak DI MANA letak kemacetan atau kegagalan dalam rantai dependensi. - LOGS (Mengidentifikasi): Melalui trace editor, kita mengklik ID jejak (trace_id) dari span layanan
payment-serviceyang gagal. Sistem otomatis menampilkan seluruh baris log aplikasi terstruktur yang memilikitrace_idyang sama. Di sana, kita menemukan baris log tingkat ERROR:{"trace_id": "8a9b1c...", "message": "Failed to decrypt response from external payment gateway: Key mismatch", "stack_trace": "..."}. Log memberikan rincian mendalam tentang MENGAPA kesalahan tersebut terjadi.
Peran Penting High Cardinality dan High Dimensionality #
Kekuatan utama dari platform observability modern adalah kemampuannya dalam mengolah data dengan karakteristik High Cardinality dan High Dimensionality.
1. Apa itu Cardinality? #
Dalam istilah database dan analisis data, cardinality merujuk pada jumlah nilai unik yang dimiliki oleh sebuah kolom data atau dimensi.
- Low Cardinality (Kardinalitas Rendah): Dimensi yang hanya memiliki sedikit variasi nilai unik. Contoh:
status_code(200, 400, 500),environment(production, staging, development), atauhttp_method(GET, POST, DELETE). - High Cardinality (Kardinalitas Tinggi): Dimensi yang memiliki ribuan hingga jutaan variasi nilai unik. Contoh:
user_id,transaction_id,ip_address,container_id, atauemail_address.
2. Bahaya Cardinality Explosion pada Metrics Tradisional #
Sistem metrik tradisional (seperti Prometheus) menyimpan data dalam bentuk deret waktu agregat. Setiap kombinasi unik dari label atau dimensi akan menghasilkan satu deret waktu (time-series) baru di database metrik.
Sebagai contoh, jika kita ingin memantau latensi API kita dengan menambahkan dimensi:
http_method(5 nilai)status_code(5 nilai)user_id(1.000.000 nilai unik pengguna aktif)
Maka total deret waktu yang harus disimpan dan diproses oleh database metrik adalah: $$5 \times 5 \times 1.000.000 = 25.000.000 \text{ deret waktu}$$
Jumlah deret waktu yang meledak mendadak ini disebut Cardinality Explosion. Hal ini akan menghabiskan memori RAM database metrik kita, menyebabkan crash pada sistem monitoring, dan memicu lonjakan tagihan cloud yang fantastis. Akibatnya, pada monitoring tradisional, kita dilarang keras merekam data kardinalitas tinggi seperti user_id ke dalam metrik.
3. Solusi Observability Modern #
Sistem observability modern dirancang untuk tidak melakukan agregasi data di depan (pre-aggregation). Mereka menyimpan data telemetri sebagai Event Mentah Terstruktur.
Ketika aplikasi menulis log atau trace yang berisi data user_id dan transaction_id, data tersebut langsung dikirim ke sistem penyimpanan kolumnar (columnar storage) atau database indeksasi cepat. Ketika terjadi insiden, insinyur kita dapat menjalankan kueri korelasi secara on-demand: “Tampilkan semua transaksi gagal yang dialami oleh pengguna dengan ID 999818 selama 10 menit terakhir”. Kita mendapatkan kemampuan penelusuran tingkat mikro tanpa merusak stabilitas database pemantauan.
Implementasi Praktis: Instrumentasi dengan OpenTelemetry #
Untuk mewujudkan observability, kode aplikasi kita harus diinstrumentasi guna memproduksi data telemetri. Saat ini, standar industri terbuka yang paling direkomendasikan adalah OpenTelemetry (OTel), sebuah proyek sandbox di bawah CNCF yang didukung oleh seluruh vendor cloud dan monitoring besar di dunia. Dengan OTel, kode kita tetap agnostik terhadap vendor; kita dapat mengganti backend analisis (misal dari Grafana Loki ke Datadog atau AWS X-Ray) tanpa mengubah satu baris pun kode instrumentasi aplikasi kita.
Berikut adalah contoh implementasi praktis penggunaan OpenTelemetry di bahasa pemrograman Go untuk mendemonstrasikan proses inisialisasi span distributed tracing dan injeksi konteks saat melakukan panggilan HTTP ke service lain.
package main
import (
"context"
"fmt"
"net/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
)
// Inisialisasi global tracer
var tracer = otel.Tracer("order-service")
// ANTI-PATTERN: Melakukan panggilan HTTP keluar tanpa context propagation
// Insinyur tidak akan bisa menghubungkan rantai trace antara layanan ini dengan layanan penerima.
func callPaymentServiceBad(r *http.Request) {
req, _ := http.NewRequest("POST", "http://payment-service/pay", nil)
// JANGAN: Melakukan pemanggilan langsung tanpa menyisipkan header traceparent
client := &http.Client{}
client.Do(req)
}
// BENAR: Menggunakan OpenTelemetry untuk context propagation secara eksplisit
func callPaymentServiceGood(ctx context.Context, orderID string) error {
// 1. Buat child span baru dari context yang ada
ctx, span := tracer.Start(ctx, "CallPaymentService", trace.WithSpanKind(trace.SpanKindClient))
defer span.End()
// Set atribut tambahan untuk membantu investigasi (High Cardinality data)
span.SetAttributes(
trace.StringAttribute("order.id", orderID),
trace.StringAttribute("payment.provider", "stripe"),
)
req, err := http.NewRequestWithContext(ctx, "POST", "http://payment-service/pay", nil)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, "Gagal membuat HTTP request")
return err
}
// 2. Injeksikan context tracing (traceparent header) ke dalam header HTTP request
// Ini memastikan trace_id yang sama diteruskan dan digunakan oleh payment-service
otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
// 3. Eksekusi request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
// Catat error ke dalam span telemetri
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
statusErr := fmt.Errorf("layanan pembayaran mengembalikan status: %d", resp.StatusCode)
span.RecordError(statusErr)
span.SetStatus(codes.Error, statusErr.Error())
return statusErr
}
span.SetStatus(codes.Ok, "Transaksi pembayaran berhasil")
return nil
}
func main() {
// Pastikan kita telah mengonfigurasi trace provider dan propagator global di sini
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
propagation.TraceContext{}, // Format standar W3C Trace Context
propagation.Baggage{},
))
}
Membangun Kultur Observability dalam Tim SRE #
Mengadopsi observability bukan sekadar membeli perangkat lunak termahal atau menginstal agen kolektor telemetri di seluruh server. Observability adalah sebuah kultur dan cara kerja tim dalam merancang, membangun, dan memelihara sistem perangkat lunak mereka.
1. Kebiasaan Instrumentasi Sejak Dini (Observability-Driven Development) #
Insinyur perangkat lunak sering kali baru menambahkan log atau metrik setelah terjadi masalah besar di lingkungan produksi. Dalam kultur yang sehat, instrumentasi dianggap sebagai bagian penting dari penulisan kode baru, setara dengan penulisan unit testing.
- Sebelum meluncurkan fitur baru, tim wajib bertanya: “Metrik bisnis apa yang akan membuktikan fitur ini berfungsi?”, “Bagaimana kita bisa melacak latensi penulisan data baru ini di sistem distributed tracing?”, dan “Apakah log kita memiliki trace_id yang valid?”.
2. Evaluasi SLO Berbasis Error Budget #
Kultur observability mendorong tim untuk menyepakati Service Level Objective (SLO) yang realistis berdasarkan pengalaman pengguna nyata, bukan target performa 100% yang mustahil. Kita menggunakan konsep Error Budget sebagai alat ukur toleransi kegagalan. Jika error budget masih melimpah, tim developer memiliki kebebasan untuk merilis fitur baru dengan cepat. Namun, jika error budget menipis akibat insiden berturut-turut, fokus tim harus dialihkan untuk memperbaiki stabilitas sistem menggunakan wawasan dari data observability.
3. Tinjauan Pasca-Insiden Tanpa Menyalahkan (Blameless Post-Mortem) #
Saat terjadi pemadaman sistem (outage), tujuan utama kita bukanlah mencari siapa insinyur yang melakukan kesalahan git commit, melainkan mencari tahu mengapa sistem kita mengizinkan kesalahan tersebut berdampak luas kepada pengguna. Kita menggunakan data tracing dan log secara kronologis untuk menganalisis kelemahan desain arsitektur. Hasil dari post-mortem wajib melahirkan rencana perbaikan sistem konkret, termasuk penambahan instrumentasi baru pada area sistem yang sebelumnya gelap dari pantauan (telemetry gap).
Perbandingan Komprehensif: Kapan Menggunakan Apa #
Kita tidak perlu membuang sistem monitoring lama kita ketika mengadopsi observability. Keduanya saling melengkapi dan memiliki peran masing-masing dalam siklus hidup operasional sistem.
- Gunakan Monitoring Untuk:
- Dashboard Stasiun Pemantauan (NOC): Menampilkan status kesehatan server, ketersediaan jaringan secara global, dan kepatuhan SLA eksternal.
- Alarm Kapasitas Sumber Daya: Mengirim pemberitahuan ketika kapasitas disk database tersisa 15% atau ketika lisensi SSL akan kedaluwarsa.
- Pemantauan Biaya Kasar: Mengawasi konsumsi tagihan bulanan cloud terhadap anggaran proyek.
- Gunakan Observability Untuk:
- Debugging Insiden Kompleks: Menelusuri masalah interaksi mikro yang tidak menentu pada sistem microservices.
- Analisis Dampak Fitur Baru: Mengukur apakah perubahan arsitektur atau perilisan kode baru menyebabkan penurunan performa secara halus (silent performance degradation).
- Optimasi Arsitektur & Latensi: Menggunakan analisis pohon jejak (trace flamegraph) untuk mengidentifikasi komponen yang menghambat kinerja transaksi secara keseluruhan.
Ringkasan #
- Monitoring berfokus pada kondisi kegagalan yang sudah diantisipasi (known unknowns), sedangkan observability berfokus pada pemecahan masalah baru yang belum pernah terjadi (unknown unknowns).
- Pendekatan monitoring tradisional gagal di era cloud-native karena adanya agregasi data yang menghilangkan konteks, serta sifat kontainer yang sementara (ephemeral).
- Tiga pilar observability wajib saling terhubung — Metrik untuk mendeteksi anomali, Tracing untuk mengisolasi lokasi kegagalan layanan, dan Logs untuk mengidentifikasi akar penyebab secara rinci.
- Karakteristik High Cardinality adalah kunci utama observability — Memungkinkan kita melakukan filter data kueri berdasarkan atribut unik seperti
user_idtanpa mengalami kegagalan sistem pemantauan.- Gunakan OpenTelemetry sebagai standar instrumentasi terbuka guna menghindari keterikatan (vendor lock-in) pada penyedia platform pemantauan tertentu.
- Kultur observability melibatkan seluruh siklus pengembangan — Mulai dari penulisan kode instrumentasi sejak awal, evaluasi performa berbasis SLO, hingga sesi tinjauan insiden yang konstruktif (blameless post-mortem).