Weave Code
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 Laravel Package

dbstudios/prometheus-client

Lightweight Prometheus client for PHP. Create a CollectorRegistry, choose a storage adapter (Redis, Filesystem, APCu), then register and use counters, gauges, and histograms. Retrieve collectors by name with typed helpers for safer access.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup for Laravel
1. **Install the package**:
   ```bash
   composer require dbstudios/prometheus-client
  1. Register the service provider (Laravel 5.5+): Add to config/app.php under providers:

    DaybreakStudios\PrometheusClient\PrometheusServiceProvider::class,
    
  2. Publish the config (optional):

    php artisan vendor:publish --provider="DaybreakStudios\PrometheusClient\PrometheusServiceProvider"
    

    This creates a prometheus.php config file in config/.

  3. Basic usage in a controller or service:

    use DaybreakStudios\PrometheusClient\Facades\Prometheus;
    
    // Increment a counter
    Prometheus::counter('api_requests_total', 'Total API requests')->increment();
    
    // Observe a histogram
    Prometheus::histogram('request_duration_seconds', 'Request duration in seconds', [0.1, 0.5, 1.0])
        ->observe(0.45);
    
  4. Expose metrics endpoint (add to routes/web.php):

    use DaybreakStudios\PrometheusClient\Facades\Prometheus;
    
    Route::get('/metrics', function () {
        return Prometheus::export();
    });
    

Implementation Patterns

1. Service Integration

Workflows:

  • Middleware for request tracking:

    use DaybreakStudios\PrometheusClient\Facades\Prometheus;
    
    public function handle($request, Closure $next)
    {
        $start = microtime(true);
        $response = $next($request);
        $duration = microtime(true) - $start;
    
        Prometheus::histogram('http_request_duration_seconds')
            ->labels(['method' => $request->method(), 'path' => $request->path()])
            ->observe($duration);
    
        return $response;
    }
    
  • Job observability (Laravel Queues):

    use DaybreakStudios\PrometheusClient\Facades\Prometheus;
    use Illuminate\Bus\Queueable;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    
    class ProcessPayment implements ShouldQueue
    {
        use Dispatchable, Queueable;
    
        public function handle()
        {
            Prometheus::counter('jobs_processed_total')->increment();
            Prometheus::histogram('job_execution_time_seconds')->observe($this->execute());
        }
    }
    
  • Database query logging:

    use DaybreakStudios\PrometheusClient\Facades\Prometheus;
    use Illuminate\Support\Facades\DB;
    
    DB::listen(function ($query) {
        Prometheus::histogram('db_query_duration_seconds')
            ->labels(['type' => $query->bindings ? 'bound' : 'plain'])
            ->observe($query->time);
    });
    

2. Adapter Selection

Adapter Use Case Laravel-Specific Notes
Redis Production (persistent, scalable) Use Laravel's Redis cache driver config.
Filesystem Debugging, local dev Store in storage/app/prometheus (auto-created).
APCu Testing (in-memory, fast) Avoid in production; data lost on restart.
InMemory Unit tests Requires symfony/stopwatch for timers.

Example Redis config (config/prometheus.php):

'adapter' => [
    'driver' => 'redis',
    'config' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'port' => env('REDIS_PORT', 6379),
        'password' => env('REDIS_PASSWORD', null),
        'prefix' => 'laravel_prom_',
    ],
],

3. Collector Patterns

Collector Type Laravel Use Case Example
Counter Track cumulative events (e.g., emails sent, API calls). Prometheus::counter('emails_sent_total')->increment()
Gauge Track real-time metrics (e.g., queue size, memory usage). Prometheus::gauge('queue_size')->set(app('queue')->size())
Histogram Measure distributions (e.g., request latency, DB query times). Prometheus::histogram('cache_hit_latency_ms')->observe($latency)

Dynamic labels with Laravel helpers:

use Illuminate\Support\Str;

Prometheus::counter('api_errors_total')
    ->labels([
        'endpoint' => Str::after($request->path(), '/api/'),
        'status' => $response->status(),
    ])
    ->increment();

4. Exporting Metrics

  • Basic endpoint (Laravel route):

    Route::get('/metrics', function () {
        return Prometheus::export();
    })->name('metrics');
    
  • Authenticated endpoint (use Laravel middleware):

    Route::get('/metrics', function () {
        return Prometheus::export();
    })->middleware('auth:prometheus-token'); // Custom middleware
    
  • Custom renderer (e.g., JSON for Grafana):

    use DaybreakStudios\PrometheusClient\Export\Render\JsonRenderer;
    
    Route::get('/metrics/json', function () {
        $renderer = new JsonRenderer();
        return response()->json($renderer->render(Prometheus::collect()));
    });
    

Gotchas and Tips

1. Common Pitfalls

Issue Solution
Labels missing in exports Ensure all labels are defined during registration (not dynamically).
APCu not working in CLI Add apc.enable_cli=1 to php.ini or use FilesystemAdapter for CLI.
Redis connection errors Verify Laravel's Redis config matches the adapter config.
Histograms with symfony/stopwatch Install via composer require symfony/stopwatch.
Type mismatches in get*() methods Use getCounter(), getGauge(), etc., for IDE autocompletion.

2. Debugging

  • Check registered collectors:

    dd(Prometheus::registry()->collectors());
    
  • Inspect adapter storage:

    // For Redis:
    dd(Prometheus::adapter()->search('*')->toArray());
    
    // For Filesystem:
    dd(scandir(storage_path('app/prometheus')));
    
  • Validate metric names: Prometheus requires metric names to match /^[a-zA-Z_:][a-zA-Z0-9_:]*$/. Use Str::snake()` for Laravel models:

    Prometheus::counter('user.' . Str::snake(class_basename($user)) . '_created_total');
    

3. Performance Tips

  • Batch increments (e.g., for bulk operations):

    Prometheus::counter('users_created_total')->increment(10); // +10 in one call
    
  • Avoid frequent observe() calls in loops:

    // Bad: Observes 1000 times
    foreach ($items as $item) {
        Prometheus::histogram('item_processing_time_ms')->observe($time);
    }
    
    // Good: Batch observe
    $times = array_map(fn($item) => $item->processing_time, $items);
    Prometheus::histogram('item_processing_time_ms')->observe($times);
    
  • Use time() for block timing (avoids manual microtime() calls):

    Prometheus::histogram('cache_operation_time_ms')->time(function () {
        Cache::get('key');
    });
    

4. Advanced Patterns

  • Custom collectors (extend base classes):

    use DaybreakStudios\PrometheusClient\Collector\CollectorInterface;
    use DaybreakStudios\PrometheusClient\Collector\Collector;
    
    class LaravelQueueGauge extends Collector implements CollectorInterface
    {
        public function set($value, array $labels = [])
        {
            $this->value = app('queue')->size();
            $this->labels = $labels;
        }
    }
    
  • Dynamic metric registration (e.g., per-tenant):

    Prometheus::registry()->register(
        new Counter(Prometheus::adapter(), 'tenant_requests_total', 'Requests per tenant', ['tenant_id']),
        ['tenant_id' => auth()->user()->tenant_id]
    );
    
  • Prometheus annotations (for alerts):

    Prometheus::gauge('app_uptime_seconds')->set(time() - $startTime);
    // Annotate in Prometheus config:
    
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor