Add complete enterprise-level reliability, security, and performance systems: ## Core Monitoring Systems - **Health Monitor**: 8 automated health checks with email alerts and REST API - **Error Recovery**: 4 recovery strategies (retry, fallback, circuit breaker, graceful failure) - **Security Monitor**: Real-time threat detection with automatic IP blocking - **Performance Monitor**: Performance tracking with automated benchmarks and alerts ## Data Protection & Optimization - **Backup Manager**: Automated backups with encryption, compression, and disaster recovery - **Cache Optimizer**: Intelligent caching with 3 strategies and 5 specialized cache groups ## Enterprise Features - Automated scheduling with WordPress cron integration - Admin dashboards for all systems under Tools menu - REST API endpoints for external monitoring - WP-CLI commands for automation and CI/CD - Comprehensive documentation (docs/MONITORING-SYSTEMS.md) - Emergency response systems with immediate email alerts - Circuit breaker pattern for external service failures - Smart cache warming and invalidation - Database query caching and optimization - File integrity monitoring - Performance degradation detection ## Integration - Plugin architecture updated with proper initialization - Singleton pattern for all monitoring classes - WordPress hooks and filters integration - Background job processing system - Comprehensive error handling and logging Systems provide enterprise-grade reliability with automated threat response, proactive performance monitoring, and complete disaster recovery capabilities. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			951 lines
		
	
	
		
			No EOL
		
	
	
		
			34 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			951 lines
		
	
	
		
			No EOL
		
	
	
		
			34 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * HVAC Performance Monitor
 | |
|  * 
 | |
|  * Provides real-time performance monitoring, benchmarking, and automated
 | |
|  * alerts for slow queries, memory leaks, and performance degradation
 | |
|  * 
 | |
|  * @package HVAC_Community_Events
 | |
|  * @since 1.0.8
 | |
|  */
 | |
| 
 | |
