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; ?>

HVAC Performance Monitor

Performance Overview

Average Page Load Time: s

Average Memory Usage: MB

Average Query Count:

Total Requests Monitored:

Recent Alerts (24h):

Current Request Stats

Load Time:

Peak Memory:

Queries:

Slow Queries:

Latest Benchmark

Date:

Database (simple): s

Database (complex): s

Cache Reads/sec:

Recent Performance Alerts

Time Type Message Value Threshold
No recent performance alerts

Performance Thresholds

The following thresholds trigger performance alerts:

'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'); } } }