Operator Agregasi
sum(...) # jumlahkan
avg(...) # rata-rata
min(...) / max(...)
count(...) # berapa banyak series
stddev(...) / stdvar(...)
topk(5, ...) # 5 nilai tertinggi
bottomk(5, ...) # 5 nilai terendah
quantile(0.95, ...) # persentil ANTAR-SERIES (bukan antar-waktu!)
count_values("versi", app_build_info) # hitung berapa series per nilaiby vs without
# PERTAHANKAN hanya label yang disebut
sum by (job, instance) (rate(http_requests_total[5m]))
# BUANG label yang disebut, pertahankan sisanya
sum without (instance, pod) (rate(http_requests_total[5m]))
# Tanpa keduanya: semua label hilang, hasilnya satu angka
sum(rate(http_requests_total[5m]))withoutGunakan without bila Anda ingin membuang satu-dua label tapi mempertahankan sisanya yang mungkin belum Anda ketahui. Contoh: menggabungkan semua pod dalam satu deployment sambil tetap mempertahankan label namespace, service, route, dan label lain yang mungkin ditambahkan tim lain nanti.
Dengan by, label baru akan hilang diam-diam; dengan without, label baru otomatis terbawa.
Operator Aritmatika & Pencocokan Label
Saat dua vektor dioperasikan, Prometheus mencocokkan series berdasarkan seluruh label yang sama persis. Bila tidak ada yang cocok, hasilnya kosong โ dan ini sumber frustrasi yang sangat umum.
# Cocok karena label kedua sisi identik
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes
# TIDAK cocok โ label berbeda -> hasil kosong
sum by (job) (rate(a_total[5m])) / sum by (instance) (rate(b_total[5m]))
# Solusi: samakan label yang dipakai untuk agregasi
sum by (job) (rate(a_total[5m])) / sum by (job) (rate(b_total[5m]))
# Atau batasi label yang dicocokkan
rate(a_total[5m]) / on (instance) rate(b_total[5m])
rate(a_total[5m]) / ignoring (status) rate(b_total[5m])Operator Perbandingan & Logika
# Menyaring: hanya series yang memenuhi kondisi yang dikembalikan
node_load1 > 4
# bool: mengubah hasil menjadi 0 atau 1, semua series dipertahankan
node_load1 > bool 4
# Operator himpunan
up == 1 and on (instance) node_load1 > 4 # keduanya benar
up == 0 or absent(up) # salah satu benar
rate(a[5m]) unless on (instance) rate(b[5m]) # a yang TIDAK punya pasangan b> menyaring, > bool menandainode_load1 > 4 hanya mengembalikan instance dengan load di atas 4 โ instance yang sehat hilang dari hasil. Untuk grafik "berapa persen instance yang bermasalah", Anda butuh semua series tetap ada:
avg(node_load1 > bool 4) # proporsi instance dengan load > 4Merangkai SLI (Service Level Indicator)
SLI adalah rasio "kejadian baik" dibagi "total kejadian". Inilah cara SRE mengukur kualitas layanan.
# SLI Ketersediaan: proporsi request yang tidak error
sum(rate(http_requests_total{status!~"5.."}[30d]))
/ sum(rate(http_requests_total[30d]))
# SLI Latency: proporsi request yang lebih cepat dari 300 ms
sum(rate(http_request_duration_seconds_bucket{le="0.3"}[30d]))
/ sum(rate(http_request_duration_seconds_count[30d]))
# Error budget tersisa (SLO 99,9%)
# 1 - (error yang sudah terjadi / error yang diizinkan)
1 - (
sum(increase(http_requests_total{status=~"5.."}[30d]))
/ (0.001 * sum(increase(http_requests_total[30d])))
)SLO 99,9% berarti Anda "boleh" gagal 0,1% dari total request. Itulah error budget Anda.
- Budget masih banyak โ tim boleh rilis fitur baru dengan agresif.
- Budget hampir habis โ bekukan rilis, fokus ke stabilitas.
Ini mengubah perdebatan "kapan boleh rilis?" dari adu argumen menjadi keputusan berbasis angka.
topk untuk Investigasi
# 10 endpoint paling lambat
topk(10, histogram_quantile(0.95,
sum by (le, route) (rate(http_request_duration_seconds_bucket[5m]))))
# 10 container paling boros memori
topk(10, container_memory_working_set_bytes{name!=""})
# 10 metrik dengan time series terbanyak (untuk berburu kardinalitas)
topk(10, count by (__name__)({__name__=~".+"}))
# 5 instance dengan error rate tertinggi
topk(5, sum by (instance) (rate(http_requests_total{status=~"5.."}[5m])))