PHP code example of iamfarhad / laravel-prometheus

1. Go to this page and download the library: Download iamfarhad/laravel-prometheus library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

iamfarhad / laravel-prometheus example snippets


->withMiddleware(function (Middleware $middleware) {
    // Easy one-liner for HTTP metrics - automatically checks if enabled
    \Iamfarhad\Prometheus\Support\PrometheusMiddlewareHelper::register($middleware);
})

->withMiddleware(function (Middleware $middleware) {
    $middleware->append(\Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware::class);
})

// In routes/api.php
Route::middleware([\Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware::class])
    ->group(function () {
        Route::get('/users', [UserController::class, 'index']);
        Route::post('/orders', [OrderController::class, 'store']);
        Route::get('/analytics/{id}', [AnalyticsController::class, 'show']);
    });

// Monitor only critical API endpoints
Route::get('/api/orders', [OrderController::class, 'index'])
    ->middleware(\Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware::class);

Route::post('/api/payments', [PaymentController::class, 'process'])
    ->middleware(\Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware::class);

// In bootstrap/app.php - register middleware alias
->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'prometheus' => \Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware::class,
    ]);
})

// In routes/api.php - use the alias
Route::middleware(['prometheus'])->group(function () {
    Route::apiResource('users', UserController::class);
    Route::apiResource('orders', OrderController::class);
});



namespace App\Http\Controllers;

use Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware;

class ApiController extends Controller
{
    public function __construct()
    {
        // Apply metrics to all methods in this controller
        $this->middleware(PrometheusMetricsMiddleware::class);
    }
}

// Monitor only in production or specific environments
Route::middleware(app()->environment('production') 
    ? [\Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware::class] 
    : []
)->group(function () {
    Route::apiResource('analytics', AnalyticsController::class);
});

use Iamfarhad\Prometheus\Facades\Prometheus;

// Register and use a counter
$counter = Prometheus::getOrRegisterCounter('orders_total', 'Total number of orders', ['status']);
$counter->inc(['completed']);

// Register and use a histogram for response times
$histogram = Prometheus::getOrRegisterHistogram(
    'api_response_time', 
    'API response time in seconds', 
    ['endpoint', 'method'],
    [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0] // Industry-standard buckets
);
$histogram->observe(0.45, ['api/users', 'GET']);

// Register and use a summary for percentile tracking
$summary = Prometheus::getOrRegisterSummary(
    'request_size_bytes',
    'Request size summary with quantiles',
    ['content_type'],
    600, // 10 minutes max age
    [0.5, 0.95, 0.99, 0.999] // p50, p95, p99, p99.9
);
$summary->observe(1024, ['application/json']);



namespace App\Http\Controllers;

use Iamfarhad\Prometheus\Facades\Prometheus;
use Illuminate\Http\Request;

class ApiController extends Controller
{
    public function createOrder(Request $request)
    {
        $startTime = microtime(true);

        try {
            $order = Order::create($request->validated());
            
            // Record success metrics
            Prometheus::getOrRegisterCounter('orders_created_total', 'Orders created', ['status'])
                ->inc(['success']);
            
            // Record processing time
            Prometheus::getOrRegisterHistogram('order_processing_time', 'Order processing duration', ['type'])
                ->observe(microtime(true) - $startTime, ['express']);
            
            return response()->json($order, 201);
        } catch (\Exception $e) {
            // Record error metrics
            Prometheus::getOrRegisterCounter('orders_created_total', 'Orders created', ['status'])
                ->inc(['error']);
            throw $e;
        }
    }
}

'http' => [
    'enabled' => env('PROMETHEUS_COLLECTOR_HTTP_ENABLED', true),
    
    // SLO-optimized buckets covering p50 (~100ms) to p99.9 (~2.5s)
    'histogram_buckets' => [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0],
    'summary_quantiles' => [0.5, 0.95, 0.99, 0.999],
    'summary_max_age' => 600,
    
    // Size tracking from 1KB to 16MB
    'size_buckets' => [1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216],
],

