Files
roi-theme/wp-content/plugins/wp-debug/inc/profiler.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'],
),
);
}
}