Kenapa Harus Mengambil Sampel
Layanan dengan 10.000 permintaan per detik dan rata-rata 20 span per permintaan menghasilkan 200.000 span per detik. Menyimpan semuanya berarti puluhan terabita per hari dan biaya yang sering melampaui biaya menjalankan layanan itu sendiri.
Sampling Kepala
Keputusan diambil di awal, saat trace dimulai, sebelum apa pun diketahui tentang hasilnya.
export OTEL_TRACES_SAMPLER=parentbased_traceidratio export OTEL_TRACES_SAMPLER_ARG=0.1 # 10 persen
Kelebihan murah, sederhana, beban aplikasi kecil
keputusan seragam di seluruh layanan lewat trace_id
Kekurangan galat dan permintaan lambat ikut terbuang secara acak
Sampler ini menghormati keputusan yang sudah dibuat layanan sebelumnya melalui flag pada header traceparent. Tanpa itu, setiap layanan memutuskan sendiri — layanan A menyimpan, layanan B membuang — dan hasilnya trace bolong-bolong yang justru menyesatkan saat dibaca.
Sampling Ekor
Collector menahan seluruh span sebuah trace, menunggu trace selesai, lalu memutuskan berdasarkan apa yang sungguh terjadi.
processors:
tail_sampling:
decision_wait: 10s
num_traces: 100000
policies:
- name: semua-galat
type: status_code
status_code: { status_codes: [ERROR] }
- name: yang-lambat
type: latency
latency: { threshold_ms: 1000 }
- name: endpoint-penting
type: string_attribute
string_attribute:
key: url.path
values: ["/pembayaran", "/checkout"]
- name: sisanya-sedikit
type: probabilistic
probabilistic: { sampling_percentage: 5 }
Hasilnya jauh lebih berguna: seluruh galat tersimpan, seluruh permintaan lambat tersimpan, dan lalu lintas normal cukup diwakili lima persen sebagai pembanding.
Collector menunggu selama decision_wait sejak span pertama, lalu memutuskan. Span yang datang setelah tenggat itu dibuang. Bila ada permintaan yang berjalan 30 detik sementara decision_wait disetel 10 detik, trace-nya tersimpan setengah — dan tepat bagian akhir yang hilang, yaitu bagian yang biasanya paling ingin dilihat. Setel di atas latensi maksimum yang wajar.
Seluruh span harus ditahan sampai keputusan diambil. Perkiraan kasarnya: laju span × decision_wait × ukuran rata-rata span. Pada 200.000 span per detik dengan jendela 10 detik dan span 500 byte, dibutuhkan sekitar 1 GB memori hanya untuk penampungan. Batasi dengan num_traces dan pantau metrik memori Collector.
Menggabungkan Keduanya
Aplikasi sampling kepala 30 persen → tekan volume jaringan Collector sampling ekor pada sisanya → simpan galat & yang lambat Hasil biaya terkendali, trace penting tetap utuh
Perlu diingat bahwa galat yang sudah terbuang oleh sampling kepala tidak dapat dipulihkan oleh sampling ekor. Bila seluruh galat wajib tersimpan, sampling kepala harus 100 persen dan seleksi sepenuhnya diserahkan ke ekor.
Dampak pada Metrik
Bila hanya 10 persen trace disimpan lalu jumlah galat dihitung dari sana, angkanya sepuluh kali lebih kecil dari kenyataan — dan tidak ada indikasi apa pun bahwa angka itu salah. Metrik harus dihasilkan dari seluruh permintaan, sebelum sampling. Prosesor spanmetrics di Collector melakukan tepat itu: menghitung metrik dari semua span yang masuk, baru sampling diterapkan sesudahnya.
connectors:
spanmetrics:
histogram:
explicit:
buckets: [10ms, 50ms, 100ms, 500ms, 1s, 5s]
service:
pipelines:
traces:
exporters: [spanmetrics, otlp/tempo]
metrics/dari-span:
receivers: [spanmetrics]
exporters: [prometheus]
Titik Awal yang Masuk Akal
Lalu lintas rendah simpan semua, jangan repot menyetel sampling Menengah sampling ekor: galat 100%, lambat 100%, normal 10% Tinggi kepala 20% + ekor pada sisanya Sangat tinggi kepala 1–5% + ekor, spanmetrics untuk angka sebenarnya