iamfarhad / laravel-prometheus
Production-ready Laravel Prometheus metrics package with built-in collectors for HTTP, database, cache, queue, events, errors, filesystem, and mail monitoring
Requires
- php: ^8.1
- illuminate/config: ^10.0|^11.0|^12.0
- illuminate/database: ^10.0|^11.0|^12.0
- illuminate/events: ^10.0|^11.0|^12.0
- illuminate/filesystem: ^10.0|^11.0|^12.0
- illuminate/log: ^10.0|^11.0|^12.0
- illuminate/mail: ^10.0|^11.0|^12.0
- illuminate/redis: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- promphp/prometheus_client_php: ^2.14
Requires (Dev)
- laravel/pint: ^1.0
- mockery/mockery: ^1.0|^2.0
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0|^11.0|^12.0
Suggests
- ext-apcu: Required for APCu storage adapter
- ext-redis: Required for Redis storage adapter
- predis/predis: Alternative Redis client
This package is auto-updated.
Last update: 2025-09-10 22:57:57 UTC
README
Enterprise-grade Prometheus metrics exporter for Laravel applications with comprehensive monitoring capabilities and industry-standard SLO tracking.
Built on the official PromPHP/prometheus_client_php library for maximum compatibility and performance.
โจ Key Features
- ๐ฏ Complete Metric Types: Counter, Gauge, Histogram, and Summary metrics with percentile tracking
- ๐ Advanced Collectors: HTTP, Database, Cache, Queue, Commands, Events, Errors, Filesystem, Mail, and Horizon
- ๐ญ Production-Ready: Built with official PromPHP library and Laravel best practices
- ๐ SLO Monitoring: Industry-standard bucket configurations for p50, p95, p99, p99.9 tracking
- ๐พ Multiple Storage: Redis, Memory, and APCu storage adapters
- ๐ Security First: IP whitelisting, authentication middleware, and secure endpoint protection
- โก High Performance: Optimized for minimal overhead with intelligent filtering
- ๐งช Fully Tested: Comprehensive test suite covering all components
- ๐ Developer Friendly: Rich documentation and intuitive API
๐ฆ Installation
composer require iamfarhad/laravel-prometheus
Publish Configuration
php artisan vendor:publish --provider="Iamfarhad\Prometheus\PrometheusServiceProvider" --tag="prometheus-config"
HTTP Middleware Setup
For HTTP request tracking, you need to register the middleware. Choose one of these simple options:
โ Option 1: Easy Helper (Recommended)
No more complex setup! Add this single line to your bootstrap/app.php
:
->withMiddleware(function (Middleware $middleware) { // Easy one-liner for HTTP metrics - automatically checks if enabled \Iamfarhad\Prometheus\Support\PrometheusMiddlewareHelper::register($middleware); })
Benefits:
- โ One line setup - No complex configuration needed
- โ Automatic checks - Only registers if HTTP collector is enabled
- โ Laravel 11+ optimized - Works perfectly with new bootstrap structure
- โ Future-proof - Handles configuration changes automatically
โ Option 2: Manual Registration
->withMiddleware(function (Middleware $middleware) { $middleware->append(\Iamfarhad\Prometheus\Http\Middleware\PrometheusMetricsMiddleware::class); })
โ Option 3: Automatic Registration (Experimental)
Enable automatic middleware registration in your .env
:
PROMETHEUS_MIDDLEWARE_AUTO_REGISTER=true
Note: Automatic registration attempts to register middleware programmatically. If it doesn't work in your setup, use Options 1 or 2.
โก Option 4: Route-Specific Registration (Performance Optimized)
For high-performance applications where you want to monitor only specific routes:
Route Groups:
// 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']); });
Individual Routes:
// 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);
Route Groups with Aliases:
// 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); });
Controller-Level Registration:
<?php 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); } }
Conditional Route Monitoring:
// 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); });
Benefits of Route-Specific Registration:
- โ Performance: Monitor only critical endpoints
- โ Selective Monitoring: Focus on business-critical routes
- โ Resource Efficiency: Reduce monitoring overhead
- โ Environment Control: Different monitoring per environment
- โ Granular Control: Fine-tune monitoring scope
Use Cases:
- High-traffic applications with performance requirements
- API endpoints where you want selective monitoring
- Admin routes that need separate tracking
- Public vs authenticated route monitoring
- Critical business logic routes only
๐ Quick Start
Basic Usage
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']);
Controller Integration
<?php 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; } } }
๐ Built-in Collectors
๐ HTTP Request Collector
Automatically enabled - Tracks all HTTP requests with comprehensive metrics.
Metrics:
http_requests_total{method, route, status}
- Total HTTP requests counterhttp_request_duration_seconds{method, route}
- Response time histogramhttp_request_duration_seconds_summary{method, route}
- Response time percentileshttp_request_size_bytes{method, route}
- Request payload sizehttp_response_size_bytes{method, route, status}
- Response payload size
Industry-Standard Configuration:
'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], ],
Example Metrics:
# HTTP request rate and latency
http_requests_total{method="GET",route="api/users",status="200"} 1250
http_request_duration_seconds_bucket{method="GET",route="api/users",le="0.1"} 1180
http_request_duration_seconds_summary{method="GET",route="api/users",quantile="0.95"} 0.085
http_request_size_bytes_bucket{method="POST",route="api/orders",le="4096"} 89
๐๏ธ Database Query Collector
Automatically enabled - Monitors database performance with operation-level granularity.
Metrics:
database_queries_total{connection, table, operation}
- Query count by operation typedatabase_query_duration_seconds{connection, table, operation}
- Query duration histogramdatabase_query_duration_seconds_summary{connection, table, operation}
- Query duration percentiles
Supported Operations: select
, insert
, update
, delete
, create
, drop
, alter
, truncate
Fine-Grained Configuration:
'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, ],
Example Metrics:
# Database performance tracking
database_queries_total{connection="mysql",table="users",operation="select"} 1250
database_queries_total{connection="mysql",table="orders",operation="insert"} 89
database_query_duration_seconds_summary{connection="mysql",table="users",operation="select",quantile="0.95"} 0.0025
โก Cache Operation Collector
Disabled by default - Monitors application cache operations (not internal storage).
โ ๏ธ Important: Disabled by default to prevent recursive counting of Prometheus's own Redis operations.
Metrics:
cache_operations_total{store, operation, result}
- Cache operation countscache_operation_duration_seconds{store, operation}
- Operation durationcache_operation_duration_seconds_summary{store, operation}
- Duration percentiles
Operations: get
, put
, forget
, flush
Results: hit
, miss
, success
, failure
Intelligent Filtering:
'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 ],
Enable for Application Cache:
PROMETHEUS_COLLECTOR_CACHE_ENABLED=true
๐ Queue Job Collectors
Basic Queue Collector
Automatically enabled - Tracks queue job processing and performance.
Metrics:
queue_jobs_total{queue, connection, status, job_class}
- Processed jobs countqueue_job_duration_seconds{queue, job_class}
- Job processing time histogramqueue_job_duration_seconds_summary{queue, job_class}
- Processing time percentilesqueue_active_jobs{queue, connection}
- Currently active jobs gauge
Status Values: completed
, failed
, exception
, timeout
Enhanced Queue Collector
Advanced monitoring with comprehensive queue health metrics:
Additional Metrics:
queue_job_wait_time_seconds{queue, job_class}
- Time jobs wait before processingqueue_job_retries_total{queue, job_class, reason}
- Job retry attemptsqueue_job_timeouts_total{queue, job_class}
- Job timeout occurrencesqueue_size{queue, connection, status}
- Queue depth metricsqueue_pending_jobs{queue, connection}
- Jobs waiting to be processedqueue_failed_jobs{queue, connection}
- Failed jobs countqueue_workers{queue, connection, supervisor}
- Active worker processes
Configuration:
'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 Collector
Automatically enabled - Tracks Laravel Artisan command executions.
Metrics:
artisan_commands_total{command, status}
- Command execution countartisan_command_duration_seconds{command, status}
- Execution time histogram
Status Values: success
, error
, invalid_usage
, interrupted
, unknown
Configuration:
'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], ],
Example Metrics:
artisan_commands_total{command="migrate",status="success"} 5
artisan_commands_total{command="queue_work",status="success"} 1
artisan_command_duration_seconds_bucket{command="migrate",le="30"} 5
๐ Horizon Collector
Available when Laravel Horizon is installed - Comprehensive Horizon monitoring.
Metrics:
horizon_supervisors{environment}
- Active supervisors counthorizon_workload{queue, supervisor}
- Queue workload distributionhorizon_master_loops_total{environment}
- Master supervisor loopsqueue_workers{queue, connection, supervisor}
- Worker process tracking
Enable:
PROMETHEUS_COLLECTOR_HORIZON_ENABLED=true
Features:
- โ Automatic Horizon detection
- โ Supervisor health monitoring
- โ Worker process tracking
- โ Workload balance analysis
๐จ Error Collector
Disabled by default - Tracks application errors and exceptions.
Metrics:
application_errors_total{exception_class, severity, component}
- Application errorsapplication_response_errors_total{http_status, method, route}
- HTTP errorsapplication_critical_errors_total{exception_class, component}
- Critical errors
๐ Additional Collectors
Event Collector
events_fired_total{event_class, status}
- Laravel event tracking
Filesystem Collector
filesystem_operations_total{disk, operation, status}
- File system operations
Mail Collector
mail_sent_total{driver, status, template}
- Email delivery tracking
Enable any collector:
PROMETHEUS_COLLECTOR_[COLLECTOR_NAME]_ENABLED=true
โ๏ธ Configuration
Storage Backends
Choose your preferred storage backend:
'storage' => [ 'driver' => env('PROMETHEUS_STORAGE_DRIVER', 'redis'), // redis, memory, apcu 'redis' => [ 'connection' => env('PROMETHEUS_REDIS_CONNECTION', 'default'), 'prefix' => env('PROMETHEUS_REDIS_PREFIX', 'prometheus_'), ], ],
Global Namespace
Set a global namespace to avoid metric name conflicts:
'namespace' => env('PROMETHEUS_NAMESPACE', ''), // e.g., 'myapp'
Results in metrics like: myapp_http_requests_total
Industry-Standard Defaults
The package comes with optimized industry-standard configurations:
// 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
๐ Security
Protecting the Metrics Endpoint
The package automatically registers a /metrics
endpoint with configurable security:
'metrics_route' => [ 'enabled' => env('PROMETHEUS_METRICS_ROUTE_ENABLED', true), 'path' => env('PROMETHEUS_METRICS_PATH', '/metrics'), 'middleware' => [], // Add security middleware ],
IP Address Restriction
Use the built-in AllowIps
middleware:
'metrics_route' => [ 'middleware' => [\Iamfarhad\Prometheus\Http\Middleware\AllowIps::class], ],
Environment Configuration:
# Supports CIDR notation and multiple IPs
PROMETHEUS_ALLOWED_IPS=127.0.0.1,192.168.1.0/24,10.0.0.100
Features:
- โ IPv4 and IPv6 support
- โ CIDR notation support
- โ Multiple IP ranges
- โ Returns 403 for unauthorized access
Authentication
Add authentication middleware:
'metrics_route' => [ 'middleware' => ['auth.basic', 'throttle:60,1'], ],
Combined Security
For maximum security:
'metrics_route' => [ 'middleware' => [ \Iamfarhad\Prometheus\Http\Middleware\AllowIps::class, 'auth.basic', 'throttle:60,1', ], ],
๐ง Advanced Usage
Custom Metrics with Summary Support
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']);
Middleware Integration
Create custom middleware for application-specific metrics:
<?php 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; } }
๐ Monitoring & Alerting
Prometheus Configuration
Add this scrape configuration to your prometheus.yml
:
scrape_configs: - job_name: 'laravel-app' static_configs: - targets: ['your-app.com:80'] metrics_path: '/metrics' scrape_interval: 15s scrape_timeout: 10s basic_auth: username: 'prometheus' password: 'your-password'
Essential Queries
SLO Monitoring
# Request success rate (SLI)
sum(rate(http_requests_total{status!~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
# 95th percentile response time
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
# Error rate
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
Database Performance
# Slow query detection (p99 > 1s)
histogram_quantile(0.99, sum(rate(database_query_duration_seconds_bucket[5m])) by (le, table, operation)) > 1
# Query rate by operation
sum(rate(database_queries_total[5m])) by (operation)
# Top slowest tables
topk(5, avg(rate(database_query_duration_seconds_sum[5m]) / rate(database_query_duration_seconds_count[5m])) by (table))
Queue Health
# Queue processing rate
sum(rate(queue_jobs_total{status="completed"}[5m])) by (queue)
# Failed job rate
sum(rate(queue_jobs_total{status="failed"}[5m])) / sum(rate(queue_jobs_total[5m]))
# Queue depth
sum(queue_pending_jobs) by (queue)
Grafana Dashboard
Create comprehensive dashboards with:
Panels:
- HTTP request rate and latency percentiles
- Database query performance by operation
- Queue processing metrics and health
- Error rates and exception tracking
- Command execution monitoring
Alerts:
- High error rate (> 1%)
- Slow database queries (p95 > 500ms)
- Queue depth growth
- Failed job rate increase
๐งช Testing
Test Suite Coverage
The package includes comprehensive tests:
- โ Unit Tests: All metric types and collectors
- โ Feature Tests: HTTP endpoints and middleware
- โ Integration Tests: Storage adapters and PromPHP integration
- โ Security Tests: IP filtering and authentication
Testing Custom Metrics
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); } }
๐ Performance Optimization
Best Practices
-
Enable Only Needed Collectors
# Disable unused collectors PROMETHEUS_COLLECTOR_CACHE_ENABLED=false PROMETHEUS_COLLECTOR_EVENTS_ENABLED=false PROMETHEUS_COLLECTOR_FILESYSTEM_ENABLED=false
-
Optimize Storage Backend
# Use Redis for production PROMETHEUS_STORAGE_DRIVER=redis
-
Configure Appropriate Buckets
// Tailor buckets to your use case 'histogram_buckets' => [0.01, 0.05, 0.1, 0.5, 1.0, 2.5, 5.0],
-
Monitor Resource Usage
- Each enabled collector adds minimal overhead (~0.1ms per request)
- Summary metrics use more memory than histograms
- High-cardinality labels increase storage requirements
-
Choose the Right Middleware Strategy
# For most applications (recommended) Use Option 1: PrometheusMiddlewareHelper::register() # For high-performance apps with 1000+ RPS Use Option 4: Route-specific registration # For testing/experimental setups Use Option 3: Automatic registration
Middleware Performance Guide
Choose your middleware registration strategy based on your application requirements:
Application Type | Recommended Option | Reasoning |
---|---|---|
Standard Web/API | Helper Registration (Option 1) | Easy setup, automatic checks, minimal overhead |
High-Traffic API (1000+ RPS) | Route-Specific (Option 4) | Monitor only critical endpoints, reduce overhead |
Microservices | Route-Specific (Option 4) | Focus on service-specific endpoints |
Admin Dashboards | Global Registration (Option 1/2) | Monitor all admin actions |
Public APIs | Route-Specific (Option 4) | Monitor API endpoints, skip static assets |
Development/Testing | Auto Registration (Option 3) | Zero-config for quick testing |
Performance Impact Comparison:
// 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 });
Real-World Example:
// 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 });
Memory Optimization
// 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]
๐ง Troubleshooting
Common Issues
-
Cache Collector Showing False Metrics
- Solution: Cache collector is disabled by default to prevent counting Prometheus's own Redis operations
- Enable only for application cache: Ensure you're using dedicated cache stores
-
High Memory Usage
- Use Redis storage instead of Memory
- Reduce histogram bucket count
- Optimize Summary quantiles and max age
-
Metrics Not Appearing
- Check collector configuration in
config/prometheus.php
- Verify storage backend connectivity
- Check Laravel logs for errors
- Check collector configuration in
-
Slow Response Times
- Optimize histogram bucket configuration
- Use Redis with proper connection pooling
- Consider metric sampling for very high traffic
Debug Mode
Enable comprehensive debug logging to troubleshoot metrics collection:
# Add to .env for debugging
PROMETHEUS_DEBUG=true
Debug Output Examples:
[Prometheus] Prometheus instance created {"namespace":"","registry_class":"Prometheus\\CollectorRegistry"}
[Prometheus] Metric operation: getOrRegisterCounter on http_requests_total {"operation":"getOrRegisterCounter","metric":"http_requests_total","labels":["method","route","status"]}
[Prometheus] Collector HttpRequestCollector: recording request {"method":"GET","route":"api/users","status":200}
[Prometheus] Performance: metrics collection took 15.2ms {"samples_count":12,"duration_ms":15.2}
[Prometheus] Performance: metrics rendering took 8.7ms {"output_size":32451,"duration_ms":8.7}
Debug Features:
- โ Metric Operations: All metric registrations and operations
- โ Collector Activity: Detailed collector behavior tracking
- โ Performance Timing: Collection and rendering performance
- โ Storage Operations: Redis/storage adapter interactions
- โ Request Tracking: HTTP middleware execution flow
- โ Cache Filtering: Cache operation filtering logic
Production Note: Always disable debug mode in production to avoid log bloat.
Middleware Configuration
All available environment variables for easy configuration:
# Core Configuration PROMETHEUS_ENABLED=true PROMETHEUS_NAMESPACE=myapp PROMETHEUS_STORAGE_DRIVER=redis PROMETHEUS_DEBUG=false # Middleware Configuration PROMETHEUS_MIDDLEWARE_AUTO_REGISTER=false # Experimental automatic registration # Collector Settings PROMETHEUS_COLLECTOR_HTTP_ENABLED=true PROMETHEUS_COLLECTOR_DATABASE_ENABLED=true PROMETHEUS_COLLECTOR_COMMAND_ENABLED=true PROMETHEUS_COLLECTOR_CACHE_ENABLED=false # Disabled by default PROMETHEUS_COLLECTOR_QUEUE_ENABLED=true PROMETHEUS_COLLECTOR_ERRORS_ENABLED=false PROMETHEUS_COLLECTOR_EVENTS_ENABLED=false PROMETHEUS_COLLECTOR_FILESYSTEM_ENABLED=false PROMETHEUS_COLLECTOR_MAIL_ENABLED=false PROMETHEUS_COLLECTOR_HORIZON_ENABLED=false # Metrics Route PROMETHEUS_METRICS_ROUTE_ENABLED=true PROMETHEUS_METRICS_PATH=/metrics # Security PROMETHEUS_ALLOWED_IPS=127.0.0.1,192.168.1.0/24 # Storage Configuration PROMETHEUS_REDIS_CONNECTION=default PROMETHEUS_REDIS_PREFIX=metrics_
๐ค Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details.
Development Setup
git clone https://github.com/iamfarhad/laravel-prometheus.git cd laravel-prometheus composer install # Run tests composer test # Check code style composer format # Run static analysis composer analyse
๐ License
This package is open-sourced software licensed under the MIT license.
๐ Support
- ๐ Documentation: Laravel Prometheus Docs
- ๐ Issues: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions
- โญ Star on GitHub: Show your support
๐ Credits
- Author: Farhad Zand
- Built on: PromPHP/prometheus_client_php
- Inspired by: Prometheus community best practices and Laravel ecosystem
๐ Built with โค๏ธ for the Laravel community
Ready for enterprise-grade monitoring with industry-standard SLO tracking! โญ
๐ฏ Key Differentiators
- โ Official PromPHP Integration: Built on the official PHP client
- โ Industry-Standard Buckets: Optimized for real-world SLO monitoring
- โ Complete Metric Types: Counter, Gauge, Histogram, AND Summary with percentiles
- โ Intelligent Filtering: Prevents recursive metric counting issues
- โ Security-First: Built-in IP filtering and authentication support
- โ Production-Ready: Used in enterprise Laravel applications
- โ Comprehensive Testing: Extensive test coverage for reliability
- โ Developer-Friendly: Rich documentation and intuitive API