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

Laravel Prometheus Laravel Package

movemoveapp/laravel-prometheus

Laravel package to collect and expose Prometheus metrics using Redis storage. Friendly fork of shureban/laravel-prometheus with support for predis/predis ^3.0. Includes artisan generators for counter and gauge metrics and publishable configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require movemoveapp/laravel-prometheus
    

    Update config/app.php to include the service provider:

    Shureban\LaravelPrometheus\PrometheusServiceProvider::class,
    
  2. Publish Config (if customization is needed):

    php artisan vendor:publish --provider="Shureban\LaravelPrometheus\PrometheusServiceProvider"
    
  3. Configure Redis Client (if using Redis): Update .env:

    REDIS_CLIENT=predis
    
  4. First Metric Creation: Use Artisan to generate a counter metric:

    php artisan make:counter AuthEvents --name=auth_events --labels=event --description="Auth-related events"
    

    This creates a class like app/Prometheus/AuthEvents.php.

  5. Expose Metrics Endpoint: Ensure the web_route in config/prometheus.php is accessible (default: /prometheus/metrics).

  6. Test Metrics: Access the endpoint (/prometheus/metrics) and verify metrics appear in Prometheus format.


First Use Case

Track User Authentication Events:

  1. Create a counter metric for auth events:
    php artisan make:counter AuthEvents --name=auth_events --labels=event,status --description="Auth events with status"
    
  2. Inject the metric into a controller and increment it:
    use App\Prometheus\AuthEvents;
    
    class LoginController extends Controller {
        public function login(AuthEvents $authEvents) {
            // Auth logic...
            $authEvents->withLabelsValues(['login', 'success'])->inc();
        }
    }
    
  3. Verify the metric appears in /prometheus/metrics:
    # HELP auth_events Auth events with status
    # TYPE auth_events counter
    auth_events{event="login",status="success"} 1
    

Implementation Patterns

Core Workflows

1. Metric Creation and Registration

  • CLI Generation: Use Artisan commands to scaffold metrics:

    php artisan make:counter UserActions --name=user_actions --labels=action,outcome --dynamic
    

    This generates a dynamic counter with action and outcome labels.

  • Manual Implementation: For static metrics, manually create classes in app/Prometheus:

    namespace App\Prometheus;
    use Shureban\LaravelPrometheus\{Counter, Name, Labels};
    
    class ApiErrors extends Counter {
        public function __construct() {
            parent::__construct(
                new Name('api_errors'),
                new Labels(['endpoint', 'http_status']),
                'Count of API errors by endpoint and status'
            );
        }
    }
    

    Register the metric in a service provider:

    $this->app->bind('apiErrors', function() {
        return new ApiErrors();
    });
    

2. Metric Instrumentation

  • Dependency Injection: Inject metrics into controllers/services:

    class OrderService {
        public function create(OrderRequest $request, ApiErrors $apiErrors) {
            try {
                // Logic...
            } catch (\Exception $e) {
                $apiErrors->withLabelsValues(['/orders', '500'])->inc();
                throw $e;
            }
        }
    }
    
  • Contextual Labels: Use dynamic labels for runtime context:

    $userMetrics->withLabels([
        'user_id' => auth()->id(),
        'role' => auth()->user()->role
    ])->inc();
    
  • Helper Methods: Encapsulate label logic in metric classes:

    class UserMetrics extends Counter {
        public function loginFailed() {
            $this->withLabelsValues(['event' => 'login', 'status' => 'failed'])->inc();
        }
    }
    

3. Rendering Metrics

  • Web Route: Configure web_route in config/prometheus.php (default: /prometheus/metrics). The package auto-registers a route for text-format rendering.

  • Manual Rendering: For custom routes or formats:

    use Shureban\LaravelPrometheus\RenderTextFormat;
    
    Route::get('/custom-metrics', function() {
        $renderer = new RenderTextFormat();
        return response($renderer->render(), 200, ['Content-Type' => RenderTextFormat::MIME_TYPE]);
    });
    

