spiral/roadrunner-metrics
RoadRunner metrics integration for PHP apps. Exposes and exports runtime and application metrics from the RoadRunner server, enabling observability with common monitoring backends. Lightweight package for collecting counters, gauges, and histograms in production.
Install the package via Composer:
composer require spiral/roadrunner-metrics
Enable the metrics service in your RoadRunner config (e.g., .rr.yaml):
metrics:
enabled: true
address: "localhost:2112" # Default exposition endpoint
Initialize the metrics collector in your worker (e.g., HTTP worker, CLI worker):
use Spiral\RoadRunner\Metrics\Metrics;
$metrics = new Metrics();
First use case: Monitor request latency for an HTTP endpoint:
$histogram = $metrics->createHistogram('http_request_duration_seconds', 'Duration of HTTP requests');
$timer = $histogram->startTimer();
// ... handle request ...
$timer->stop();
Access metrics at http://localhost:2112/metrics (if metrics server is enabled) or push to your preferred backend (e.g., Prometheus).
Worker-level instrumentation: Use a service provider or middleware to register metrics once per worker lifecycle (since RoadRunner reuses workers):
// In a middleware or worker bootstrap file
$counter = $metrics->createCounter('http_requests_total', 'Total HTTP requests');
$histogram = $metrics->createHistogram('http_request_duration_seconds', 'Request latency');
$gauge = $metrics->createGauge('active_workers', 'Number of active workers');
Structured labeling: Attach labels (tags) for dimensional reporting:
$counter->add(1, ['method' => 'GET', 'route' => '/api/users']);
Gauge updates for dynamic values (e.g., queue depth, memory usage):
$gauge->set(count($queue));
// or increment/decrement
$gauge->increment();
Histograms with automatic buckets for timing operations:
$timer = $histogram->startTimer(['service' => 'db']);
$result = $db->query($sql);
$timer->stop();
Batch exporting: To integrate with external metrics systems, use Metrics::collect() and push to your backend (e.g., StatsD, Prometheus Pushgateway).
🛑 Avoid creating metrics per request—register once per worker lifecycle. Creating the same metric multiple times throws an InvalidArgumentException.
⏱️ Timer cleanup: Always call stop() on histogram timers (even on exceptions), or use finally blocks. Leaking timers won’t report but can cause memory bloat in long-lived workers.
📏 Bucket defaults: Histograms use sensible default buckets (0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0)—override via optional config if needed (though API currently doesn’t expose bucket customization—see GitHub issues for updates).
🔍 Label consistency is critical: Mismatched label names or values across create* vs add/observe calls result in new metric series, potentially exploding cardinality.
🐞 Debugging tip: Enable RoadRunner logs with --debug flag to see metric registration failures or exposition errors.
📁 File descriptor limits: In high-load setups, ensure your OS allows enough open FDs—the metrics server (address) binds to a socket.
🔄 RoadRunner version compatibility: This package targets RR v2.0+; ensure your spiral/roadrunner version aligns (e.g., RR v2023.2+).
🔌 Extensibility: For non-standard backends, implement Spiral\RoadRunner\Metrics\ExporterInterface and wire it via DI or factory to forward raw metric data.
How can I help you explore Laravel packages today?