'database' => [
    'enabled' => env('PROMETHEUS_COLLECTOR_DATABASE_ENABLED', true),
    
    // Sub-millisecond precision for fast queries to 5s for complex operations
    'histogram_buckets' => [0.0005, 0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0],
    'summary_quantiles' => [0.5, 0.95, 0.99, 0.999],
    'summary_max_age' => 600,
],

'cache' => [
    'enabled' => env('PROMETHEUS_COLLECTOR_CACHE_ENABLED', false), // Disabled by default
    
    // Sub-millisecond precision for cache operations
    'histogram_buckets' => [0.0001, 0.0005, 0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.1],
    'summary_quantiles' => [0.5, 0.95, 0.99],
    'summary_max_age' => 300, // 5 minutes for frequent operations
],

'queue' => [
    'enabled' => env('PROMETHEUS_COLLECTOR_QUEUE_ENABLED', true),
    
    // Wide range from quick jobs to long-running processes (10 minutes)
    'histogram_buckets' => [0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0, 30.0, 60.0, 120.0, 300.0, 600.0],
    'summary_quantiles' => [0.5, 0.95, 0.99],
    'summary_max_age' => 900, // 15 minutes for long-running jobs
],

'command' => [
    'enabled' => env('PROMETHEUS_COLLECTOR_COMMAND_ENABLED', true),
    
    // From quick commands to long migrations (30 minutes)
    'histogram_buckets' => [0.1, 0.5, 1.0, 2.5, 5.0, 10.0, 30.0, 60.0, 120.0, 300.0, 600.0, 1800.0],
],

'storage' => [
    'driver' => env('PROMETHEUS_STORAGE_DRIVER', 'redis'), // redis, memory, apcu

    'redis' => [
        'connection' => env('PROMETHEUS_REDIS_CONNECTION', 'default'),
        'prefix' => env('PROMETHEUS_REDIS_PREFIX', 'prometheus_'),
    ],
],

'namespace' => env('PROMETHEUS_NAMESPACE', ''), // e.g., 'myapp'

// Optimized for SLO monitoring
'default_histogram_buckets' => [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0],

// Complete percentile coverage
'default_summary_quantiles' => [0.5, 0.95, 0.99, 0.999],

// Balanced for real-time monitoring
'default_summary_max_age' => 600, // 10 minutes

'metrics_route' => [
    'enabled' => env('PROMETHEUS_METRICS_ROUTE_ENABLED', true),
    'path' => env('PROMETHEUS_METRICS_PATH', '/metrics'),
    'middleware' => [], // Add security middleware
],

'metrics_route' => [
    'middleware' => [\Iamfarhad\Prometheus\Http\Middleware\AllowIps::class],
],

'metrics_route' => [
    'middleware' => ['auth.basic', 'throttle:60,1'],
],

'metrics_route' => [
    'middleware' => [
        \Iamfarhad\Prometheus\Http\Middleware\AllowIps::class,
        'auth.basic',
        'throttle:60,1',
    ],
],

use Iamfarhad\Prometheus\Facades\Prometheus;

// Counter with custom labels
$counter = Prometheus::getOrRegisterCounter(
    'user_actions_total',
    'Total user actions',
    ['action_type', 'source']
);
$counter->inc(['login', 'web']);

// Histogram with industry-standard buckets
$histogram = Prometheus::getOrRegisterHistogram(
    'api_response_time',
    'API response time distribution', 
    ['endpoint', 'method'],
    [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0]
);
$histogram->observe(0.075, ['users', 'GET']);

// Summary with percentile tracking
$summary = Prometheus::getOrRegisterSummary(
    'request_processing_time',
    'Request processing time summary',
    ['service', 'endpoint'],
    600, // 10 minutes max age
    [0.5, 0.95, 0.99, 0.999] // p50, p95, p99, p99.9
);
$summary->observe(0.125, ['auth', 'login']);

// Gauge for real-time values
$gauge = Prometheus::getOrRegisterGauge(
    'active_connections',
    'Number of active connections',
    ['service']
);
$gauge->set(42, ['websocket']);



namespace App\Http\Middleware;

use Iamfarhad\Prometheus\Facades\Prometheus;
use Closure;

