add files inc
This commit is contained in:
222
inc/realtime-debug.php
Normal file
222
inc/realtime-debug.php
Normal file
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
/**
|
||||
* Real-time Execution Logger for WordPress
|
||||
* Логирует выполнение страницы в реальном времени
|
||||
*/
|
||||
|
||||
class RealtimePageLogger {
|
||||
private static $instance;
|
||||
private $log_file;
|
||||
private $request_id;
|
||||
private $start_time;
|
||||
|
||||
public static function get_instance() {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function __construct() {
|
||||
$this->log_file = WP_CONTENT_DIR . '/realtime-debug.log';
|
||||
$this->request_id = uniqid('req_', true);
|
||||
$this->start_time = microtime(true);
|
||||
|
||||
// Очищаем файл при инициализации
|
||||
$this->clean_log_file();
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистка лог-файла с проверками
|
||||
*/
|
||||
private function clean_log_file() {
|
||||
// Если файл не существует, создаем его
|
||||
if (!file_exists($this->log_file)) {
|
||||
if (touch($this->log_file)) {
|
||||
chmod($this->log_file, 0644);
|
||||
$this->log_message("Создан новый лог-файл", 'SYSTEM');
|
||||
} else {
|
||||
error_log('Не удалось создать файл realtime-debug.log');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Проверяем доступность для записи
|
||||
if (!is_writable($this->log_file)) {
|
||||
error_log('Файл realtime-debug.log недоступен для записи');
|
||||
return;
|
||||
}
|
||||
|
||||
// Очищаем файл
|
||||
if (file_put_contents($this->log_file, '') === false) {
|
||||
error_log('Не удалось очистить файл realtime-debug.log');
|
||||
} else {
|
||||
$this->log_message("Лог-файл очищен", 'SYSTEM');
|
||||
}
|
||||
}
|
||||
|
||||
private function init() {
|
||||
// Начинаем логирование как можно раньше
|
||||
add_action('plugins_loaded', [$this, 'log_plugins_loaded'], 1);
|
||||
add_action('setup_theme', [$this, 'log_setup_theme'], 1);
|
||||
add_action('after_setup_theme', [$this, 'log_after_setup_theme'], 1);
|
||||
add_action('init', [$this, 'log_init'], 1);
|
||||
|
||||
// Логируем все основные этапы
|
||||
add_action('wp_loaded', [$this, 'log_wp_loaded']);
|
||||
add_action('parse_query', [$this, 'log_parse_query']);
|
||||
add_action('pre_get_posts', [$this, 'log_pre_get_posts']);
|
||||
add_action('wp', [$this, 'log_wp']);
|
||||
|
||||
// Логируем SQL запросы
|
||||
add_filter('query', [$this, 'log_sql_query']);
|
||||
|
||||
// Логируем шаблоны
|
||||
add_filter('template_include', [$this, 'log_template_include'], 9999);
|
||||
|
||||
// Логируем завершение
|
||||
add_action('shutdown', [$this, 'log_shutdown'], 9999);
|
||||
|
||||
// Логируем хуки в реальном времени
|
||||
$this->setup_hook_logging();
|
||||
}
|
||||
|
||||
public function setup_hook_logging() {
|
||||
$important_hooks = [
|
||||
'template_redirect',
|
||||
'get_header',
|
||||
'wp_head',
|
||||
'the_post',
|
||||
'loop_start',
|
||||
'loop_end',
|
||||
'get_sidebar',
|
||||
'get_footer',
|
||||
'wp_footer',
|
||||
'admin_bar_menu',
|
||||
'wp_enqueue_scripts',
|
||||
'wp_print_styles',
|
||||
'wp_print_scripts'
|
||||
];
|
||||
|
||||
foreach ($important_hooks as $hook) {
|
||||
add_action($hook, function() use ($hook) {
|
||||
$this->log_hook($hook);
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private function log_message($message, $level = 'INFO') {
|
||||
$timestamp = microtime(true);
|
||||
$elapsed = round(($timestamp - $this->start_time) * 1000, 2);
|
||||
$memory = memory_get_usage(true);
|
||||
|
||||
$log = sprintf(
|
||||
"[%s] %s | %6.2fms | %8s | %s | %s\n",
|
||||
date('H:i:s'),
|
||||
$this->request_id,
|
||||
$elapsed,
|
||||
size_format($memory, 0),
|
||||
$level,
|
||||
$message
|
||||
);
|
||||
|
||||
file_put_contents($this->log_file, $log, FILE_APPEND);
|
||||
}
|
||||
|
||||
public function log_plugins_loaded() {
|
||||
$this->log_message('PLUGINS_LOADED - Плагины загружены');
|
||||
}
|
||||
|
||||
public function log_setup_theme() {
|
||||
$this->log_message('SETUP_THEME - Начинается загрузка темы');
|
||||
}
|
||||
|
||||
public function log_after_setup_theme() {
|
||||
$this->log_message('AFTER_SETUP_THEME - Тема загружена');
|
||||
}
|
||||
|
||||
public function log_init() {
|
||||
$this->log_message('INIT - WordPress инициализирован');
|
||||
}
|
||||
|
||||
public function log_wp_loaded() {
|
||||
$this->log_message('WP_LOADED - WordPress полностью загружен');
|
||||
}
|
||||
|
||||
public function log_parse_query() {
|
||||
global $wp_query;
|
||||
$this->log_message(sprintf('PARSE_QUERY - Запрос: %s', $wp_query->query_vars['pagename'] ?? 'main'));
|
||||
}
|
||||
|
||||
public function log_pre_get_posts($query) {
|
||||
if ($query->is_main_query()) {
|
||||
$this->log_message('PRE_GET_POSTS - Основной запрос к posts');
|
||||
}
|
||||
}
|
||||
|
||||
public function log_wp() {
|
||||
$this->log_message('WP - Запрос обработан, готовим данные для шаблона');
|
||||
}
|
||||
|
||||
public function log_sql_query($query) {
|
||||
$trimmed = trim($query);
|
||||
if (!empty($trimmed) && !str_starts_with($trimmed, '/*')) {
|
||||
//$short_query = substr($trimmed, 0, 150);
|
||||
//if (strlen($trimmed) > 150) {
|
||||
// $short_query .= '...';
|
||||
// }
|
||||
$this->log_message("SQL: {$query}", 'SQL');
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function log_hook($hook) {
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4);
|
||||
$caller = $this->get_caller_info($backtrace);
|
||||
$this->log_message("HOOK: {$hook} → {$caller}", 'HOOK');
|
||||
}
|
||||
|
||||
public function log_template_include($template) {
|
||||
$template_name = basename($template);
|
||||
$this->log_message("TEMPLATE: {$template_name}", 'TEMPLATE');
|
||||
return $template;
|
||||
}
|
||||
|
||||
public function log_shutdown() {
|
||||
$total_time = round((microtime(true) - $this->start_time) * 1000, 2);
|
||||
$peak_memory = memory_get_peak_usage(true);
|
||||
|
||||
$this->log_message("SHUTDOWN - Завершение работы ({$total_time}ms, " .
|
||||
size_format($peak_memory) . ")", 'FINISH');
|
||||
}
|
||||
|
||||
private function get_caller_info($backtrace) {
|
||||
foreach ($backtrace as $trace) {
|
||||
if (isset($trace['file']) &&
|
||||
!str_contains($trace['file'], 'wp-includes') &&
|
||||
!str_contains($trace['file'], 'wp-admin')) {
|
||||
$file = basename($trace['file']);
|
||||
$line = $trace['line'] ?? 'unknown';
|
||||
return "{$file}:{$line}";
|
||||
}
|
||||
}
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
// Инициализируем логгер только если включен дебаг
|
||||
//if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
RealtimePageLogger::get_instance();
|
||||
//}
|
||||
|
||||
// Функция для очистки лога
|
||||
add_action('wp_ajax_clear_realtime_log', 'clear_realtime_debug_log');
|
||||
function clear_realtime_debug_log() {
|
||||
if (current_user_can('administrator')) {
|
||||
file_put_contents(WP_CONTENT_DIR . '/realtime-debug.log', '');
|
||||
echo "Realtime log cleared!";
|
||||
}
|
||||
wp_die();
|
||||
}
|
||||
Reference in New Issue
Block a user