Заметки

Логи WordPress: как включить и читать

M
Markabus
·10 сентября 2026 г.
Тёмный рабочий стол разработчика: крупным планом монитор с бегущим логом в терминале, среди серых строк выделяются красные строки ошибок; на заднем плане размытая серверная стойка

Сайт «иногда тормозит», после обновления плагина отвалилась корзина, а на одной странице вместо контента белый экран. Догадки тут не помогают — помогает лог. 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
}

Раз в неделю файл архивируется, хранятся четыре копии — примерно месяц истории при предсказуемом размере.

Порядок действий при поломке

Работающая последовательность, когда «всё сломалось»:

  1. Включить WP_DEBUG_LOG, вывод ошибок оставить выключенным.
  2. Очистить лог, повторить действие, которое ломает сайт.
  3. grep -n "Fatal error" — взять самую свежую запись, посмотреть файл и строку.
  4. Если фаталов нет — искать Warning примерно в то же время.
  5. Пусто и здесь — идти в лог nginx или Apache: ошибка уровня сервера до PHP просто не дошла.
  6. Виновник найден — обновить плагин, откатить версию или чинить свой код.

Всё это работает одинаково от старых веток до актуальной WordPress 7.1: механизм отладки не меняется годами. Настройте его один раз на всех своих сайтах — и следующая поломка перестанет быть детективом.

Частые вопросы

Q.Где лежит файл debug.log?

По умолчанию в wp-content/debug.log. Путь можно сменить, передав его прямо в константу: define( 'WP_DEBUG_LOG', '/home/user/logs/wp-errors.log' ). Вынести лог за пределы каталога сайта — самый надёжный вариант: так его физически нельзя открыть по прямой ссылке.

Q.Можно ли оставить WP_DEBUG включённым на боевом сайте?

Да, если рядом стоит WP_DEBUG_DISPLAY = false и @ini_set('display_errors', 0). Тогда ошибки пишутся в файл, но не выводятся посетителям. Именно так и стоит держать продакшен — постоянно вести журнал, а не включать отладку на час. Сам файл при этом должен быть закрыт от прямого доступа или лежать вне каталога сайта.

Q.Включил отладку, а debug.log пустой или не появился — почему?

Три частые причины: константы прописаны ниже строки /* That's all, stop editing! */ и не сработали; WP_DEBUG остался false, без него WP_DEBUG_LOG не работает; у PHP нет прав на запись в wp-content. Ещё вариант — ошибок просто нет: если сайт падает на уровне сервера, запись уйдёт в лог nginx или Apache, а не в debug.log.

Q.Чем Query Monitor отличается от debug.log?

debug.log — история: что и когда сломалось, разбирается постфактум. Query Monitor показывает текущую страницу здесь и сейчас: ошибки PHP, SQL-запросы с временем выполнения, хуки, внешние HTTP-запросы, и группирует их по плагинам. Инструменты дополняют друг друга, но плагин на боевом сайте обычно держат выключенным.

Источники

Предыдущая
Хуки WooCommerce: как менять поведение магазина

Читайте также

Рабочее место разработчика ночью: на переднем мониторе — редактор с PHP-кодом, на втором — страница товара интернет-магазина; свет от экранов падает на клавиатуру и столЗаметки
8 сентября 2026 г.

Хуки WooCommerce: как менять поведение магазина

Хуки — штатный способ менять магазин на WooCommerce, не трогая файлы плагина. Разбираем действия и фильтры, приоритеты, remove_action, пять рабочих рецептов и главную ловушку 2026 года — блочные «Корзину» и «Оформление заказа», где классические хуки просто не вызываются.

Читать →
Тёмный рабочий стол разработчика крупным планом: экран ноутбука с открытым терминалом и командной строкой, рядом механическая клавиатура, кабель и сетевой коммутатор в расфокусеЗаметки
7 сентября 2026 г.

WP-CLI: команды на каждый день

Рабочий набор команд WP-CLI для повседневного обслуживания сайтов: установка, обновления ядра и плагинов, дампы базы, замена домена без порчи сериализованных данных, пользователи, медиа, кеш, cron, алиасы для нескольких окружений — и грабли, на которые наступают чаще всего.

Читать →
Тёмный рабочий стол разработчика крупным планом: монитор с планом выполнения SQL-запроса в терминале, рядом механическая клавиатура и стойка с индикаторамиЗаметки
4 сентября 2026 г.

Индексы MySQL: как ускорить запросы

Разбираем, как устроены индексы в MySQL, как найти запросы, которым их не хватает, как собрать правильный составной индекс и почему лишние индексы вредят не меньше отсутствующих.

Читать →