- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
Performance Monitoring Module
Overview
The Performance Module provides comprehensive performance monitoring and profiling capabilities for the application. It uses a modular middleware-based architecture that allows fine-grained tracking of different application components.
Architecture
Core Components
- PerformanceCollector - Central collection point for all performance metrics
- PerformanceMetric - Individual metric with timing, memory, and statistical data
- PerformanceConfig - Configuration for enabling/disabling tracking per category
- PerformanceReporter - Generates reports in multiple formats (HTML, JSON, Text)
- PerformanceService - Simplified API for application developers
Middleware Components
The module provides specialized middleware for different application layers:
HTTP Layer
RequestPerformanceMiddleware- Tracks overall request/response performanceControllerPerformanceMiddleware- Monitors controller executionRoutingPerformanceMiddleware- Measures route resolution timePerformanceDebugMiddleware- Injects debug reports into HTML responses
Data Layer
DatabasePerformanceMiddleware- Tracks database queries and slow query detectionCachePerformanceMiddleware- Monitors cache operations and hit/miss ratios
Features
Metrics Tracked
-
Request Metrics
- Total request time
- Memory usage (before/after/peak)
- Request success/failure counts
-
Controller Metrics
- Controller execution time
- Action-specific performance
- Controller invocation counts
-
Database Metrics
- Query execution time
- Query type distribution (SELECT, INSERT, UPDATE, etc.)
- Slow query detection
- Query success/failure rates
-
Cache Metrics
- Cache hit/miss ratios
- Operation performance (get, set, delete)
- Data size tracking
-
Routing Metrics
- Route resolution time
- Route pattern matching
- 404 detection
Performance Categories
The system categorizes metrics into logical groups:
SYSTEM- Overall system and request metricsDATABASE- Database-related operationsCACHE- Caching operationsVIEW- Template renderingTEMPLATE- Template processingROUTING- Route resolutionCONTROLLER- Controller executionAPI- API-specific metricsFILESYSTEM- File operationsCUSTOM- User-defined metrics
Configuration
Basic Configuration
$config = new PerformanceConfig(
enabled: true,
httpTracking: true,
databaseTracking: true,
cacheTracking: true,
slowQueryThreshold: 100.0, // ms
detailedReports: false,
excludedPaths: ['/health', '/metrics']
);
Environment-based Configuration
$config = new PerformanceConfig(
enabled: $_ENV['APP_DEBUG'] ?? false,
slowQueryThreshold: (float) ($_ENV['PERFORMANCE_SLOW_QUERY_THRESHOLD'] ?? 100.0),
detailedReports: $_ENV['PERFORMANCE_DETAILED_REPORTS'] === 'true'
);
Usage
Basic Usage with PerformanceService
// Inject the service
public function __construct(
private PerformanceService $performance
) {}
// Measure a function
$result = $this->performance->measure('user_lookup', function() {
return $this->userRepository->findById($id);
}, PerformanceCategory::DATABASE);
// Manual timing
$this->performance->startTiming('complex_calculation');
$result = $this->performComplexCalculation();
$this->performance->endTiming('complex_calculation');
// Record metrics
$this->performance->recordMetric('cache_size', $size, PerformanceCategory::CACHE);
$this->performance->increment('api_calls', 1, PerformanceCategory::API);
Convenience Methods
// Database queries
$users = $this->performance->measureDatabaseQuery('user_select', function() {
return $this->db->select('SELECT * FROM users');
});
// Cache operations
$data = $this->performance->measureCacheOperation('get', function() {
return $this->cache->get('user_data');
});
// View rendering
$html = $this->performance->measureViewRender('user_profile', function() {
return $this->templateEngine->render('user/profile.html');
});
Getting Performance Data
// Get current request stats
$stats = $this->performance->getRequestStats();
// Returns: ['time_ms' => 150.5, 'memory_bytes' => 2048, ...]
// Get slowest operations
$slowest = $this->performance->getSlowestOperations(5);
// Generate reports
$htmlReport = $this->performance->generateReport('html');
$jsonReport = $this->performance->generateReport('json');
$textReport = $this->performance->generateReport('text');
Middleware Integration
HTTP Middleware Setup
Add the middleware to your HTTP middleware stack in order of priority:
// High priority - should run first
$middlewareStack->add(RequestPerformanceMiddleware::class);
// After routing
$middlewareStack->add(RoutingPerformanceMiddleware::class);
// Before controller execution
$middlewareStack->add(ControllerPerformanceMiddleware::class);
// Low priority - should run last for debug output
$middlewareStack->add(PerformanceDebugMiddleware::class);
Database Middleware Setup
// Register with your database layer
$databaseLayer->addMiddleware(DatabasePerformanceMiddleware::class);
Cache Middleware Setup
// Register with your cache layer
$cacheLayer->addMiddleware(CachePerformanceMiddleware::class);
Report Formats
HTML Reports
HTML reports provide a comprehensive, visually appealing overview with:
- Summary statistics
- Category breakdown
- Slowest operations table
- Interactive toggle for debugging
JSON Reports
Perfect for APIs and external monitoring tools:
{
"timestamp": "2024-01-15 10:30:00",
"summary": {
"total_request_time_ms": 245.67,
"total_request_memory_bytes": 4096,
"peak_memory_bytes": 8192,
"metrics_count": 15
},
"categories": {
"database": {
"metrics_count": 3,
"total_time_ms": 89.45,
"total_calls": 12
}
},
"metrics": {
"http_request": {
"category": "system",
"measurements": {
"total_duration_ms": 245.67,
"avg_duration_ms": 245.67
}
}
}
}
Text Reports
Console-friendly format for logs and CLI tools.
Debug Features
Debug Middleware
The PerformanceDebugMiddleware automatically injects performance reports into HTML responses when debug mode is enabled. It adds:
- A floating "Performance" button
- Detailed performance overlay
- Automatic insertion before
</body>tag - Performance headers for AJAX requests
Performance Headers
When not injecting HTML reports, the system adds HTTP headers:
X-Performance-Time: 245.67 ms
X-Performance-Memory: 4.0 KB
X-Performance-Peak-Memory: 8.0 KB
X-Performance-Database: 89.45 ms (12 calls)
Performance Considerations
Overhead
The performance monitoring system is designed to have minimal overhead:
- Disabled tracking adds virtually no performance cost
- Metric collection uses efficient data structures
- Report generation only occurs when requested
Memory Usage
- Metrics are stored in memory during request lifecycle
- Automatic cleanup after request completion
- Configurable limits for metrics per category
Production Usage
For production environments:
$config = new PerformanceConfig(
enabled: false, // Disable in production
// Or enable only critical tracking
enabled: true,
httpTracking: true,
databaseTracking: true,
cacheTracking: false,
detailedReports: false,
excludedPaths: ['/health', '/metrics', '/api/status']
);
Examples
Custom Metrics
class UserService
{
public function __construct(
private PerformanceService $performance
) {}
public function processUserData(array $userData): User
{
return $this->performance->measure('user_processing', function() use ($userData) {
// Validate data
$this->performance->startTiming('user_validation');
$this->validateUserData($userData);
$this->performance->endTiming('user_validation');
// Transform data
$transformedData = $this->performance->measure('user_transformation',
fn() => $this->transformUserData($userData),
PerformanceCategory::CUSTOM
);
// Save to database
return $this->performance->measureDatabaseQuery('user_insert',
fn() => $this->userRepository->create($transformedData)
);
}, PerformanceCategory::CUSTOM);
}
}
Conditional Tracking
public function expensiveOperation(): Result
{
if ($this->performance->isEnabled()) {
return $this->performance->measure('expensive_op',
fn() => $this->doExpensiveOperation(),
PerformanceCategory::CUSTOM
);
}
return $this->doExpensiveOperation();
}
Troubleshooting
Common Issues
- Missing metrics: Ensure middleware is properly registered
- Memory issues: Check
maxMetricsPerCategoryconfiguration - Slow performance: Disable detailed reports in production
- Missing HTML reports: Verify
PerformanceDebugMiddlewareis last in chain
Debug Information
// Check if tracking is enabled
if (!$performance->isEnabled()) {
echo "Performance tracking is disabled\n";
}
// Get current configuration
$config = $performance->getConfig();
echo "Database tracking: " . ($config->databaseTracking ? 'enabled' : 'disabled') . "\n";
// Check collected metrics
$metrics = $performance->getMetrics();
echo "Collected " . count($metrics) . " metrics\n";