Сайт «иногда тормозит», после обновления плагина отвалилась корзина, а на одной странице вместо контента белый экран. Догадки тут не помогают — помогает лог. WordPress умеет записывать все ошибки PHP в отдельный файл, и включается это тремя строчками в конфиге. Разберём, как их правильно прописать, куда попадает файл, как не отдать его посторонним и как читать записи, чтобы за минуту находить виновника.
Что вообще логирует WordPress
Своего «журнала событий» вроде админского лога действий у ядра нет. То, что принято называть логами WordPress, — это стандартный лог ошибок PHP, которому движок подсовывает свой файл и свои настройки. Туда попадает всё, что PHP считает проблемой при выполнении кода: фатальные ошибки, предупреждения, замечания и сообщения об устаревших функциях.
Отсюда важный вывод: лог покажет проблемы в коде — вашей темы, плагинов, ядра. Он не расскажет, кто удалил товар и почему заказ не ушёл в CRM. Для таких вещей нужны отдельные инструменты или собственное логирование, о котором ниже.
Рядом живут ещё три журнала, о которых часто забывают:
- лог веб-сервера —
/var/log/nginx/error.logилиerror_logу Apache. Сюда попадают ошибки уровня сервера: таймауты, 502, отказ соединения с PHP-FPM; - лог PHP-FPM — там видны падения самого процесса и превышения лимитов памяти;
- лог медленных запросов MySQL — если сайт тормозит, а PHP-ошибок нет, смотреть надо туда (и дальше — в индексы).
Включаем debug.log: три константы в wp-config.php
Все настройки живут в wp-config.php в корне сайта. Вставлять их нужно выше строки /* That's all, stop editing! */ — ниже они уже не сработают.
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
Что делает каждая:
WP_DEBUG— главный выключатель режима отладки. По умолчаниюfalse. Пока он выключен, остальные константы не имеют смысла:WP_DEBUG_LOGработает только вместе с ним.WP_DEBUG_LOG— включает запись ошибок в файл.WP_DEBUG_DISPLAY— показывать ли ошибки прямо в HTML страницы. По умолчаниюtrue, и на боевом сайте это ровно то, чего быть не должно: посетитель увидит пути к файлам и куски кода. Ставимfalse.- Строка с
ini_set— страховка: некоторые хостинги включают вывод ошибок на уровне PHP, и константы WordPress их не переопределяют.
Такая связка безопасна для продакшена: ошибки пишутся в файл, наружу не выводятся. Именно так и стоит держать боевой сайт — не «включить отладку на час», а вести журнал постоянно.
Ещё две константы — для разработки
SCRIPT_DEBUG заставляет ядро подключать неминифицированные версии своих CSS и JS — полезно, когда ловите ошибку в скриптах админки. SAVEQUERIES складывает все SQL-запросы страницы в массив $wpdb->queries вместе со временем выполнения и вызвавшей функцией. Обе заметно нагружают сайт, поэтому на боевом их не оставляют.
Куда попадает файл и как сменить путь
По умолчанию лог пишется в wp-content/debug.log. Место удобное, но публичное: если сервер отдаёт файл по прямой ссылке, любой желающий прочитает пути на диске, имена таблиц и обрывки логики плагинов. Это разведданные для атаки.
Самое надёжное решение — вынести лог за пределы каталога сайта. Константа принимает не только true, но и путь:
define( 'WP_DEBUG_LOG', '/home/user/logs/wp-errors.log' );
Каталог должен существовать и быть доступен на запись пользователю, от которого работает PHP. Если вынести некуда, закройте файл на уровне сервера. Для Apache в .htaccess:
<Files debug.log>
Require all denied
</Files>
Для nginx — в конфиг сайта:
location ~* /wp-content/debug\.log {
deny all;
}
Проверить результат просто: откройте https://ваш-сайт/wp-content/debug.log в браузере. Должно быть 403 или 404, а не текст. Эта проверка стоит того, чтобы попасть в общий чек-лист безопасности сайта.
Как читать записи
Типичная строка выглядит так:
[09-Sep-2026 10:12:33 UTC] PHP Fatal error: Uncaught Error:
Call to undefined function wc_get_order() in
/var/www/site/wp-content/plugins/my-plugin/orders.php:42
Читается справа налево: файл и номер строки — вот где искать. Дальше идёт stack trace (стек вызовов) — цепочка функций, приведших к ошибке; по ней видно, из какого хука всё началось. Время указано в UTC, а не в часовом поясе сайта — при сверке с жалобами пользователей это регулярно сбивает с толку.
Четыре уровня и что с ними делать
- Fatal error — выполнение остановлено. Это причина белого экрана и «сайт лежит». Разбирать в первую очередь, всегда.
- Warning — код продолжил работу, но что-то пошло не так: не найден файл, деление на ноль, неверный аргумент. Часто именно отсюда растут «странности» вроде пустого блока на странице.
- Notice — обращение к несуществующему индексу массива или переменной. Поодиночке безобидно, тысячами — признак кривого кода и лишняя нагрузка.
- Deprecated — используется устаревшая функция PHP или WordPress. Сегодня работает, после следующего мажорного обновления PHP — нет. Это ваш список технического долга.
Навигация по большому файлу
Через месяц лог может весить сотни мегабайт, и открывать его целиком не нужно. По SSH хватает четырёх команд:
# последние 100 строк
tail -n 100 wp-content/debug.log
# смотреть в реальном времени: воспроизводим баг и видим запись
tail -f wp-content/debug.log
# только фатальные, с номерами строк
grep -n "Fatal error" wp-content/debug.log
# кто чаще всего мусорит: топ плагинов по числу упоминаний
grep -o "plugins/[^/]*" wp-content/debug.log | sort | uniq -c | sort -rn
Последняя команда — самый быстрый способ понять, какой плагин виноват: она считает, сколько раз каждый из них засветился в логе.
Свои сообщения в логе
Отладка «вслепую» через var_dump() ломает вёрстку и попадает на глаза посетителям. Правильнее писать в тот же файл функцией error_log(). Массивы и объекты она сама не переваривает, поэтому удобна маленькая обёртка в functions.php темы или в своём плагине:
function my_log( $data, $label = '' ) {
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
return;
}
if ( is_array( $data ) || is_object( $data ) ) {
$data = print_r( $data, true );
}
error_log( trim( $label . ' ' . $data ) );
}
Проверка на WP_DEBUG здесь ключевая: выключили отладку — записи прекратились, вычищать вызовы по всему проекту не нужно. Дальше остаётся расставить my_log() в нужных местах — например, внутри хуков WooCommerce, чтобы увидеть, что реально приходит в заказ.
Белый экран и режим восстановления
С версии 5.2 ядро не показывает белый экран при падении плагина: оно ловит фатальную ошибку, отключает виновника и присылает администратору письмо со специальной ссылкой. По ней открывается режим восстановления — админка работает, сломанный плагин помечен, его можно обновить или удалить.
Работает это, только если почта с сайта уходит. Если писем нет, а сайт лёг — обработчик можно отключить и увидеть настоящую ошибку:
define( 'WP_DISABLE_FATAL_ERROR_HANDLER', true );
Вместе с WP_DEBUG_LOG это даст полную запись падения в файле. На боевом сайте константу оставлять не стоит — она снимает защиту от белого экрана.
Query Monitor: лог в реальном времени
Файл хорош для разбора постфактум, но когда нужно понять, что происходит на этой конкретной странице, удобнее плагин Query Monitor — он добавляет панель в админ-бар и показывает PHP-ошибки, все SQL-запросы с временем выполнения, сработавшие хуки, HTTP-запросы наружу и подключённые скрипты. Отдельно подсвечивает медленные и дублирующиеся запросы и группирует их по плагинам — то есть сразу отвечает на вопрос «кто тормозит».
Актуальная версия — 4.0.7 (июнь 2026), более 200 000 активных установок, требуется WordPress 6.2+ и PHP 7.4+. Данные плагин никуда не отправляет и не хранит. Панель видна только пользователям с правами администратора, но на продакшене его обычно держат выключенным — ради лишних запросов и памяти. Для системной работы над скоростью пригодится чек-лист оптимизации.
Без доступа к файлам: WP-CLI
Если есть консоль, править конфиг руками не обязательно:
wp config set WP_DEBUG true --raw
wp config set WP_DEBUG_LOG true --raw
wp config set WP_DEBUG_DISPLAY false --raw
wp config get WP_DEBUG
Флаг --raw обязателен: без него значение запишется строкой 'true' в кавычках, а строка 'false' в PHP истинна — отладка окажется включена там, где вы её выключали. Другие полезные команды собраны в шпаргалке по WP-CLI.
Гигиена: ротация и уборка
Лог растёт бесконечно и на активном сайте с шумным плагином способен занять весь диск. Минимум — очищать файл, не удаляя его: > wp-content/debug.log. Удалять сам файл не надо, PHP создаст новый, но так теряется история.
Нормальное решение — logrotate. Конфиг в /etc/logrotate.d/wordpress:
/var/www/site/wp-content/debug.log {
weekly
rotate 4
compress
missingok
notifempty
create 0640 www-data www-data
}
Раз в неделю файл архивируется, хранятся четыре копии — примерно месяц истории при предсказуемом размере.
Порядок действий при поломке
Работающая последовательность, когда «всё сломалось»:
- Включить
WP_DEBUG_LOG, вывод ошибок оставить выключенным. - Очистить лог, повторить действие, которое ломает сайт.
grep -n "Fatal error"— взять самую свежую запись, посмотреть файл и строку.- Если фаталов нет — искать
Warningпримерно в то же время. - Пусто и здесь — идти в лог nginx или Apache: ошибка уровня сервера до PHP просто не дошла.
- Виновник найден — обновить плагин, откатить версию или чинить свой код.
Всё это работает одинаково от старых веток до актуальной WordPress 7.1: механизм отладки не меняется годами. Настройте его один раз на всех своих сайтах — и следующая поломка перестанет быть детективом.
Частые вопросы
По умолчанию в wp-content/debug.log. Путь можно сменить, передав его прямо в константу: define( 'WP_DEBUG_LOG', '/home/user/logs/wp-errors.log' ). Вынести лог за пределы каталога сайта — самый надёжный вариант: так его физически нельзя открыть по прямой ссылке.
Да, если рядом стоит WP_DEBUG_DISPLAY = false и @ini_set('display_errors', 0). Тогда ошибки пишутся в файл, но не выводятся посетителям. Именно так и стоит держать продакшен — постоянно вести журнал, а не включать отладку на час. Сам файл при этом должен быть закрыт от прямого доступа или лежать вне каталога сайта.
Три частые причины: константы прописаны ниже строки /* That's all, stop editing! */ и не сработали; WP_DEBUG остался false, без него WP_DEBUG_LOG не работает; у PHP нет прав на запись в wp-content. Ещё вариант — ошибок просто нет: если сайт падает на уровне сервера, запись уйдёт в лог nginx или Apache, а не в debug.log.
debug.log — история: что и когда сломалось, разбирается постфактум. Query Monitor показывает текущую страницу здесь и сейчас: ошибки PHP, SQL-запросы с временем выполнения, хуки, внешние HTTP-запросы, и группирует их по плагинам. Инструменты дополняют друг друга, но плагин на боевом сайте обычно держат выключенным.
Источники
- 1.Debugging in WordPress — WordPress Developer Resourceshttps://developer.wordpress.org/advanced-administration/debug/debug-wordpress/
- 2.wp-config.php — WordPress Developer Resourceshttps://developer.wordpress.org/apis/wp-config-php/
- 3.wp config set — WP-CLI Command Referencehttps://developer.wordpress.org/cli/commands/config/set/
- 4.Query Monitor — WordPress plugin directoryhttps://wordpress.org/plugins/query-monitor/
- 5.WordPress Releases — wordpress.orghttps://wordpress.org/download/releases/