| if (!defined('ABSPATH')) {
 | |
|     exit;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * HVAC_Performance_Monitor class
 | |
|  */
 | |
| class HVAC_Performance_Monitor {
 | |
|     
 | |
|     /**
 | |
|      * Performance thresholds
 | |
|      */
 | |
|     const THRESHOLDS = [
 | |
|         'slow_query_time' => 2.0,        // 2 seconds
 | |
|         'memory_usage_mb' => 128,        // 128 MB
 | |
|         'page_load_time' => 3.0,         // 3 seconds
 | |
|         'cpu_usage_percent' => 80,       // 80%
 | |
|         'db_query_count' => 100,         // 100 queries per request
 | |
|         'cache_hit_rate' => 70           // 70% cache hit rate
 | |
|     ];
 | |
|     
 | |
|     /**
 | |
|      * Performance metrics
 | |
|      */
 | |
|     private static $metrics = [];
 | |
|     private static $query_log = [];
 | |
|     private static $memory_checkpoints = [];
 | |
|     private static $start_time;
 | |
|     private static $start_memory;
 | |
|     
 | |
|     /**
 | |
|      * Alert settings
 | |
|      */
 | |
|     private static $alert_settings = [
 | |
|         'email_alerts' => true,
 | |
|         'slack_webhook' => '',
 | |
|         'alert_threshold' => 3,     // Number of incidents before alert
 | |
|         'alert_cooldown' => 1800,   // 30 minutes between alerts
 | |
|         'benchmark_frequency' => 'daily'
 | |
|     ];
 | |
|     
 | |
|     /**
 | |
|      * Initialize performance monitoring
 | |
|      */
 | |
|     public static function init() {
 | |
|         // Load settings
 | |
|         self::$alert_settings = array_merge(
 | |
|             self::$alert_settings, 
 | |
|             get_option('hvac_performance_settings', [])
 | |
|         );
 | |
|         
 | |
|         // Set initial measurements
 | |
|         self::$start_time = microtime(true);
 | |
|         self::$start_memory = memory_get_usage(true);
 | |
|         
 | |
|         // Hook into WordPress performance points
 | |
|         add_action('init', [__CLASS__, 'start_monitoring'], 0);
 | |
|         add_action('wp_loaded', [__CLASS__, 'checkpoint_loaded']);
 | |
|         add_action('wp_footer', [__CLASS__, 'checkpoint_footer']);
 | |
|         add_action('shutdown', [__CLASS__, 'finalize_monitoring']);
 | |
|         
 | |
|         // Database query monitoring
 | |
|         add_filter('query', [__CLASS__, 'monitor_query']);
 | |
|         add_action('wp_db_query', [__CLASS__, 'log_query_completion']);
 | |
|         
 | |
|         // Memory monitoring
 | |
|         add_action('wp_loaded', [__CLASS__, 'checkpoint_memory']);
 | |
|         add_action('wp_footer', [__CLASS__, 'checkpoint_memory']);
 | |
|         
 | |
|         // Schedule performance benchmarks
 | |
|         if (!wp_next_scheduled('hvac_performance_benchmark')) {
 | |
|             $frequency = self::$alert_settings['benchmark_frequency'];
 | |
|             wp_schedule_event(time(), $frequency, 'hvac_performance_benchmark');
 | |
|         }
 | |
|         
 | |
|         add_action('hvac_performance_benchmark', [__CLASS__, 'run_performance_benchmark']);
 | |
|         
 | |
|         // Admin interface
 | |
|         if (is_admin()) {
 | |
|             add_action('admin_menu', [__CLASS__, 'add_admin_menu']);
 | |
|             add_action('wp_ajax_hvac_performance_action', [__CLASS__, 'handle_performance_action']);
 | |
|             add_action('admin_bar_menu', [__CLASS__, 'add_admin_bar_stats'], 999);
 | |
|         }
 | |
|         
 | |
|         // REST API endpoints
 | |
|         add_action('rest_api_init', [__CLASS__, 'register_rest_endpoints']);
 | |
|         
 | |
|         // WP-CLI integration
 | |
|         if (defined('WP_CLI') && WP_CLI) {
 | |
|             WP_CLI::add_command('hvac performance', [__CLASS__, 'wp_cli_performance']);
 | |
|         }
 | |
|         
 | |
|         // Emergency alerts for critical performance issues
 | |
|         add_action('hvac_critical_performance_issue', [__CLASS__, 'handle_critical_issue']);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Start monitoring
 | |
|      */
 | |
|     public static function start_monitoring() {
 | |
|         // Only monitor frontend requests and specific admin pages
 | |
|         if (!self::should_monitor()) {
 | |
|             return;
 | |
|         }
 | |
|         
 | |
|         self::$metrics['start_time'] = microtime(true);
 | |
|         self::$metrics['start_memory'] = memory_get_usage(true);
 | |
|         self::$metrics['query_count'] = 0;
 | |
|         self::$metrics['slow_queries'] = [];
 | |
|         
 | |
|         // Set up query monitoring
 | |
|         global $wpdb;
 | |
|         $wpdb->save_queries = true;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Check if we should monitor this request
 | |
|      */
 | |
|     private static function should_monitor() {
 | |
|         // Skip monitoring for certain requests
 | |
|         if (wp_doing_ajax() || wp_doing_cron() || (defined('WP_CLI') && WP_CLI)) {
 | |
|             return false;
 | |
|         }
 | |
|         
 | |
|         // Skip for admin unless it's a plugin page
 | |
|         if (is_admin()) {
 | |
|             $screen = get_current_screen();
 | |
|             if (!$screen || strpos($screen->id, 'hvac') === false) {
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         // Skip for REST API unless it's our endpoints
 | |
|         if (defined('REST_REQUEST') && REST_REQUEST) {
 | |
|             $request_uri = $_SERVER['REQUEST_URI'] ?? '';
 | |
|             if (strpos($request_uri, '/hvac/v1/') === false) {
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         return true;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Monitor database queries
 | |
|      */
 | |
|     public static function monitor_query($query) {
 | |
|         if (!isset(self::$metrics['start_time'])) {
 | |
|             return $query;
 | |
|         }
 | |
|         
 | |
|         $start_time = microtime(true);
 | |
|         
 | |
|         // Store query info for monitoring
 | |
|         self::$query_log[] = [
 | |
|             'query' => $query,
 | |
|             'start_time' => $start_time,
 | |
|             'backtrace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5)
 | |
|         ];
 | |
|         
 | |
|         return $query;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Log query completion
 | |
|      */
 | |
|     public static function log_query_completion($result) {
 | |
|         if (empty(self::$query_log)) {
 | |
|             return;
 | |
|         }
 | |
|         
 | |
|         $current_query = &self::$query_log[count(self::$query_log) - 1];
 | |
|         $execution_time = microtime(true) - $current_query['start_time'];
 | |
|         $current_query['execution_time'] = $execution_time;
 | |
|         
 | |
|         self::$metrics['query_count']++;
 | |
|         
 | |
|         // Check for slow queries
 | |
|         if ($execution_time > self::THRESHOLDS['slow_query_time']) {
 | |
|             self::$metrics['slow_queries'][] = [
 | |
|                 'query' => substr($current_query['query'], 0, 200),
 | |
|                 'time' => $execution_time,
 | |
|                 'backtrace' => $current_query['backtrace']
 | |
|             ];
 | |
|             
 | |
|             // Log slow query
 | |
|             HVAC_Logger::warning(
 | |
|                 "Slow query detected: {$execution_time}s - " . substr($current_query['query'], 0, 100),
 | |
|                 'Performance Monitor'
 | |
|             );
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Memory checkpoint
 | |
|      */
 | |
|     public static function checkpoint_memory($checkpoint = null) {
 | |
|         if (!isset(self::$metrics['start_time'])) {
 | |
|             return;
 | |
|         }
 | |
|         
 | |
|         $current_memory = memory_get_usage(true);
 | |
|         $peak_memory = memory_get_peak_usage(true);
 | |
|         
 | |
|         if ($checkpoint === null) {
 | |
|             $checkpoint = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0]['function'];
 | |
|         }
 | |
|         
 | |
|         self::$memory_checkpoints[] = [
 | |
|             'checkpoint' => $checkpoint,
 | |
|             'time' => microtime(true),
 | |
|             'current_memory' => $current_memory,
 | |
|             'peak_memory' => $peak_memory,
 | |
|             'memory_mb' => round($current_memory / 1024 / 1024, 2)
 | |
|         ];
 | |
|         
 | |
|         // Check for memory threshold breach
 | |
|         $memory_mb = $current_memory / 1024 / 1024;
 | |
|         if ($memory_mb > self::THRESHOLDS['memory_usage_mb']) {
 | |
|             HVAC_Logger::warning(
 | |
|                 "High memory usage detected: {$memory_mb}MB at checkpoint: $checkpoint",
 | |
|                 'Performance Monitor'
 | |
|             );
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Checkpoint: WordPress loaded
 | |
|      */
 | |
|     public static function checkpoint_loaded() {
 | |
|         self::checkpoint_memory('wp_loaded');
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Checkpoint: Footer
 | |
|      */
 | |
|     public static function checkpoint_footer() {
 | |
|         self::checkpoint_memory('wp_footer');
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Finalize monitoring
 | |
|      */
 | |
|     public static function finalize_monitoring() {
 | |
|         if (!isset(self::$metrics['start_time'])) {
 | |
|             return;
 | |
|         }
 | |
|         
 | |
|         $end_time = microtime(true);
 | |
|         $total_time = $end_time - self::$metrics['start_time'];
 | |
|         $peak_memory = memory_get_peak_usage(true);
 | |
|         $peak_memory_mb = $peak_memory / 1024 / 1024;
 | |
|         
 | |
|         // Finalize metrics
 | |
|         self::$metrics['total_time'] = $total_time;
 | |
|         self::$metrics['peak_memory'] = $peak_memory;
 | |
|         self::$metrics['peak_memory_mb'] = $peak_memory_mb;
 | |
|         self::$metrics['timestamp'] = time();
 | |
|         
 | |
|         // Calculate cache hit rate if object cache is available
 | |
|         if (function_exists('wp_cache_get_stats')) {
 | |
|             $cache_stats = wp_cache_get_stats();
 | |
|             if (isset($cache_stats['cache_hits']) && isset($cache_stats['cache_misses'])) {
 | |
|                 $total_requests = $cache_stats['cache_hits'] + $cache_stats['cache_misses'];
 | |
|                 if ($total_requests > 0) {
 | |
|                     self::$metrics['cache_hit_rate'] = ($cache_stats['cache_hits'] / $total_requests) * 100;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         // Check thresholds and send alerts
 | |
|         self::check_performance_thresholds();
 | |
|         
 | |
|         // Store metrics for analysis
 | |
|         self::store_performance_metrics();
 | |
|         
 | |
|         // Log performance summary for slow requests
 | |
|         if ($total_time > self::THRESHOLDS['page_load_time']) {
 | |
|             HVAC_Logger::warning(
 | |
|                 "Slow page load: {$total_time}s, Memory: {$peak_memory_mb}MB, Queries: " . self::$metrics['query_count'],
 | |
|                 'Performance Monitor'
 | |
|             );
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Check performance thresholds
 | |
|      */
 | |
|     private static function check_performance_thresholds() {
 | |
|         $alerts = [];
 | |
|         
 | |
|         // Check page load time
 | |
|         if (self::$metrics['total_time'] > self::THRESHOLDS['page_load_time']) {
 | |
|             $alerts[] = [
 | |
|                 'type' => 'slow_page_load',
 | |
|                 'message' => 'Page load time exceeded threshold',
 | |
|                 'value' => self::$metrics['total_time'],
 | |
|                 'threshold' => self::THRESHOLDS['page_load_time']
 | |
|             ];
 | |
|         }
 | |
|         
 | |
|         // Check memory usage
 | |
|         if (self::$metrics['peak_memory_mb'] > self::THRESHOLDS['memory_usage_mb']) {
 | |
|             $alerts[] = [
 | |
|                 'type' => 'high_memory_usage',
 | |
|                 'message' => 'Memory usage exceeded threshold',
 | |
|                 'value' => self::$metrics['peak_memory_mb'],
 | |
|                 'threshold' => self::THRESHOLDS['memory_usage_mb']
 | |
|             ];
 | |
|         }
 | |
|         
 | |
|         // Check query count
 | |
|         if (self::$metrics['query_count'] > self::THRESHOLDS['db_query_count']) {
 | |
|             $alerts[] = [
 | |
|                 'type' => 'excessive_queries',
 | |
|                 'message' => 'Database query count exceeded threshold',
 | |
|                 'value' => self::$metrics['query_count'],
 | |
|                 'threshold' => self::THRESHOLDS['db_query_count']
 | |
|             ];
 | |
|         }
 | |
|         
 | |
|         // Check slow queries
 | |
|         if (count(self::$metrics['slow_queries']) > 0) {
 | |
|             $alerts[] = [
 | |
|                 'type' => 'slow_queries',
 | |
|                 'message' => 'Slow queries detected',
 | |
|                 'value' => count(self::$metrics['slow_queries']),
 | |
|                 'threshold' => 0
 | |
|             ];
 | |
|         }
 | |
|         
 | |
|         // Check cache hit rate
 | |
|         if (isset(self::$metrics['cache_hit_rate']) && 
 | |
|             self::$metrics['cache_hit_rate'] < self::THRESHOLDS['cache_hit_rate']) {
 | |
|             $alerts[] = [
 | |
|                 'type' => 'low_cache_hit_rate',
 | |
|                 'message' => 'Cache hit rate below threshold',
 | |
|                 'value' => self::$metrics['cache_hit_rate'],
 | |
|                 'threshold' => self::THRESHOLDS['cache_hit_rate']
 | |
|             ];
 | |
|         }
 | |
|         
 | |
|         // Process alerts
 | |
|         if (!empty($alerts)) {
 | |
|             self::process_performance_alerts($alerts);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Process performance alerts
 | |
|      */
 | |
|     private static function process_performance_alerts($alerts) {
 | |
|         // Count recent alerts to avoid spam
 | |
|         $recent_alerts = self::get_recent_alerts(1800); // Last 30 minutes
 | |
|         
 | |
|         if (count($recent_alerts) >= self::$alert_settings['alert_threshold']) {
 | |
|             return; // Cooldown period
 | |
|         }
 | |
|         
 | |
|         // Store alerts
 | |
|         $stored_alerts = get_option('hvac_performance_alerts', []);
 | |
|         foreach ($alerts as $alert) {
 | |
|             $alert['timestamp'] = time();
 | |
|             $alert['request_uri'] = $_SERVER['REQUEST_URI'] ?? '';
 | |
|             $alert['user_agent'] = $_SERVER['HTTP_USER_AGENT'] ?? '';
 | |
|             $stored_alerts[] = $alert;
 | |
|         }
 | |
|         
 | |
|         // Keep only last 1000 alerts
 | |
|         if (count($stored_alerts) > 1000) {
 | |
|             $stored_alerts = array_slice($stored_alerts, -1000);
 | |
|         }
 | |
|         
 | |
|         update_option('hvac_performance_alerts', $stored_alerts);
 | |
|         
 | |
|         // Send notifications
 | |
|         if (self::$alert_settings['email_alerts']) {
 | |
|             self::send_performance_alert_email($alerts);
 | |
|         }
 | |
|         
 | |
|         // Check for critical issues
 | |
|         $critical_alerts = array_filter($alerts, function($alert) {
 | |
|             return $alert['type'] === 'slow_page_load' && $alert['value'] > 10 ||
 | |
|                    $alert['type'] === 'high_memory_usage' && $alert['value'] > 256 ||
 | |
|                    $alert['type'] === 'excessive_queries' && $alert['value'] > 500;
 | |
|         });
 | |
|         
 | |
|         if (!empty($critical_alerts)) {
 | |
|             do_action('hvac_critical_performance_issue', $critical_alerts);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Get recent alerts
 | |
|      */
 | |
|     private static function get_recent_alerts($timeframe = 1800) {
 | |
|         $stored_alerts = get_option('hvac_performance_alerts', []);
 | |
|         $cutoff_time = time() - $timeframe;
 | |
|         
 | |
|         return array_filter($stored_alerts, function($alert) use ($cutoff_time) {
 | |
|             return $alert['timestamp'] >= $cutoff_time;
 | |
|         });
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Send performance alert email
 | |
|      */
 | |
|     private static function send_performance_alert_email($alerts) {
 | |
|         $admin_email = get_option('admin_email');
 | |
|         $site_name = get_bloginfo('name');
 | |
|         
 | |
|         $subject = "[$site_name] Performance Alert";
 | |
|         $message = "Performance issues detected on $site_name:\n\n";
 | |
|         
 | |
|         foreach ($alerts as $alert) {
 | |
|             $message .= "• {$alert['message']}\n";
 | |
|             $message .= "  Value: {$alert['value']} (Threshold: {$alert['threshold']})\n\n";
 | |
|         }
 | |
|         
 | |
|         $message .= "Request: " . ($_SERVER['REQUEST_URI'] ?? 'Unknown') . "\n";
 | |
|         $message .= "Time: " . date('Y-m-d H:i:s') . "\n";
 | |
|         $message .= "\nCheck the performance monitor for detailed analysis.";
 | |
|         
 | |
|         wp_mail($admin_email, $subject, $message);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Store performance metrics
 | |
|      */
 | |
|     private static function store_performance_metrics() {
 | |
|         // Store in database for trend analysis
 | |
|         global $wpdb;
 | |
|         
 | |
|         $metrics_data = [
 | |
|             'timestamp' => time(),
 | |
|             'page_load_time' => self::$metrics['total_time'],
 | |
|             'peak_memory_mb' => self::$metrics['peak_memory_mb'],
 | |
|             'query_count' => self::$metrics['query_count'],
 | |
|             'slow_query_count' => count(self::$metrics['slow_queries']),
 | |
|             'cache_hit_rate' => self::$metrics['cache_hit_rate'] ?? null,
 | |
|             'request_uri' => $_SERVER['REQUEST_URI'] ?? '',
 | |
|         ];
 | |
|         
 | |
|         // Store in options (simple approach - could use custom table for high-volume sites)
 | |
|         $stored_metrics = get_option('hvac_performance_metrics', []);
 | |
|         $stored_metrics[] = $metrics_data;
 | |
|         
 | |
|         // Keep only last 1000 metrics
 | |
|         if (count($stored_metrics) > 1000) {
 | |
|             $stored_metrics = array_slice($stored_metrics, -1000);
 | |
|         }
 | |
|         
 | |
|         update_option('hvac_performance_metrics', $stored_metrics);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Run performance benchmark
 | |
|      */
 | |
|     public static function run_performance_benchmark() {
 | |
|         $benchmark_results = [
 | |
|             'timestamp' => time(),
 | |
|             'database_benchmark' => self::benchmark_database(),
 | |
|             'memory_benchmark' => self::benchmark_memory(),
 | |
|             'cache_benchmark' => self::benchmark_cache(),
 | |
|             'file_io_benchmark' => self::benchmark_file_io()
 | |
|         ];
 | |
|         
 | |
|         // Store benchmark results
 | |
|         update_option('hvac_performance_benchmark', $benchmark_results);
 | |
|         
 | |
|         HVAC_Logger::info(
 | |
|             'Performance benchmark completed: ' . json_encode($benchmark_results),
 | |
|             'Performance Monitor'
 | |
|         );
 | |
|         
 | |
|         // Check if performance has degraded
 | |
|         $previous_benchmark = get_option('hvac_previous_benchmark', null);
 | |
|         if ($previous_benchmark) {
 | |
|             $degradation = self::check_performance_degradation($previous_benchmark, $benchmark_results);
 | |
|             if ($degradation) {
 | |
|                 self::send_performance_alert_email([
 | |
|                     [
 | |
|                         'type' => 'performance_degradation',
 | |
|                         'message' => 'Performance degradation detected',
 | |
|                         'details' => $degradation
 | |
|                     ]
 | |
|                 ]);
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         update_option('hvac_previous_benchmark', $benchmark_results);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Benchmark database performance
 | |
|      */
 | |
|     private static function benchmark_database() {
 | |
|         global $wpdb;
 | |
|         
 | |
|         $start_time = microtime(true);
 | |
|         
 | |
|         // Simple query benchmark
 | |
|         $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->posts}");
 | |
|         $simple_query_time = microtime(true) - $start_time;
 | |
|         
 | |
|         // Complex query benchmark
 | |
|         $start_time = microtime(true);
 | |
|         $wpdb->get_results("
 | |
|             SELECT p.*, pm.meta_value 
 | |
|             FROM {$wpdb->posts} p 
 | |
|             LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id 
 | |
|             WHERE p.post_type = 'post' 
 | |
|             AND p.post_status = 'publish' 
 | |
|             LIMIT 10
 | |
|         ");
 | |
|         $complex_query_time = microtime(true) - $start_time;
 | |
|         
 | |
|         return [
 | |
|             'simple_query_time' => round($simple_query_time, 4),
 | |
|             'complex_query_time' => round($complex_query_time, 4)
 | |
|         ];
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Benchmark memory performance
 | |
|      */
 | |
|     private static function benchmark_memory() {
 | |
|         $start_memory = memory_get_usage();
 | |
|         
 | |
|         // Create test data
 | |
|         $test_data = [];
 | |
|         for ($i = 0; $i < 1000; $i++) {
 | |
|             $test_data[] = str_repeat('x', 1000);
 | |
|         }
 | |
|         
 | |
|         $peak_memory = memory_get_usage();
 | |
|         $memory_used = $peak_memory - $start_memory;
 | |
|         
 | |
|         unset($test_data);
 | |
|         
 | |
|         return [
 | |
|             'memory_used_mb' => round($memory_used / 1024 / 1024, 2),
 | |
|             'peak_memory_mb' => round(memory_get_peak_usage() / 1024 / 1024, 2)
 | |
|         ];
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Benchmark cache performance
 | |
|      */
 | |
|     private static function benchmark_cache() {
 | |
|         $iterations = 100;
 | |
|         $test_key = 'hvac_performance_test_' . time();
 | |
|         $test_data = str_repeat('x', 1000);
 | |
|         
 | |
|         // Write benchmark
 | |
|         $start_time = microtime(true);
 | |
|         for ($i = 0; $i < $iterations; $i++) {
 | |
|             wp_cache_set($test_key . $i, $test_data, 'hvac_perf_test', 60);
 | |
|         }
 | |
|         $write_time = microtime(true) - $start_time;
 | |
|         
 | |
|         // Read benchmark
 | |
|         $start_time = microtime(true);
 | |
|         for ($i = 0; $i < $iterations; $i++) {
 | |
|             wp_cache_get($test_key . $i, 'hvac_perf_test');
 | |
|         }
 | |
|         $read_time = microtime(true) - $start_time;
 | |
|         
 | |
|         // Cleanup
 | |
|         for ($i = 0; $i < $iterations; $i++) {
 | |
|             wp_cache_delete($test_key . $i, 'hvac_perf_test');
 | |
|         }
 | |
|         
 | |
|         return [
 | |
|             'write_time' => round($write_time, 4),
 | |
|             'read_time' => round($read_time, 4),
 | |
|             'writes_per_second' => round($iterations / $write_time, 2),
 | |
|             'reads_per_second' => round($iterations / $read_time, 2)
 | |
|         ];
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Benchmark file I/O performance
 | |
|      */
 | |
|     private static function benchmark_file_io() {
 | |
|         $upload_dir = wp_upload_dir()['basedir'];
 | |
|         $test_file = $upload_dir . '/hvac_perf_test.txt';
 | |
|         $test_data = str_repeat('Performance test data. ', 1000);
 | |
|         
 | |
|         // Write benchmark
 | |
|         $start_time = microtime(true);
 | |
|         file_put_contents($test_file, $test_data);
 | |
|         $write_time = microtime(true) - $start_time;
 | |
|         
 | |
|         // Read benchmark
 | |
|         $start_time = microtime(true);
 | |
|         $read_data = file_get_contents($test_file);
 | |
|         $read_time = microtime(true) - $start_time;
 | |
|         
 | |
|         // Cleanup
 | |
|         if (file_exists($test_file)) {
 | |
|             unlink($test_file);
 | |
|         }
 | |
|         
 | |
|         return [
 | |
|             'write_time' => round($write_time, 4),
 | |
|             'read_time' => round($read_time, 4),
 | |
|             'data_size_kb' => round(strlen($test_data) / 1024, 2)
 | |
|         ];
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Check performance degradation
 | |
|      */
 | |
|     private static function check_performance_degradation($previous, $current) {
 | |
|         $degradation_threshold = 0.5; // 50% increase
 | |
|         $issues = [];
 | |
|         
 | |
|         // Check database performance
 | |
|         $db_degradation = ($current['database_benchmark']['complex_query_time'] / 
 | |
|                           $previous['database_benchmark']['complex_query_time']) - 1;
 | |
|         if ($db_degradation > $degradation_threshold) {
 | |
|             $issues[] = "Database queries " . round($db_degradation * 100, 1) . "% slower";
 | |
|         }
 | |
|         
 | |
|         // Check cache performance
 | |
|         $cache_degradation = ($current['cache_benchmark']['read_time'] / 
 | |
|                              $previous['cache_benchmark']['read_time']) - 1;
 | |
|         if ($cache_degradation > $degradation_threshold) {
 | |
|             $issues[] = "Cache reads " . round($cache_degradation * 100, 1) . "% slower";
 | |
|         }
 | |
|         
 | |
|         return empty($issues) ? false : $issues;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Handle critical performance issues
 | |
|      */
 | |
|     public static function handle_critical_issue($alerts) {
 | |
|         // Log critical issue
 | |
|         HVAC_Logger::error(
 | |
|             'Critical performance issue detected: ' . json_encode($alerts),
 | |
|             'Performance Monitor'
 | |
|         );
 | |
|         
 | |
|         // Send immediate alert
 | |
|         $admin_email = get_option('admin_email');
 | |
|         $site_name = get_bloginfo('name');
 | |
|         
 | |
|         $subject = "[$site_name] CRITICAL Performance Issue";
 | |
|         $message = "CRITICAL performance issues detected:\n\n";
 | |
|         
 | |
|         foreach ($alerts as $alert) {
 | |
|             $message .= "• {$alert['message']}: {$alert['value']}\n";
 | |
|         }
 | |
|         
 | |
|         $message .= "\nImmediate attention required!";
 | |
|         
 | |
|         wp_mail($admin_email, $subject, $message);
 | |
|         
 | |
|         // Trigger error recovery if available
 | |
|         if (class_exists('HVAC_Error_Recovery')) {
 | |
|             do_action('hvac_operation_failed', 'performance', 'Critical performance degradation', $alerts);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Get performance statistics
 | |
|      */
 | |
|     public static function get_performance_stats() {
 | |
|         $metrics = get_option('hvac_performance_metrics', []);
 | |
|         $alerts = get_option('hvac_performance_alerts', []);
 | |
|         $benchmark = get_option('hvac_performance_benchmark', null);
 | |
|         
 | |
|         if (empty($metrics)) {
 | |
|             return [
 | |
|                 'avg_page_load_time' => 0,
 | |
|                 'avg_memory_usage' => 0,
 | |
|                 'avg_query_count' => 0,
 | |
|                 'total_requests' => 0,
 | |
|                 'recent_alerts' => 0,
 | |
|                 'benchmark' => null
 | |
|             ];
 | |
|         }
 | |
|         
 | |
|         $total_requests = count($metrics);
 | |
|         $recent_cutoff = time() - 86400; // Last 24 hours
 | |
|         
 | |
|         // Calculate averages
 | |
|         $avg_page_load_time = array_sum(array_column($metrics, 'page_load_time')) / $total_requests;
 | |
|         $avg_memory_usage = array_sum(array_column($metrics, 'peak_memory_mb')) / $total_requests;
 | |
|         $avg_query_count = array_sum(array_column($metrics, 'query_count')) / $total_requests;
 | |
|         
 | |
|         // Recent alerts
 | |
|         $recent_alerts = count(array_filter($alerts, function($alert) use ($recent_cutoff) {
 | |
|             return $alert['timestamp'] >= $recent_cutoff;
 | |
|         }));
 | |
|         
 | |
|         return [
 | |
|             'avg_page_load_time' => round($avg_page_load_time, 3),
 | |
|             'avg_memory_usage' => round($avg_memory_usage, 2),
 | |
|             'avg_query_count' => round($avg_query_count, 1),
 | |
|             'total_requests' => $total_requests,
 | |
|             'recent_alerts' => $recent_alerts,
 | |
|             'benchmark' => $benchmark
 | |
|         ];
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Add admin menu
 | |
|      */
 | |
|     public static function add_admin_menu() {
 | |
|         if (current_user_can('manage_options')) {
 | |
|             add_management_page(
 | |
|                 'HVAC Performance Monitor',
 | |
|                 'HVAC Performance',
 | |
|                 'manage_options',
 | |
|                 'hvac-performance-monitor',
 | |
|                 [__CLASS__, 'admin_page']
 | |
|             );
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Add admin bar stats
 | |
|      */
 | |
|     public static function add_admin_bar_stats($admin_bar) {
 | |
|         if (!current_user_can('manage_options') || !isset(self::$metrics['start_time'])) {
 | |
|             return;
 | |
|         }
 | |
|         
 | |
|         $current_memory = round(memory_get_usage(true) / 1024 / 1024, 1);
 | |
|         $query_count = get_num_queries();
 | |
|         
 | |
|         $admin_bar->add_node([
 | |
|             'id' => 'hvac-performance',
 | |
|             'title' => "HVAC: {$current_memory}MB | {$query_count}Q",
 | |
|             'href' => admin_url('tools.php?page=hvac-performance-monitor')
 | |
|         ]);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Admin page
 | |
|      */
 | |
|     public static function admin_page() {
 | |
|         $stats = self::get_performance_stats();
 | |
|         $recent_alerts = array_slice(get_option('hvac_performance_alerts', []), -20, 20, true);
 | |
|         $current_metrics = self::$metrics;
 | |
|         
 | |
|         ?>
 | |
|         <div class="wrap">
 | |
|             <h1>HVAC Performance Monitor</h1>
 | |
|             
 | |
|             <div class="performance-overview">
 | |
|                 <div class="card">
 | |
|                     <h2>Performance Overview</h2>
 | |
|                     <p><strong>Average Page Load Time:</strong> <?php echo $stats['avg_page_load_time']; ?>s</p>
 | |
|                     <p><strong>Average Memory Usage:</strong> <?php echo $stats['avg_memory_usage']; ?>MB</p>
 | |
|                     <p><strong>Average Query Count:</strong> <?php echo $stats['avg_query_count']; ?></p>
 | |
|                     <p><strong>Total Requests Monitored:</strong> <?php echo $stats['total_requests']; ?></p>
 | |
|                     <p><strong>Recent Alerts (24h):</strong> <?php echo $stats['recent_alerts']; ?></p>
 | |
|                 </div>
 | |
|                 
 | |
|                 <?php if (!empty($current_metrics)): ?>
 | |
|                 <div class="card">
 | |
|                     <h2>Current Request Stats</h2>
 | |
|                     <p><strong>Load Time:</strong> <?php echo isset($current_metrics['total_time']) ? round($current_metrics['total_time'], 3) . 's' : 'In progress'; ?></p>
 | |
|                     <p><strong>Peak Memory:</strong> <?php echo isset($current_metrics['peak_memory_mb']) ? round($current_metrics['peak_memory_mb'], 2) . 'MB' : round(memory_get_peak_usage(true) / 1024 / 1024, 2) . 'MB'; ?></p>
 | |
|                     <p><strong>Queries:</strong> <?php echo $current_metrics['query_count'] ?? get_num_queries(); ?></p>
 | |
|                     <p><strong>Slow Queries:</strong> <?php echo count($current_metrics['slow_queries'] ?? []); ?></p>
 | |
|                 </div>
 | |
|                 <?php endif; ?>
 | |
|                 
 | |
|                 <?php if ($stats['benchmark']): ?>
 | |
|                 <div class="card">
 | |
|                     <h2>Latest Benchmark</h2>
 | |
|                     <p><strong>Date:</strong> <?php echo date('Y-m-d H:i:s', $stats['benchmark']['timestamp']); ?></p>
 | |
|                     <p><strong>Database (simple):</strong> <?php echo $stats['benchmark']['database_benchmark']['simple_query_time']; ?>s</p>
 | |
|                     <p><strong>Database (complex):</strong> <?php echo $stats['benchmark']['database_benchmark']['complex_query_time']; ?>s</p>
 | |
|                     <p><strong>Cache Reads/sec:</strong> <?php echo $stats['benchmark']['cache_benchmark']['reads_per_second']; ?></p>
 | |
|                     <p>
 | |
|                         <button type="button" id="run-benchmark" class="button button-primary">Run New Benchmark</button>
 | |
|                     </p>
 | |
|                 </div>
 | |
|                 <?php endif; ?>
 | |
|             </div>
 | |
|             
 | |
|             <div class="card">
 | |
|                 <h2>Recent Performance Alerts</h2>
 | |
|                 <table class="wp-list-table widefat fixed striped">
 | |
|                     <thead>
 | |
|                         <tr>
 | |
|                             <th>Time</th>
 | |
|                             <th>Type</th>
 | |
|                             <th>Message</th>
 | |
|                             <th>Value</th>
 | |
|                             <th>Threshold</th>
 | |
|                         </tr>
 | |
|                     </thead>
 | |
|                     <tbody>
 | |
|                         <?php if (empty($recent_alerts)): ?>
 | |
|                         <tr>
 | |
|                             <td colspan="5">No recent performance alerts</td>
 | |
|                         </tr>
 | |
|                         <?php else: ?>
 | |
|                         <?php foreach (array_reverse($recent_alerts) as $alert): ?>
 | |
|                         <tr>
 | |
|                             <td><?php echo date('Y-m-d H:i:s', $alert['timestamp']); ?></td>
 | |
|                             <td><?php echo esc_html($alert['type']); ?></td>
 | |
|                             <td><?php echo esc_html($alert['message']); ?></td>
 | |
|                             <td><?php echo esc_html($alert['value']); ?></td>
 | |
|                             <td><?php echo esc_html($alert['threshold']); ?></td>
 | |
|                         </tr>
 | |
|                         <?php endforeach; ?>
 | |
|                         <?php endif; ?>
 | |
|                     </tbody>
 | |
|                 </table>
 | |
|             </div>
 | |
|             
 | |
|             <div class="card">
 | |
|                 <h2>Performance Thresholds</h2>
 | |
|                 <p>The following thresholds trigger performance alerts:</p>
 | |
|                 <ul>
 | |
|                     <li><strong>Slow Query Time:</strong> <?php echo self::THRESHOLDS['slow_query_time']; ?>s</li>
 | |
|                     <li><strong>Memory Usage:</strong> <?php echo self::THRESHOLDS['memory_usage_mb']; ?>MB</li>
 | |
|                     <li><strong>Page Load Time:</strong> <?php echo self::THRESHOLDS['page_load_time']; ?>s</li>
 | |
|                     <li><strong>Database Query Count:</strong> <?php echo self::THRESHOLDS['db_query_count']; ?> queries</li>
 | |
|                     <li><strong>Cache Hit Rate:</strong> <?php echo self::THRESHOLDS['cache_hit_rate']; ?>%</li>
 | |
|                 </ul>
 | |
|             </div>
 | |
|             
 | |
|             <style>
 | |
|             .performance-overview { display: flex; gap: 20px; margin-bottom: 20px; }
 | |
|             .performance-overview .card { flex: 1; }
 | |
|             </style>
 | |
|             
 | |
|             <script>
 | |
|             document.getElementById('run-benchmark')?.addEventListener('click', function() {
 | |
|                 this.disabled = true;
 | |
|                 this.textContent = 'Running Benchmark...';
 | |
|                 
 | |
|                 fetch(ajaxurl, {
 | |
|                     method: 'POST',
 | |
|                     body: new URLSearchParams({
 | |
|                         action: 'hvac_performance_action',
 | |
|                         performance_action: 'run_benchmark',
 | |
|                         nonce: '<?php echo wp_create_nonce('hvac_performance_action'); ?>'
 | |
|                     })
 | |
|                 })
 | |
|                 .then(response => response.json())
 | |
|                 .then(data => {
 | |
|                     if (data.success) {
 | |
|                         location.reload();
 | |
|                     } else {
 | |
|                         alert('Benchmark failed');
 | |
|                         this.disabled = false;
 | |
|                         this.textContent = 'Run New Benchmark';
 | |
|                     }
 | |
|                 });
 | |
|             });
 | |
|             </script>
 | |
|         </div>
 | |
|         <?php
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Handle performance actions
 | |
|      */
 | |
|     public static function handle_performance_action() {
 | |
|         check_ajax_referer('hvac_performance_action', 'nonce');
 | |
|         
 | |
|         if (!current_user_can('manage_options')) {
 | |
|             wp_send_json_error('Insufficient permissions');
 | |
|         }
 | |
|         
 | |
|         $action = sanitize_text_field($_POST['performance_action']);
 | |
|         
 | |
|         switch ($action) {
 | |
|             case 'run_benchmark':
 | |
|                 self::run_performance_benchmark();
 | |
|                 wp_send_json_success('Benchmark completed');
 | |
|                 break;
 | |
|                 
 | |
|             default:
 | |
|                 wp_send_json_error('Unknown action');
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Register REST endpoints
 | |
|      */
 | |
|     public static function register_rest_endpoints() {
 | |
|         register_rest_route('hvac/v1', '/performance/stats', [
 | |
|             'methods' => 'GET',
 | |
|             'callback' => [__CLASS__, 'rest_performance_stats'],
 | |
|             'permission_callback' => function() {
 | |
|                 return current_user_can('manage_options');
 | |
|             }
 | |
|         ]);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * REST API performance stats
 | |
|      */
 | |
|     public static function rest_performance_stats() {
 | |
|         $stats = self::get_performance_stats();
 | |
|         
 | |
|         return new WP_REST_Response([
 | |
|             'stats' => $stats,
 | |
|             'timestamp' => time()
 | |
|         ], 200);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * WP-CLI performance command
 | |
|      */
 | |
|     public static function wp_cli_performance($args, $assoc_args) {
 | |
|         $subcommand = $args[0] ?? 'stats';
 | |
|         
 | |
|         switch ($subcommand) {
 | |
|             case 'stats':
 | |
|                 $stats = self::get_performance_stats();
 | |
|                 WP_CLI::line('HVAC Performance Statistics:');
 | |
|                 WP_CLI::line('Average Page Load: ' . $stats['avg_page_load_time'] . 's');
 | |
|                 WP_CLI::line('Average Memory: ' . $stats['avg_memory_usage'] . 'MB');
 | |
|                 WP_CLI::line('Average Queries: ' . $stats['avg_query_count']);
 | |
|                 WP_CLI::line('Recent Alerts: ' . $stats['recent_alerts']);
 | |
|                 break;
 | |
|                 
 | |
|             case 'benchmark':
 | |
|                 WP_CLI::line('Running performance benchmark...');
 | |
|                 self::run_performance_benchmark();
 | |
|                 WP_CLI::success('Benchmark completed');
 | |
|                 break;
 | |
|                 
 | |
|             default:
 | |
|                 WP_CLI::error('Unknown subcommand. Use: stats, benchmark');
 | |
|         }
 | |
|     }
 | |
| }
 |