267 lines
7.1 KiB
PHP
267 lines
7.1 KiB
PHP
<?php
|
|
/**
|
|
* Performance Profiler Module
|
|
*
|
|
* Mide tiempos de ejecución, memoria y detecta bottlenecks
|
|
*
|
|
* @package WP_Debug
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* WP_Debug_Profiler class
|
|
*/
|
|
class WP_Debug_Profiler {
|
|
|
|
/**
|
|
* Active timers
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $timers = array();
|
|
|
|
/**
|
|
* Completed timers
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $completed_timers = array();
|
|
|
|
/**
|
|
* Memory snapshots
|
|
*
|
|
* @var array
|
|
*/
|
|
private static $memory_snapshots = array();
|
|
|
|
/**
|
|
* Initialize profiler
|
|
*/
|
|
public static function init() {
|
|
// Start tracking on init
|
|
add_action('init', array(__CLASS__, 'start_tracking'), 1);
|
|
|
|
// Record metrics on shutdown
|
|
add_action('shutdown', array(__CLASS__, 'record_metrics'), 999);
|
|
|
|
// Track query execution
|
|
add_filter('query', array(__CLASS__, 'track_query'));
|
|
}
|
|
|
|
/**
|
|
* Start tracking
|
|
*/
|
|
public static function start_tracking() {
|
|
self::$memory_snapshots['init'] = memory_get_usage();
|
|
|
|
// Log page load start
|
|
if (class_exists('WP_Debug_Logger')) {
|
|
WP_Debug_Logger::debug('Page load started', array(
|
|
'url' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '',
|
|
'memory' => self::format_bytes(memory_get_usage()),
|
|
));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Start a timer
|
|
*
|
|
* @param string $name Timer name
|
|
* @return bool True on success
|
|
*/
|
|
public static function start_timer($name) {
|
|
self::$timers[$name] = array(
|
|
'start' => microtime(true),
|
|
'memory_start' => memory_get_usage(),
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* End a timer
|
|
*
|
|
* @param string $name Timer name
|
|
* @return float|bool Elapsed time in seconds, or false
|
|
*/
|
|
public static function end_timer($name) {
|
|
if (!isset(self::$timers[$name])) {
|
|
return false;
|
|
}
|
|
|
|
$end_time = microtime(true);
|
|
$memory_end = memory_get_usage();
|
|
|
|
$elapsed = $end_time - self::$timers[$name]['start'];
|
|
$memory_used = $memory_end - self::$timers[$name]['memory_start'];
|
|
|
|
self::$completed_timers[$name] = array(
|
|
'elapsed' => $elapsed,
|
|
'memory_used' => $memory_used,
|
|
'memory_peak' => memory_get_peak_usage(),
|
|
);
|
|
|
|
// Log if exceeds threshold
|
|
$threshold = get_option('wp_debug_profiler_threshold', 1000); // milliseconds
|
|
if ($elapsed * 1000 > $threshold) {
|
|
if (class_exists('WP_Debug_Logger')) {
|
|
WP_Debug_Logger::warning("Slow execution: {$name}", array(
|
|
'elapsed_ms' => round($elapsed * 1000, 2),
|
|
'memory' => self::format_bytes($memory_used),
|
|
));
|
|
}
|
|
}
|
|
|
|
unset(self::$timers[$name]);
|
|
|
|
return $elapsed;
|
|
}
|
|
|
|
/**
|
|
* Get completed timers
|
|
*
|
|
* @return array Timers
|
|
*/
|
|
public static function get_timers() {
|
|
return self::$completed_timers;
|
|
}
|
|
|
|
/**
|
|
* Track query execution
|
|
*
|
|
* @param string $query SQL query
|
|
* @return string Query
|
|
*/
|
|
public static function track_query($query) {
|
|
// This will be used by query analyzer
|
|
return $query;
|
|
}
|
|
|
|
/**
|
|
* Record metrics on shutdown
|
|
*/
|
|
public static function record_metrics() {
|
|
// Calculate total execution time
|
|
$total_time = timer_stop(0, 3);
|
|
|
|
// Get memory stats
|
|
$memory_current = memory_get_usage();
|
|
$memory_peak = memory_get_peak_usage();
|
|
|
|
// Get server load if available
|
|
$server_load = self::get_server_load();
|
|
|
|
// Prepare metrics
|
|
$metrics = array(
|
|
'execution_time' => $total_time,
|
|
'memory_current' => $memory_current,
|
|
'memory_peak' => $memory_peak,
|
|
'server_load' => $server_load,
|
|
'timers' => self::$completed_timers,
|
|
'url' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '',
|
|
'timestamp' => current_time('mysql'),
|
|
);
|
|
|
|
// Log metrics
|
|
if (class_exists('WP_Debug_Logger')) {
|
|
WP_Debug_Logger::info('Page load completed', array(
|
|
'time' => round($total_time, 3) . 's',
|
|
'memory_peak' => self::format_bytes($memory_peak),
|
|
'timers_count' => count(self::$completed_timers),
|
|
));
|
|
}
|
|
|
|
// Store metrics in transient for frontend panel
|
|
set_transient('wp_debug_last_metrics', $metrics, 3600);
|
|
}
|
|
|
|
/**
|
|
* Get server load
|
|
*
|
|
* @return string|null Server load
|
|
*/
|
|
private static function get_server_load() {
|
|
if (function_exists('sys_getloadavg')) {
|
|
$load = sys_getloadavg();
|
|
return implode(', ', array_map(function($val) {
|
|
return round($val, 2);
|
|
}, $load));
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Format bytes to human readable
|
|
*
|
|
* @param int $bytes Bytes
|
|
* @return string Formatted string
|
|
*/
|
|
public static function format_bytes($bytes) {
|
|
$units = array('B', 'KB', 'MB', 'GB');
|
|
$bytes = max($bytes, 0);
|
|
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
|
$pow = min($pow, count($units) - 1);
|
|
|
|
$bytes /= (1 << (10 * $pow));
|
|
|
|
return round($bytes, 2) . ' ' . $units[$pow];
|
|
}
|
|
|
|
/**
|
|
* Get performance report
|
|
*
|
|
* @return array Performance report
|
|
*/
|
|
public static function get_performance_report() {
|
|
$metrics = get_transient('wp_debug_last_metrics');
|
|
|
|
if (!$metrics) {
|
|
return array(
|
|
'error' => 'No metrics available',
|
|
);
|
|
}
|
|
|
|
// Analyze and provide suggestions
|
|
$suggestions = array();
|
|
|
|
// Check execution time
|
|
if ($metrics['execution_time'] > 3) {
|
|
$suggestions[] = 'Page load time exceeds 3 seconds. Consider caching or optimizing queries.';
|
|
}
|
|
|
|
// Check memory
|
|
if ($metrics['memory_peak'] > 128 * 1024 * 1024) { // 128MB
|
|
$suggestions[] = 'Memory usage is high (' . self::format_bytes($metrics['memory_peak']) . '). Check for memory leaks.';
|
|
}
|
|
|
|
// Check slow timers
|
|
$slow_timers = array();
|
|
foreach ($metrics['timers'] as $name => $timer) {
|
|
if ($timer['elapsed'] > 1) {
|
|
$slow_timers[$name] = round($timer['elapsed'], 3) . 's';
|
|
}
|
|
}
|
|
|
|
if (!empty($slow_timers)) {
|
|
$suggestions[] = 'Slow functions detected: ' . implode(', ', array_keys($slow_timers));
|
|
}
|
|
|
|
return array(
|
|
'metrics' => $metrics,
|
|
'suggestions' => $suggestions,
|
|
'formatted' => array(
|
|
'execution_time' => round($metrics['execution_time'], 3) . 's',
|
|
'memory_current' => self::format_bytes($metrics['memory_current']),
|
|
'memory_peak' => self::format_bytes($metrics['memory_peak']),
|
|
'server_load' => $metrics['server_load'],
|
|
),
|
|
);
|
|
}
|
|
}
|