Mengaktifkan plugin metrics RoadRunner dengan endpoint Prometheus, mendefinisikan counter, gauge, dan histogram kustom lewat config, merekam nilai dari worker PHP, dan menyusun dashboard untuk latensi request serta kesehatan pool.

Setelah di episode 9 kita membuat log terstruktur, pada episode kali ini kita menambahkan angka ke dalam observability: plugin metrics RoadRunner yang mengekspos metric ke format Prometheus. Log menjawab "apa yang terjadi", metric menjawab "seberapa sering dan seberapa lambat" — dua-duanya dibutuhkan untuk mengoperasikan aplikasi dengan percaya diri.
Mengapa episode ini penting? Karena metric adalah bahasa umum tim ops: dashboard, alerting, dan keputusan scaling semuanya berdasar pada angka. RoadRunner memberi metric otomatis untuk HTTP dan worker, plus ruang untuk metric kustom dari kode bisnis kalian.
metrics:
address: 127.0.0.1:2112
collect:
requests_total:
type: counter
help: "Total request HTTP."
request_duration:
type: histogram
help: "Durasi request HTTP."
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]
worker_memory:
type: gauge
help: "Memory worker aktif (MB)."
pool_workers:
type: gauge
help: "Jumlah worker di pool."Jenis metric yang didukung:
| Tipe | Karakteristik | Contoh pemakaian |
|---|---|---|
counter | Naik monoton | Jumlah request, jumlah job gagal |
gauge | Bisa naik/turun | Worker aktif, memory terpakai |
histogram | Distribusi nilai | Latensi request, ukuran payload |
Setelah server jalan, endpoint Prometheus tersedia:
curl http://127.0.0.1:2112/metricsPrometheus (atau Grafana Alloy/VictoriaMetrics) diarahkan ke alamat ini untuk scraping otomatis.
RoadRunner menyediakan metric request HTTP tanpa kode kustom bila middleware http_metrics aktif:
http:
address: 0.0.0.0:8080
middleware: ["http_metrics", "gzip"]Dengan middleware ini, metric seperti jumlah request per status code dan durasi otomatis terekspos. Gabungkan dengan metric kustom untuk gambar lengkap.
Metric kustom direkam dari PHP dengan package spiral/roadrunner-metrics:
composer require spiral/roadrunner-metricsuse Spiral\RoadRunner\Metrics\Metrics;
$metrics = new Metrics($rpc);
// Counter: increment
$metrics->inc('requests_total');
// Gauge: set nilai
$metrics->set('worker_memory', memory_get_usage(true) / 1024 / 1024);
// Histogram: observe nilai
$metrics->observe('request_duration', $durationSeconds);
// Counter dengan label
$metrics->add('requests_total', 1, ['method' => 'GET']);Sama seperti KV dan jobs, pemanggilan metric diteruskan via RPC ke plugin Go. Worker PHP tidak memegang koneksi Prometheus apa pun.
Note
Metric dengan label (misal per-method, per-status) jauh lebih informatif untuk dashboard, tetapi hati-hati: kombinasi label yang terlalu banyak menghasilkan cardinality tinggi yang membebani Prometheus. Batasi label pada dimensi yang benar-benar kalian filter.
Dengan metric di atas, kalian bisa menyusun dashboard Grafana. Query PromQL yang paling berguna:
# Latensi rata-rata request per menit
rate(request_duration_sum[1m]) / rate(request_duration_count[1m])
# Error rate (status 5xx)
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
# Worker restart (kesehatan pool)
rate(worker_restarts_total[5m])Panel yang disarankan:
| Panel | Query | Apa yang dijawab |
|---|---|---|
| Request rate | rate(http_requests_total[5m]) | Volume traffic |
| Latensi p95/p99 | histogram_quantile(0.99, ...) | Apakah pengguna merasakan lambat? |
| Worker restart | rate(worker_restarts_total[5m]) | Apakah pool tidak stabil? (crash/leak) |
| Memory worker | avg(worker_memory) | Apakah memory mendekati max_worker_memory? |
Gejala umum yang terlihat dari metric:
| Pola | Arti |
|---|---|
| Latensi naik seiring request rate | Pool kurang besar — lihat episode 20 |
worker_restarts_total melonjak | Worker crash/leak — periksa log dan max_worker_memory |
| Memory worker mendekati batas | Naikkan max_worker_memory atau perbaiki leak |
| Counter label aneh | Bug logika — lihat distribusi label |
Dari metric ini, siapkan alert Prometheus sederhana:
groups:
- name: roadrunner
rules:
- alert: HighErrorRate
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m])) > 0.05
for: 5m
labels:
severity: page
annotations:
summary: "Error rate melebihi 5% selama 5 menit"Pada episode 12 ini, kalian telah membuka jendela angka ke aplikasi.
Inti yang harus dibawa pulang:
metrics menyediakan endpoint Prometheus di metrics.address.http_metrics.spiral/roadrunner-metrics.Di episode 13 selanjutnya, kita belajar caching & static assets — menyempurnakan layanan file statis dengan header cache, ETag, dan kompresi, memanfaatkan sendfile, serta strategi long-term caching untuk aset. Sampai jumpa di episode 13!