dbstudios/prometheus-client-bundle
Installation
composer require dbstudios/prometheus-client-bundle
For Symfony Flex projects, the bundle auto-enables. Otherwise, add to config/bundles.php:
DaybreakStudios\PrometheusClientBundle\DaybreakStudiosPrometheusClientBundle::class => ['all' => true],
Basic Configuration
Place this in config/packages/dbstudios_prometheus.yaml (Symfony 4+) or app/config/config.yml (Symfony 3.4-):
dbstudios_prometheus:
adapter: DaybreakStudios\PrometheusClient\Adapter\ApcuAdapter
Note: The ApcuAdapter is memory-based and requires APCu installed. For production, consider RedisAdapter or FileAdapter.
First Metric
Inject the PrometheusClient service and register a counter:
use DaybreakStudios\PrometheusClient\PrometheusClient;
class MyController extends AbstractController
{
public function __construct(private PrometheusClient $prometheus)
{
}
public function index()
{
$counter = $this->prometheus->getCounter('my_app_requests_total', 'Total requests');
$counter->inc();
// ...
}
}
Expose Metrics
Add this route to your config/routes.yaml:
prometheus:
path: /metrics
controller: DaybreakStudios\PrometheusClientBundle\Controller\MetricsController::metrics
Access /metrics to see Prometheus-compatible metrics.
$counter = $prometheus->getCounter('app_errors_total', 'Total HTTP errors', ['status_code']);
$counter->inc(1, ['status_code' => '500']);
$gauge = $prometheus->getGauge('active_users', 'Current active users');
$gauge->inc(5); // or $gauge->dec(2);
$histogram = $prometheus->getHistogram('request_latency_seconds', 'Request latency', ['route']);
$histogram->observe(0.456, ['route' => 'homepage']);
$summary = $prometheus->getSummary('api_latency_seconds', 'API latency', ['endpoint']);
$summary->observe(0.123, ['endpoint' => 'users']);
Use labels to segment metrics (e.g., by user, route, or environment):
$counter = $prometheus->getCounter('user_actions', 'User actions', ['user_id', 'action']);
$counter->inc(1, ['user_id' => '123', 'action' => 'login']);
Create middleware to track requests globally:
namespace App\Middleware;
use DaybreakStudios\PrometheusClient\PrometheusClient;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class PrometheusMiddleware implements MiddlewareInterface
{
public function __construct(private PrometheusClient $prometheus) {}
public function handle(Request $request, HttpKernelInterface $next)
{
$start = microtime(true);
$response = $next->handle($request);
$duration = microtime(true) - $start;
$this->prometheus->getHistogram('http_request_duration_seconds')
->observe($duration, ['method' => $request->getMethod(), 'path' => $request->getPathInfo()]);
return $response;
}
}
Register in config/services.yaml:
services:
App\Middleware\PrometheusMiddleware:
tags:
- { name: kernel.middleware, priority: -100 }
For distributed systems, replace the default ApcuAdapter with a shared adapter (e.g., Redis):
# config/packages/dbstudios_prometheus.yaml
dbstudios_prometheus:
adapter: redis_adapter
Define the Redis adapter service:
services:
redis_adapter:
class: DaybreakStudios\PrometheusClient\Adapter\RedisAdapter
arguments:
- '@redis.client'
Use Symfony’s Cron component or a scheduler to scrape metrics periodically:
# config/packages/monolog.yaml (example with Monolog)
monolog:
handlers:
prometheus:
type: stream
path: php://output
level: debug
process_psr_3_messages: false
formatter: monolog.formatter.json
Combine with a cron job to push metrics to Prometheus.
Since this is a Symfony bundle, use Symfony’s Bridge in Laravel:
composer require symfony/http-foundation symfony/dependency-injection symfony/config
AppServiceProvider:
use Symfony\Component\DependencyInjection\ContainerBuilder;
public function boot()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
$loader->load('dbstudios_prometheus.yaml');
$this->app->singleton('prometheus', function () use ($container) {
return $container->get('DaybreakStudios\PrometheusClient\PrometheusClient');
});
}
Define rules in prometheus.rules:
groups:
- name: app-alerts
rules:
- alert: HighErrorRate
expr: rate(app_errors_total[1m]) > 0.1
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate on {{ $labels.instance }}"
rate(http_request_duration_seconds_count[1m])).increase(app_errors_total[5m])).histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[1m])) by (le))).ApcuAdapter in production without APCu installed causes crashes.RUN docker-php-ext-install apcu
FileAdapter for local testing (metrics stored in /tmp/prometheus).user_id) can bloat metrics.user_type, region). Use le (bucket) labels for histograms.laravel_app_requests_total).ApcuAdapterapc.enable_cli=0 in php.ini or use RedisAdapter for shared environments.PrometheusClient to Laravel’s container:
$this->app->bind('DaybreakStudios\PrometheusClient\PrometheusClient', function ($app) {
return $app->make('prometheus'); // Your custom service
});
/metrics returns valid Prometheus format:
curl http://localhost/metrics | grep ^#
# HELP my_app_requests_total Total requests
# TYPE my_app_requests_total counter
my_app_requests_total 42
Enable debug mode in
How can I help you explore Laravel packages today?