Kodeloka
  1. Kodeloka
  2. Kelas OpenTelemetry
  3. Materi

4 · Produksi · Modul 8 dari 8

Menyelidiki Masalah dengan Telemetri

Mengubah data telemetri menjadi jawaban — alur kerja yang berulang, dari gejala sampai akar masalah.

Alur Penyelidikan

1. Metrik    apa yang berubah, dan kapan persisnya?
2. Metrik    layanan mana yang terdampak?
3. Trace     ambil contoh permintaan yang lambat atau gagal
4. Trace     span mana yang memakan waktu atau menghasilkan galat?
5. Log       apa yang terjadi di dalam span itu — pakai trace_id
6. Perubahan penerapan, flag, atau konfigurasi apa yang bertepatan?

Metode RED untuk Setiap Layanan

Rate      laju permintaan per detik
Errors    proporsi permintaan yang gagal
Duration  sebaran latensi — p50, p95, p99
# Laju permintaan
sum(rate(http_server_request_duration_count[5m])) by (service_name)

# Proporsi galat
sum(rate(http_server_request_duration_count{status_code=~"5.."}[5m])) by (service_name)
  / sum(rate(http_server_request_duration_count[5m])) by (service_name)

# p99
histogram_quantile(0.99,
  sum(rate(http_server_request_duration_bucket[5m])) by (le, service_name))
💡 Rata-rata menyembunyikan persis masalah yang dicari

Bila 99 permintaan selesai dalam 10 ms dan satu permintaan memakan 5 detik, rata-ratanya 60 ms — terlihat sehat. Padahal ada pengguna yang menunggu lima detik. Persentil menunjukkan pengalaman terburuk yang nyata dialami sebagian pengguna, dan itulah yang biasanya menjadi keluhan.

Pola yang Sering Terlihat pada Trace

N+1 kueri
GET /pesanan                    [====================] 890ms
  ├─ SELECT pesanan              [=]                    12ms
  ├─ SELECT item WHERE id=1       [=]                    9ms
  ├─ SELECT item WHERE id=2        [=]                    8ms
  └─ ... 98 span serupa lagi
→ satu kueri per baris; gabungkan atau muat sekaligus
Rantai berurutan yang bisa diparalelkan
GET /dasbor                     [====================] 640ms
  ├─ layanan-pengguna            [=====]               150ms
  ├─ layanan-pesanan                  [======]         180ms
  ├─ layanan-stok                          [=====]     160ms
  └─ layanan-notifikasi                         [====] 140ms
→ tidak saling bergantung; jalankan bersamaan, total menjadi ~180ms
Celah tanpa span
POST /bayar                     [====================] 2100ms
  ├─ validasi                    [==]                   90ms
  │                                  ← celah 1400ms tanpa span
  └─ simpan                                        [==] 110ms
→ ada pekerjaan yang tidak terinstrumentasi, atau menunggu kunci,
  atau menunggu koneksi dari pool yang habis
⚠️ Celah besar di dalam trace adalah petunjuk, bukan kekosongan

Waktu itu tetap terpakai — hanya tidak terlihat karena tidak ada span yang mewakilinya. Tersangka yang paling sering: menunggu koneksi dari pool basis data yang habis, penguncian, jeda garbage collection, atau panggilan ke pustaka yang belum terinstrumentasi. Tambahkan span manual di sekitar area itu untuk mempersempit.

Mencari Kesamaan pada Permintaan Bermasalah

Bandingkan atribut antara permintaan lambat dan permintaan normal:

  penyewa.id      apakah terpusat pada satu pelanggan?
  wilayah         apakah hanya satu wilayah?
  service.version apakah hanya versi baru?
  k8s.node.name   apakah hanya satu node?
  hasil.cache     apakah selalu miss?
💡 Atribut bisnis membuat penyelidikan jauh lebih cepat

Menemukan bahwa seluruh permintaan lambat berasal dari satu penyewa langsung mempersempit ruang pencarian dari "seluruh sistem" menjadi "apa yang berbeda pada penyewa itu" — biasanya volume data yang jauh lebih besar. Tanpa atribut semacam penyewa.id pada span, pola ini tidak akan pernah terlihat.

Menghubungkan Perubahan Penerapan

span.setAttribute("service.version", process.env.VERSI_APLIKASI);
span.setAttribute("deployment.id",   process.env.ID_PENERAPAN);
histogram_quantile(0.99,
  sum(rate(http_server_request_duration_bucket[5m])) by (le, service_version))

Memecah latensi berdasarkan versi menjawab pertanyaan pertama dalam hampir setiap insiden: apakah ini disebabkan penerapan terakhir? Grafik dengan dua garis versi berdampingan menjawabnya dalam hitungan detik.

Menemukan Layanan Sumber Masalah

⚠️ Layanan yang paling banyak memunculkan galat sering hanya korban

Ketika basis data melambat, seluruh layanan yang bergantung padanya ikut menampilkan galat dan latensi tinggi. Dasbor menunjukkan sepuluh layanan bermasalah sekaligus, dan tim mudah tersesat memperbaiki gejala di layanan yang paling berisik. Telusuri trace ke span terdalam yang bermasalah — di sanalah asal kegagalannya, dan biasanya hanya satu tempat.

Daftar Periksa Kesiapan Produksi

□ service.name dan service.version disetel di seluruh layanan
□ deployment.environment membedakan produksi dari staging
□ trace_id tercatat pada setiap log terstruktur
□ Metrik dihasilkan sebelum sampling — spanmetrics atau instrumen sendiri
□ Nama span memakai pola rute, bukan URL dengan ID
□ Atribut sensitif disunting di Collector
□ Collector sendiri dipantau oleh sistem yang terpisah darinya
□ Peringatan berbasis SLO, bukan ambang batas mentah
□ Retensi ditetapkan sesuai anggaran dan kebutuhan penyelidikan
🚫 Observabilitas yang tidak pernah dipakai saat tenang tidak akan menolong saat panik

Dasbor yang baru dibuka pertama kali ketika insiden berlangsung hampir selalu mengecewakan: kueri salah, label tidak sesuai, data yang dibutuhkan ternyata tidak pernah dikumpulkan. Biasakan membuka trace dan dasbor saat sistem sehat — untuk meninjau penerapan baru atau memeriksa endpoint lambat — sehingga celah dalam instrumentasi ditemukan sebelum benar-benar dibutuhkan.