Files
profile/inc/realtime-debug.php
Profile Profile ed4d79b706 add files inc
2026-03-09 20:51:08 +03:00

222 lines
7.4 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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();
}