Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Prometheus Client Php Laravel Package

endclothing/prometheus_client_php

A PHP Prometheus client for instrumenting applications and exposing metrics for scraping. Provides counters, gauges, histograms, and summaries with in-memory, APC, and Redis storage adapters, plus framework-friendly integration for monitoring Laravel/PHP services.

Deep Wiki
Context7

Getting Started

Install the package:

composer require endclothing/prometheus_client_php

Everything lives under the Prometheus\ namespace. The three objects you touch first:

  • Prometheus\CollectorRegistry — register and hold metrics.
  • Prometheus\Storage\Redis / APC / InMemory / PDO — the backing store.
  • Prometheus\RenderTextFormat — renders the /metrics payload.

Minimal endpoint:

use Prometheus\CollectorRegistry;
use Prometheus\Storage\Redis;
use Prometheus\RenderTextFormat;

$adapter  = new Redis(['host' => '127.0.0.1', 'port' => 6379]);
$registry = new CollectorRegistry($adapter);

$counter = $registry->getOrRegisterCounter(
    'app',
    'http_requests_total',
    'Total HTTP requests',
    ['method', 'route', 'status']
);
$counter->inc(['GET', '/home', '200']);

$renderer = new RenderTextFormat();
header('Content-Type: ' . RenderTextFormat::MIME_TYPE);
echo $renderer->render($registry->getMetricFamilySamples());

First use case: instrument the request lifecycle — a counter for requests, a histogram for latency, a gauge for queue depth. Start by reading CollectorRegistry, the adapter class you choose, and the README examples for Counter, Gauge, Histogram, and Summary.

Implementation Patterns

Centralize metric definitions. Put all getOrRegister* calls in one class or service provider. Registration is idempotent for identical config, but a changed help string or label list throws MetricsRegistrationException. One canonical definition avoids that.

Laravel integration skeleton:

// AppServiceProvider::register()
$this->app->singleton(CollectorRegistry::class, function () {
    Redis::setPrefix(config('prometheus.prefix', 'app'));
    $adapter = new Redis([
        'host' => config('prometheus.redis.host'),
        'port' => config('prometheus.redis.port'),
    ]);
    return new CollectorRegistry($adapter);
});
// routes/api.php
Route::get('/metrics', function (CollectorRegistry $registry) {
    $renderer = new RenderTextFormat();
    return response($renderer->render($registry->getMetricFamilySamples()))
        ->header('Content-Type', RenderTextFormat::MIME_TYPE);
});

Middleware for RED metrics. Time the request, then observe a histogram labelled by route template (not raw URI):

$start = microtime(true);
$response = $next($request);
$route = $request->route()?->uri() ?? 'unmatched';

app(CollectorRegistry::class)
    ->getOrRegisterHistogram(
        'app',
        'http_request_duration_seconds',
        'HTTP request duration',
        ['route', 'method'],
        [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]
    )
    ->observe(microtime(true) - $start, [$route, $request->method()]);

Adapter selection. Redis is the default for multi-server deployments. APC/APCu is faster but shared only within one host's PHP-FPM pool. PDO works when you have a database but no Redis (expect more write load). InMemory is for tests and single-process scripts only.

CLI and cron jobs. A scrape cannot reach a short-lived CLI process, so push to a Pushgateway:

$gateway = new Prometheus\PushGateway('http://pushgateway:9091');
$gateway->pushAdd(
    $registry->getMetricFamilySamples(),
    'nightly-report',
    ['env' => 'prod']
);

Use pushAdd for accumulating counters across runs; use push when the job should replace its previous snapshot.

Testing. Swap in Prometheus\Storage\InMemory, call $registry->wipeStorage() in setUp(), then assert on getMetricFamilySamples() or rendered output. This keeps CI free of Redis/APCu.

Custom backends. Implement Prometheus\Storage\Adapter if you need DynamoDB, Memcached, etc.; the registry only depends on that interface.

Gotchas and Tips

  • Registration mismatches throw. If a metric with the same name was registered with a different help string or label set, getOrRegister* throws. Version the metric name or wipe storage when you intentionally change schema.
  • Metrics don't appear until first write. A labelled counter only shows up after inc()/incBy(). Call incBy(0, $labels) at startup to expose zero-valued series.
  • Counter names and _total. Use the _total suffix yourself (http_requests_total); the library exposes the name you register. Histograms automatically expose _bucket, _sum, and _count.
  • InMemory is per-process. It does not survive between requests. APC/APCu is per-host and requires apc.enable_cli=1 for CLI tests. Redis is the safe shared store.
  • High cardinality kills Prometheus. Never label by user ID, raw URL, email, or request ID. Label by route template, status class, method, queue name.
  • Keep label order consistent. Pass associative arrays in the same order each call; adapters serialize label sets into storage keys and order can create duplicate series.
  • Histogram bucket changes are invasive. Existing stored bucket keys won't match a new bucket list; rename the metric or wipe storage when changing buckets. Summary in this library is basic — prefer Histogram for latency quantiles.
  • Gauges persist. There is no "reset per scrape"; set the gauge to the current value on each update. For per-request values, a gauge will look stale until overwritten.
  • Redis prefixes and cleanup. Use Redis::setPrefix() to namespace keys per app/environment. Call $registry->wipeStorage() only in tests or explicit admin commands — never on a live /metrics request.
  • Protect the endpoint. /metrics can leak route names, versions, and traffic patterns. Restrict by network policy or auth; scrape from inside the cluster.
  • Correct response format. Use RenderTextFormat::MIME_TYPE; ensure no BOM, debug output, or framework error page precedes the render.
  • Octane/Swoole caution. A long-lived worker keeps the registry and in-memory adapter alive across requests; metrics can go stale between requests. Use Redis/APC and be deliberate about gauge updates.
  • Debugging checklist. Dump getMetricFamilySamples() to confirm registration; check adapter connectivity and prefix; confirm the scrape hits the same Redis DB/APC pool; confirm wipeStorage() isn't running in production.
  • Performance. Each observation is a storage round-trip. For hot paths, sample (e.g. 1 in 10 requests) or aggregate in-process and flush periodically; do not put a Redis call in a tight loop.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings