Где находится debug.log в WordPress и как перенести его в безопасное место
Где искать debug.log в wp-content, как вынести его за пределы корня сайта, чтобы файл не скачали посетители, и какие настройки WP_DEBUG оставляют лог пустым.
Опубликовано
По умолчанию WordPress пишет лог отладки в wp-content/debug.log — на диске это абсолютный путь вида /path/to/your/site/wp-content/debug.log. Файл не существует, пока в него что-нибудь не запишется, и запись вообще идёт только тогда, когда в wp-config.php константа WP_DEBUG равна true, а WP_DEBUG_LOG включена. Это стандартное расположение к тому же представляет реальную угрозу безопасности: на большинстве хостингов файл может скачать кто угодно прямо из браузера.
Три константы и что делает каждая
Все три помещаются в wp-config.php выше строки /* That's all, stop editing! Happy blogging. */. Всё, что добавлено ниже, выполняется уже после загрузки WordPress и попросту игнорируется.
| Константа | По умолчанию | Что делает |
|---|---|---|
WP_DEBUG | false | Главный выключатель. Повышает уровень отчётов PHP, чтобы показывать замечания, предупреждения и устаревшие вызовы. Без неё ничего из списка не работает. |
WP_DEBUG_LOG | false | Направляет ошибки в файл. Значение true означает wp-content/debug.log. Строка трактуется как путь к файлу для записи. |
WP_DEBUG_DISPLAY | true | Выводит ошибки в HTML страницы, где их видит каждый посетитель. |
Чаще всего ошибаются именно в зависимости между ними. WP_DEBUG_LOG читается внутри ветки WP_DEBUG в стартовом коде WordPress. Если WP_DEBUG равна false, то установка WP_DEBUG_LOG в true не даёт ровным счётом ничего — ни файла, ни ошибки, ни предупреждения. Если вы добавили WP_DEBUG_LOG, а лог не появился, сначала проверьте WP_DEBUG.
Рабочая конфигурация для боевого сайта:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
Если WP_DEBUG уже определена выше по файлу — а обычно это так, со значением false, — правьте существующую строку, а не добавляйте второй define(). Повторное определение той же константы вызывает предупреждение PHP, которое на сайте с включённым выводом окажется прямо в шапке страницы.
Почему WP_DEBUG_DISPLAY на рабочем сайте должна быть false
При включённом выводе ошибки PHP печатаются прямо в HTML-ответ. Одно-единственное уведомление об устаревшем вызове из темы покажет каждому посетителю абсолютный путь на вашем сервере. Ошибка базы данных выдаст имена таблиц и фрагменты запросов. Хуже того, вывод, появившийся до отправки заголовков, ломает редиректы, ломает ответы REST и AJAX, которые ждут чистого JSON, и способен породить тот самый белый экран, в котором потом обвиняют плагин.
Один нюанс, который стоит знать: значение null у WP_DEBUG_DISPLAY — это не то же самое, что false. null велит WordPress не трогать настройку PHP display_errors и унаследовать то, что задано на сервере. false принудительно её выключает. На боевом сайте ставьте false и добавляйте строку с ini_set выше как подстраховку: плагин может включить display_errors обратно позже в ходе запроса.
Стандартное расположение доступно всем
wp-content/debug.log лежит внутри корня сайта. Стандартная установка WordPress ничем не закрывает прямые запросы к нему. На типичной конфигурации Apache или nginx адрес https://yoursite.com/wp-content/debug.log отдаёт файл обычным текстом. Логи отладки содержат абсолютные пути на сервере, внутренности плагинов и темы, ошибки базы данных с реальным текстом запросов, а иногда и значения, переданные в упавшие функции. Это бесплатная разведка для любого, кто угадает адрес, — и один из первых адресов, которые перебирают автоматические сканеры.
Бороться с этим можно двумя способами. Лучший — перенести лог.
Перенос лога по пути
Начиная с WordPress 5.1 WP_DEBUG_LOG принимает не только логическое значение, но и строку с путём к файлу. Укажите место за пределами корня сайта:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/home/youruser/logs/wp-errors.log' );
define( 'WP_DEBUG_DISPLAY', false );
Три правила для этого пути. Путь должен быть абсолютным: относительный разрешается относительно рабочего каталога PHP, который меняется от запроса к запросу и от сервера к серверу, так что вы просто потеряете файл. Каталог должен существовать заранее: PHP его не создаст, а если не сможет открыть файл, то промолчит. И каталог должен быть доступен на запись пользователю PHP, а на виртуальном хостинге это не та же учётная запись, под которой вы заходите по SFTP.
Если хостинг запирает вас внутри корня сайта и писать выше некуда, оставьте путь по умолчанию и закройте доступ на уровне сервера. Для Apache:
<Files "debug.log">
Require all denied
</Files>
Это помещается в файл .htaccess внутри wp-content, а не в корневой: корневой .htaccess WordPress перезаписывает при сохранении постоянных ссылок и может стереть вашу правку. На nginx .htaccess не работает вовсе — там нужен блок location в конфигурации сервера, а на управляемом хостинге это обычно означает обращение в поддержку.
Честно о том, что даёт блокировка: файл по-прежнему лежит на диске в каталоге, который отдаёт веб-сервер. Уязвимость обхода пути в любом плагине всё ещё позволит его прочитать. Вынос за пределы корня сайта — решение более надёжное.
Как читать файл и следить за ним
По SSH можно смотреть за ним вживую, пока воспроизводите баг:
tail -f wp-content/debug.log
Повторите ошибку в другой вкладке, и новые строки появятся сразу же. Чтобы увидеть только недавние события или отфильтровать по одному плагину:
tail -n 100 wp-content/debug.log
grep -i 'plugin-slug' wp-content/debug.log | tail -n 50
PHP дописывает в конец файла, поэтому читайте снизу вверх. Каждая запись помечена временем в UTC, которое не совпадёт с часовым поясом, заданным в WordPress, — не решите из-за этого, что смотрите на старые записи.
С помощью 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
Флаг --raw здесь важен: без него значение запишется строкой "true", а не логическим значением. Для варианта с путём флаг --raw не нужен, чтобы значение записалось строкой в кавычках.
Нет SSH? Скачайте файл по SFTP или откройте в файловом менеджере хостинга. Плагинов, показывающих лог прямо в wp-admin, лучше избегать, если вы не доверяете им полностью: вы даёте плагину доступ на чтение файла, полного серверных подробностей.
Если нужен готовый блок для wp-config под вашу конфигурацию, вместе с безопасным путём за пределами корня и подходящим правилом для сервера, генератор лога отладки WordPress соберёт его за вас.
Выключайте, когда закончили
Ядро WordPress не ротирует и не обрезает debug.log. На сайте, который выдаёт уведомление при каждой загрузке страницы, файл растёт без ограничений и может забить диск — а это уронит сайт куда сильнее, чем баг, который вы искали. Включите логирование, воспроизведите проблему, прочитайте лог и верните WP_DEBUG в false.
Очистить файл, не удаляя его:
: > wp-content/debug.log
Если лог остаётся пустым
Проверяйте по порядку. WP_DEBUG равна false — самая частая причина, которая молча отключает всё остальное. Константа стоит ниже строки «stop editing» в wp-config.php. Права доступа — PHP не может писать в wp-content или в указанный вами каталог. Фатальная ошибка до окончания загрузки wp-config, например синтаксическая ошибка в самом файле конфигурации, происходит слишком рано, чтобы логирование WordPress её поймало; такие ошибки уходят в собственный PHP-лог сервера. Хостинг переопределяет настройку — некоторые управляемые платформы фиксируют параметр PHP error_log или направляют логи в свою панель; в этом случае ваши константы заданы верно, просто вывод оказался в другом месте. Прежде чем считать конфигурацию сломанной, загляните в просмотрщик логов у хостера.
FAQ
Вопросы
Где находится лог отладки WordPress?
По умолчанию это wp-content/debug.log, прямо внутри папки wp-content. WordPress создаёт файл только тогда, когда в него действительно что-то записывается, поэтому его отсутствие ещё не означает, что логирование сломано. Если в WP_DEBUG_LOG вместо true указан путь к файлу, лог пишется по этому пути.
Почему в wp-content нет файла debug.log?
Три частые причины. WP_DEBUG равен false, поэтому WordPress вообще не включает логирование, что бы ни стояло в WP_DEBUG_LOG. Либо ошибок ещё не было и файл просто не создан. Либо PHP не может писать в wp-content из-за прав доступа. Сначала проверьте константы, потом права.
Может ли кто угодно скачать мой debug.log?
Как правило, да. Файл wp-content/debug.log лежит внутри корня сайта, и никакие правила доступа его не закрывают, поэтому запрос к этому адресу из браузера часто отдаёт файл целиком. В логах отладки обычно есть абсолютные пути на сервере, ошибки базы данных и фрагменты запросов. Вынесите лог за пределы корня сайта или закройте его в конфигурации сервера.
Чем WP_DEBUG_LOG отличается от WP_DEBUG_DISPLAY?
WP_DEBUG_LOG записывает ошибки в файл. WP_DEBUG_DISPLAY выводит их в HTML страницы, где их видит любой посетитель. На рабочем сайте нужно логирование включённым, а вывод выключенным. Обе константы полностью игнорируются, если WP_DEBUG не равен true, — именно этот шаг чаще всего и пропускают.
Как читать лог отладки WordPress?
По SSH запустите tail -f по пути к логу и наблюдайте, как новые записи появляются вживую, пока вы воспроизводите проблему. Без SSH скачайте файл по SFTP или откройте его в файловом менеджере хостинга. Читайте снизу вверх: PHP дописывает новые записи в конец файла.
Замедляет ли включённый WP_DEBUG рабочий сайт?
Незначительно, и главный риск не в скорости, а в диске. Подробное логирование на посещаемом сайте способно раздуть debug.log до гигабайтов и забить диск, а это уронит сайт целиком. Включите, воспроизведите баг, прочитайте лог и выключите обратно. Ядро WordPress не ротирует и не обрезает этот файл.