4. Event-Based Metrics

  • Listen to Laravel Events: Instrument events globally:

    use Illuminate\Support\Facades\Event;
    use App\Prometheus\AuthEvents;
    
    Event::listen('auth.attempted', function($event) {
        app(AuthEvents::class)->withLabelsValues(['event' => 'attempt', 'status' => $event->success ? 'success' : 'failed'])->inc();
    });
    
  • Queue Job Metrics: Track job processing:

    class ProcessPaymentJob implements ShouldQueue {
        public function handle() {
            app('paymentJobs')->withLabelsValues(['job' => 'process_payment', 'status' => 'started'])->inc();
            try {
                // Job logic...
                app('paymentJobs')->withLabelsValues(['job' => 'process_payment', 'status' => 'completed'])->inc();
            } catch (\Exception $e) {
                app('paymentJobs')->withLabelsValues(['job' => 'process_payment', 'status' => 'failed'])->inc();
                throw $e;
            }
        }
    }
    

Integration Tips

1. Prometheus Scraping

  • Configure Prometheus to scrape the /prometheus/metrics endpoint:
    scrape_configs:
      - job_name: 'laravel_app'
        static_configs:
          - targets: ['your-laravel-app:8000']
    
  • Use environment variables for dynamic hostnames:
    // config/prometheus.php
    'web_route' => env('PROMETHEUS_ROUTE', '/prometheus/metrics'),
    

2. Label Strategies

  • Static Labels: Use for fixed dimensions (e.g., environment=production).
  • Dynamic Labels: Use for runtime context (e.g., user_id, request_id).
  • Avoid Over-Labeling: Limit labels to 3-5 per metric to reduce cardinality.

3. Testing Metrics

  • Unit Tests: Mock metrics in tests:
    $counter = Mockery::mock(AuthEvents::class);
    $counter->shouldReceive('withLabelsValues')->with(['login', 'success'])->once()->andReturnSelf();
    $counter->shouldReceive('inc')->once();
    
  • Integration Tests: Use HTTP tests to verify /prometheus/metrics:
    $response = $this->get('/prometheus/metrics');
    $response->assertSeeText('# HELP auth_events Auth events with status');
    

4. Performance Considerations

  • Redis Backend: If using Redis, ensure Predis ^3.0 is optimized for your Redis cluster.
  • Batch Operations: For high-throughput apps, batch metric increments (e.g., using queues).
  • Avoid Blocking: Ensure metric updates don’t block critical paths (e.g., use async queues for non-critical metrics).

5. Custom Metric Types

  • Extend Base Classes: Create custom metric types by extending Counter, Gauge, etc.:
    namespace App\Prometheus;
    use Shureban\LaravelPrometheus\Gauge;
    
    class MemoryUsage extends Gauge {
        public function setCurrentUsage(int $bytes) {
            $this->set($bytes);
        }
    }
    

Gotchas and Tips

Pitfalls

1. Redis Dependency

  • Issue: The package uses Redis as a backend for metric storage. If Redis is down, metrics may not be collected or exposed.
  • Fix: Implement a fallback (e.g., in-memory storage) or ensure Redis is highly available.
  • Workaround: For local development, use a local Redis instance or mock the Redis client.

2. Label Cardinality Explosion

  • Issue: Overusing dynamic labels (e.g., user_id) can explode cardinality, overwhelming Prometheus.
  • Fix: Limit dynamic labels to high-level dimensions (e.g., user_segment instead of user_id).
  • Tip: Use le (less-than-or-equal) or ge (greater-than-or-equal) labels for numeric ranges.

3. Metric Naming Conflicts

  • Issue: Custom metric names must be unique across the application. Conflicts can lead to silent failures.
  • Fix: Prefix custom metrics (e.g., app_auth_events).
  • Tip: Use the --name flag in Artisan commands to enforce consistency.

4. **Pred

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.
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php
trappistes/laravel-custom-fields
splash/sonata-admin
splash/metadata