class MetricsMiddleware
{
    public function handle($request, Closure $next)
    {
        $startTime = microtime(true);
        
        $response = $next($request);
        
        // Record custom business metrics
        Prometheus::getOrRegisterHistogram(
            'business_operation_duration',
            'Business operation processing time',
            ['operation', 'user_type']
        )->observe(
            microtime(true) - $startTime,
            [$request->route()->getName(), $request->user()?->type ?? 'guest']
        );
        
        return $response;
    }
}

use Iamfarhad\Prometheus\Tests\TestCase;

class CustomMetricsTest extends TestCase
{
    public function test_custom_counter_increments()
    {
        $counter = Prometheus::getOrRegisterCounter('test_counter', 'Test counter', ['type']);
        $counter->inc(['test']);
        $counter->inc(['test']);

        $metrics = Prometheus::collect();
        $this->assertStringContains('test_counter{type="test"} 2', Prometheus::render());
    }

    public function test_summary_tracks_percentiles()
    {
        $summary = Prometheus::getOrRegisterSummary(
            'test_summary',
            'Test summary',
            ['method'],
            300,
            [0.5, 0.95, 0.99]
        );
        
        // Add sample observations
        for ($i = 0; $i < 100; $i++) {
            $summary->observe($i / 100, ['GET']);
        }

        $rendered = Prometheus::render();
        $this->assertStringContains('test_summary{method="GET",quantile="0.5"}', $rendered);
        $this->assertStringContains('test_summary{method="GET",quantile="0.95"}', $rendered);
    }
}

   // Tailor buckets to your use case
   'histogram_buckets' => [0.01, 0.05, 0.1, 0.5, 1.0, 2.5, 5.0],
   

// Global Registration (All Routes)
// ✅ Complete monitoring coverage
// ⚠️  ~0.1ms overhead per request
// 📊 Full application metrics
Route::middleware(['prometheus'])->group(function () {
    // All routes monitored
});

// Route-Specific Registration (Critical Routes Only)
// ✅ Minimal performance impact
// ✅ Focus on business-critical metrics
// ⚠️  Partial monitoring coverage
Route::middleware(['prometheus'])->group(function () {
    Route::post('/api/orders', [OrderController::class, 'store']);      // Monitor
    Route::post('/api/payments', [PaymentController::class, 'process']); // Monitor
});
Route::get('/health', [HealthController::class, 'check']); // Skip monitoring

// Smart Conditional Registration
// ✅ Environment-specific monitoring
// ✅ Zero production overhead for non-critical routes
Route::middleware(config('app.env') === 'production' 
    ? ['prometheus'] 
    : []
)->group(function () {
    // Production: monitored, Development: not monitored
});

// routes/api.php - Production-optimized monitoring setup

// Critical business endpoints - Always monitor
Route::middleware([\Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware::class])
    ->prefix('api/v1')
    ->group(function () {
        Route::post('/orders', [OrderController::class, 'store']);
        Route::put('/orders/{id}/status', [OrderController::class, 'updateStatus']);
        Route::post('/payments', [PaymentController::class, 'process']);
        Route::get('/analytics/sales', [AnalyticsController::class, 'sales']);
    });

// Admin endpoints - Monitor in production only
Route::middleware(app()->environment('production') 
    ? [\Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware::class] 
    : []
)->prefix('admin')->group(function () {
    Route::get('/dashboard', [AdminController::class, 'dashboard']);
    Route::post('/users', [UserController::class, 'store']);
});

// Health/Status endpoints - No monitoring needed (reduces noise)
Route::get('/health', [HealthController::class, 'check']);
Route::get('/status', [StatusController::class, 'check']);

// Public API - Selective monitoring for rate limiting insights
Route::prefix('public-api')->group(function () {
    Route::middleware([\Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware::class])
        ->get('/search', [SearchController::class, 'search']); // Monitor
    
    Route::get('/docs', [DocsController::class, 'index']); // Don't monitor
});

// Reduce Summary max age for high-traffic applications
'summary_max_age' => 300, // 5 minutes instead of 10

// Use fewer quantiles for less critical metrics
'summary_quantiles' => [0.5, 0.95], // Instead of [0.5, 0.95, 0.99, 0.999]
bash
php artisan vendor:publish --provider="Iamfarhad\Prometheus\PrometheusServiceProvider" --tag="prometheus-config"