Membahas instrumen metrics OpenTelemetry: Counter, UpDownCounter, Gauge, dan Histogram beserta varian asinkron (observable), lalu memahami View dan aggregation, perbedaan delta vs cumulative, dan cara mengekspor metrics ke backend Prometheus

Setelah episode 4 membedah traces, kali ini giliran metrics — sinyal yang paling sering dipakai untuk alerting dan SLO. Traces menjawab "kenapa lambat?", metrics menjawab "berapa?" dan "kapan?" — dan tanpa metrics yang baik, alerting kalian menembak dalam gelap.
Episode ini membahas dua lapis: instrument (cara mengukur di kode) dan export (cara backend menerima angka). Kesalahan umum di lapisan ini menghasilkan dashboard dengan data yang menyesatkan — misalnya counter yang di-reset saat restart aplikasi dan membuat grafik turun drastis.
OTel mendefinisikan instrumen berdasarkan pola perubahan nilai dan cara pengukuran (sinkron vs asinkron).
Dipanggil langsung di kode saat peristiwa terjadi.
from opentelemetry import metrics
meter = metrics.get_meter("payment.service")
requests = meter.create_counter("http.server.request.count",
description="Jumlah request masuk")
def on_request():
requests.add(1, {"http.response.status_code": "200"})connections = meter.create_up_down_counter("db.connections.active")
connections.add(1) # koneksi dibuka
connections.add(-1) # koneksi ditutuplatency = meter.create_histogram("http.server.request.duration",
unit="s", description="Durasi request HTTP")
def on_request(duration_s: float):
latency.record(duration_s, {"http.route": "/checkout"})Diukur SDK secara berkala dengan memanggil callback — cocok untuk nilai yang tidak punya event alami, seperti penggunaan memori atau jumlah goroutine. Variasinya: ObservableCounter, ObservableUpDownCounter, ObservableGauge.
create_observable_gauge) — nilai snapshot yang bisa naik/turun, diukur saat callback dipanggil.def read_memory():
usage = psutil.virtual_memory()
return metrics.Observation(usage.percent, {"mem.unit": "percent"})
meter.create_observable_gauge(
"process.memory.usage", callbacks=[read_memory]
)| Instrument | Naik/Turun | Sinkron/Async | Contoh |
|---|---|---|---|
| Counter | Naik saja | Sinkron | jumlah request |
| UpDownCounter | Naik & turun | Sinkron | koneksi aktif |
| Histogram | Distribusi | Sinkron | latensi, ukuran |
| ObservableCounter | Naik saja | Async | total sejak boot (dibaca via /proc) |
| ObservableGauge | Naik & turun | Async | suhu CPU, memori |
View adalah konfigurasi SDK yang mengubah bagaimana instrumen di-agregasi dan diekspor — tanpa menyentuh kode aplikasi. Gunakan View untuk:
from opentelemetry.sdk.metrics import View
from opentelemetry.sdk.metrics.export import ExplicitBucketHistogramAggregation
view = View(
instrument_name="http.server.request.duration",
aggregation=ExplicitBucketHistogramAggregation(
boundaries=[0.005, 0.01, 0.05, 0.1, 0.25, 0.5, 1.0]
),
)Ada dua cara backend menerima metrics:
Pilihannya ditentukan SDK/backend dan di-negotiasi lewat OTLP. Kesalahan umum: mencampur keduanya di dashboard dan melihat counter turun — itu biasanya bukan bug, melainkan reset cumulative saat proses restart, atau pergantian mode delta-cumulative yang tidak disadari.
Tip
Saat membuat alerting untuk counter seperti http.server.request.count, gunakan rate (misal rate(metric[5m]) di PromQL), bukan nilai mentah. Nilai cumulative yang monoton tidak berguna untuk mendeteksi lonjakan — yang penting adalah kecepatan kenaikannya.
Backend metrics paling umum adalah Prometheus. Dua jalur yang dipakai OTel:
Tambahkan jalur ekspor ke pipeline collector episode 0:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
exporters:
debug:
verbosity: basic
prometheus:
endpoint: 0.0.0.0:8889
namespace: otel
service:
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [debug, prometheus]Jalankan ulang collector, kirim metrics dari SDK Python, lalu scrape localhost:8889/metrics — kalian akan melihat metric dengan nama otel_http_server_request_count beserta attribute-nya.
user_id pada metric akan meledakkan jumlah series; gunakan attribute ber-cardinality rendah.s) sesuai semantic conventions, bukan milidetik, agar backend konsisten.Pada episode 5 ini, kalian telah menguasai instrumen metrics dan cara ekspornya.
Inti yang harus dibawa pulang:
Di episode 6 selanjutnya, kita akan membahas logs: konsep & korelasi dengan traces — Logs API yang masih bertahap, structured logs standar, dan bagaimana trace_id/span_id otomatis disuntikkan ke log record agar log bisa langsung dikaitkan ke trace. Sampai jumpa di episode 6!