Отладка .htaccess: error_log, LogLevel rewrite:trace, чтение логов

Большинство проблем с .htaccess диагностируются за 1–2 минуты, если знать, куда смотреть. Главный инструмент — error_log: там почти всегда точная строка и причина. Для пошаговой трассировки mod_rewrite — директива LogLevel alert rewrite:trace3 в конфиге сервера. Без доступа к конфигу — онлайн-инструменты этого сайта.

Где error_log и как его читать

Где найти error_log зависит от хостинга — подробная сводка в хабе «.htaccess на хостингах» → раздел про error.log. Краткий справочник:

  • cPanel — «Metrics → Errors» или файл ~/logs/error_log.
  • ISPmanager — раздел «Журналы» в панели.
  • Plesk — «Logs» сайта в панели.
  • VPS / выделенный/var/log/apache2/error.log (Debian/Ubuntu) или /var/log/httpd/error_log (CentOS/RHEL); для конкретного сайта — путь из директивы ErrorLog в его vhost.

Как читать запись: ищите имя своего .htaccess и следующие ключевые сообщения:

  • Invalid command 'X', perhaps misspelled or defined by a module not included in the server configuration — опечатка в директиве, или модуль не загружен.
  • … not allowed here — директива есть, но AllowOverride не включает нужную группу (подробнее про AllowOverride).
  • client denied by server configuration — запрос заблокирован правилом доступа.
  • Request exceeded the limit of 10 internal redirects — бесконечная рекурсия в rewrite-правилах.

Запись в error_log обычно содержит: дату и время, уровень ([error], [warn]), имя файла и номер строки .htaccess (например, /var/www/site/public_html/.htaccess:5) и само сообщение. Номер строки — быстрый способ найти проблемное место.

LogLevel rewrite:trace — пошаговая трассировка mod_rewrite

Директива LogLevel alert rewrite:trace3 заставляет Apache печатать каждый шаг обработки mod_rewrite в error_log. Уровни: trace1 (минимум) … trace8 (максимум детализации). Для большинства задач достаточно trace3trace5.

Важно: эта директива работает только в конфиге сервера или vhost-конфиге — в блоке <Directory>, <VirtualHost> или глобально. В .htaccess LogLevel не работает.

.htaccessкопировать
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example.com/public_html

    # Трассировка mod_rewrite — только на время отладки!
    # Снимите после диагностики, иначе error.log вырастет огромным.
    LogLevel alert rewrite:trace3

    <Directory /var/www/example.com/public_html>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

После добавления — перезапустите Apache (apachectl restart) и сделайте запрос. В error_log появятся строки трейса. Пример (вывод сокращён):

.htaccessкопировать
[rewrite:trace3] [rid#7f…][perdir /var/www/site/] strip per-dir prefix: /var/www/site/blog/5 -> blog/5
[rewrite:trace4] [rid#7f…][perdir /var/www/site/] applying pattern '^blog/([0-9]+)$' to uri 'blog/5'
[rewrite:trace4] [rid#7f…][perdir /var/www/site/] RewriteCond: input='blog/5' pattern='^blog/([0-9]+)$' => matched
[rewrite:trace2] [rid#7f…][perdir /var/www/site/] rewrite 'blog/5' -> '/post.php?id=5'
[rewrite:trace2] [rid#7f…][perdir /var/www/site/] local path result: post.php?id=5
[rewrite:trace1] [rid#7f…][perdir /var/www/site/] pass through /var/www/site/post.php

Как читать: applying pattern '…' to uri '…' — какое правило применяется к какому URL; => matched / => not-matched — сработало ли условие; rewrite '…' -> '…' — во что переписан URL; [L] removed all rules — флаг [L] остановил обработку. Смотрите первое место, где результат расходится с ожидаемым.

RewriteLog удалён в Apache 2.4

В Apache 2.2 для трассировки mod_rewrite использовались директивы RewriteLog (путь к файлу) и RewriteLogLevel (уровень). В Apache 2.4 они удалены — вместо них используйте LogLevel … rewrite:traceN как показано выше. Если видите RewriteLog или RewriteLogLevel в старых инструкциях или .htaccess — это синтаксис Apache 2.2, в 2.4 эти директивы дадут ошибку.

Если error_log не даёт чёткого указания на строку, используйте бинарный поиск: закомментируйте символом # ровно половину строк .htaccess, обновите страницу. Если ошибка пропала — проблема в закомментированной половине. Если осталась — в не-закомментированной. Делите оставшуюся половину снова и повторяйте, пока не останется 1–2 строки. Это быстро: при 32 строках — максимум 5 итераций.

При этом помните о зависимостях: если строки в вашем блоке связаны (например, RewriteCond относится к следующему RewriteRule), комментируйте блоками, а не отдельными строками.

apachectl configtest

Команда apachectl configtest (или apache2ctl -t, или httpd -t) проверяет синтаксис конфига сервера (все .conf-файлы Apache) — и выводит «Syntax OK» или список ошибок с номерами строк. Полезна при правке vhost-конфигов.

Важно: apachectl configtest не проверяет .htaccess — они применяются только при реальных запросах. Для проверки .htaccess используйте линтер /check/ и error_log после реального запроса.

Чтение access_log

access_log (обычно /var/log/apache2/access.log) записывает каждый HTTP-запрос: IP-клиента, дату, метод, URL, код ответа, размер, referer, User-Agent. Формат по умолчанию — Combined Log Format.

Что искать: статусы 500 (ошибка конфигурации), 403 (запрещён доступ), 404 (не найден). Для анализа паттернов (флуд, боты, подозрительные запросы) — инструмент /log-analyze/.

Онлайн-инструменты

  • Линтер .htaccess — проверяет синтаксис, баланс блоков, устаревшие директивы Apache 2.4, опечатки в именах. Заменяет apachectl configtest для .htaccess.
  • Тестер RewriteRule — пошаговая трассировка правил на конкретном URL: какое правило сработало, что вернул каждый RewriteCond, во что превратился адрес. Аналог LogLevel rewrite:trace, но онлайн.
  • Объяснялка .htaccess — построчный разбор файла: что делает каждая директива.
  • Симулятор нагрузки — показывает, какие правила создают наибольший оверхед при каждом запросе.
  • Аудит безопасности .htaccess — поиск уязвимых конфигураций.
  • Diff двух .htaccess — сравнение двух версий файла, последствия изменений.

Рекомендуемый порядок отладки

  1. Открыть error_log — почти всегда там точная строка и причина. Это первый шаг всегда.
  2. Линтер /check/ — прогнать файл, найти синтаксические ошибки, опечатки, устаревшие директивы.
  3. Объяснялка — если непонятно, что делает та или иная строка.
  4. Тестер /rewrite/ — если проблема с mod_rewrite (правило не срабатывает, неправильный редирект).
  5. Бинарный поиск — если предыдущие шаги не помогли: закомментировать половину и делить дальше.
  6. LogLevel alert rewrite:trace3 — если есть доступ к конфигу сервера и нужна пошаговая трассировка в error_log.