Отключение логирования отдельных запросов Apache с помощью SetEnvIf
Почему это нужно
По умолчанию Apache логирует все запросы в access.log. Это искажает статистику страниц при использовании анализаторов по типу Webalizer или AWStats, если в логи попадают:
- запросы мониторинга (например, Monit, Nagios);
- поисковые пауки;
- обращения с вашего внутреннего IP или тестовых машин;
- встроенные ресурсы (iframe), которые удваивают просмотры;
- массовые запросы из‑за ботов.
Цель — исключить такие запросы из логов, не влияя на работу сайта и не теряя важных записей об ошибках.
Как работает SetEnvIf — кратко
SetEnvIf устанавливает переменные окружения для текущего запроса, если определённое поле совпадает с регулярным выражением. Формат:
SetEnvIf attribute regex env-variable- attribute — одно из полей (Request_URI, User-Agent, Remote_Addr, Remote_Host, Referer, и др.).
- regex — Perl-совместимое регулярное выражение.
- env-variable — имя метки, например dontlog.
Позже в директиве CustomLog можно указать условие env=!dontlog, чтобы исключать из логирования помеченные запросы.
Контексты размещения
SetEnvIf можно использовать в:
- глобальной конфигурации Apache (для всего сервера),
- конфигурации виртуального хоста (vhost),
- внутри
(для каталога и подпапок), - в .htaccess (если AllowOverride FileInfo включён).
Примеры популярных случаев
- Исключить монитор Monit, который запрашивает /monit/token каждую минуту:
SetEnvIf Request_URI "^/monit/token$" dontlog- Исключить iframe /iframe/iframe.html:
SetEnvIf Request_URI "^/iframe/iframe.html$" dontlog- Не логировать Internet Explorer:
SetEnvIf User_Agent "(MSIE)" dontlog- Клиенты с хостом, оканчивающимся на bla.example.com:
SetEnvIf Remote_Host "bla.example.com$" dontlog- Конкретный IP-адрес:
SetEnvIf Remote_Addr "192\.168\.0\.154" dontlog- robots.txt:
SetEnvIf Request_URI "^/robots\.txt$" dontlog- Несколько поисковых ботов (без учёта регистра):
SetEnvIfNoCase User-Agent "Slurp/cat" dontlog
SetEnvIfNoCase User-Agent "Ask Jeeves/Teoma" dontlog
SetEnvIfNoCase User-Agent "Googlebot" dontlog
SetEnvIfNoCase Remote_Host "fastsearch.net$" dontlog- Исключить запросы к статическим расширениям (gif, jpg, png, css, js и др.):
SetEnvIfNoCase Request_URI "\.(gif)|(jpg)|(png)|(css)|(js)|(ico)|(eot)$" dontlog- Не логировать переходы с собственного домена:
SetEnvIfNoCase Referer "www\.mydomain\.com" dontlogКак отключить логирование помеченных запросов
Найдите вашу директиву CustomLog (в конфигурации сервера или vhost):
CustomLog /var/log/apache2/access.log combinedи добавьте env=!dontlog:
CustomLog /var/log/apache2/access.log combined env=!dontlogАналогично при использовании cronolog или конвейера (pipe):
CustomLog "|/usr/bin/cronolog --symlink=/var/log/httpd/access.log /var/log/httpd/access.log_%Y_%m_%d" combined env=!dontlogПосле правок перезапустите Apache.
Полный пример конфигурации виртуального хоста
ServerName www.example.com
DocumentRoot /var/www/example
# Не логировать монитор и iframe
SetEnvIf Request_URI "^/monit/token$" dontlog
SetEnvIf Request_URI "^/iframe/iframe.html$" dontlog
# Не логировать статические файлы
SetEnvIfNoCase Request_URI "\.(gif|jpg|png|css|js|ico|eot)$" dontlog
# Логирование с исключением помеченных запросов
CustomLog /var/log/apache2/example-access.log combined env=!dontlog
ErrorLog /var/log/apache2/example-error.log
Регулярные выражения и советы по написанию
- Экранируйте точки и слеши, когда нужно точное совпадение: . и /.
- ^ — начало строки; $ — конец строки. Для точного совпадения используйте оба.
- SetEnvIf чувствителен к регистру; SetEnvIfNoCase — нет.
- Тестируйте регулярки на реальных URL и user‑agent, прежде чем применять глобально.
Полезный приём: сначала включите логирование метки (например, поместите временно другую CustomLog с env=dontlog), чтобы убедиться, какие запросы будут отфильтрованы.
Когда это не сработает и ограничения
- SetEnvIf оперирует на уровне запроса Apache; если доступ идёт через обратный прокси или load balancer, Remote_Addr может быть адресом прокси — учитывайте X-Forwarded-For и конфигурацию прокси.
- Если вы используете внешний логгер или уже фильтруете логи на этапе агрегации (например, в ELK), лучше делать фильтрацию централизованно.
- Для более сложной логики (состояния, частоты, динамических правил) нужна внешняя система или модуль типа mod_security.
- Удаление записи из логов означает, что вы не сможете использовать этот лог для ретроспективного анализа именно этих запросов.
Альтернативные подходы
- Фильтрация на стороне системы логирования (Logstash, Fluentd, rsyslog) — удобно, если у вас централизованная инфраструктура.
- Использовать модуль mod_security для сложных правил блокировки и логики.
- Конфигурировать логи на прокси/баланcировщике, если он принимает большую часть трафика.
- Временно включать отдельный лог для мониторинга и потом архивировать/удалять его.
Мини‑методология внедрения (шаги)
- Определите, какие запросы нужно исключить (списки URL, user-agent, IP/хаost).
- Напишите и протестируйте SetEnvIf/SetEnvIfNoCase локально или в staging.
- Временно включите отдельный лог для меток, чтобы убедиться в корректности.
- Обновите CustomLog с env=!метка.
- Перезапустите Apache и проверяйте access.log и новый лог меток.
- Наблюдайте неделю и корректируйте правила.
Тестирование и отладка
- Включите временный лог для помеченных запросов:
CustomLog /var/log/apache2/example-dontlog.log combined env=dontlog- Отправьте тестовые запросы curl/браузером и проверьте, что они попадают в dontlog-файл, а не в основной.
- Используйте утилиты для проверки регулярных выражений.
- Проверьте поведение при проксировании и X-Forwarded-For.
Критерии приёмки
- После перезапуска Apache лог main access.log не содержит тестовых запросов.
- Тестовые запросы попадают в временный лог env=dontlog (если он включён).
- Не нарушена функциональность страниц и API.
- Мониторинг и оповещения (если есть) продолжают корректно работать.
Роли и чеклист
Sysadmin:
- Реализовать правило в конфигурации vhost или глобально.
- Перезапустить/перезагрузить Apache.
- Настроить резервное логирование.
Разработчик:
- Проверить, что приложение не полагается на логирование специфических внутренних URL.
- Предоставить список URL и user‑agent для исключения.
SRE/DevOps:
- Проверить совместимость с системой агрегирования логов.
- Убедиться, что прокси/балансировщик не скрывает реальные IP.
Безопасность и конфиденциальность
- Не исключайте из логов безопасностно значимые запросы, которые могут понадобиться при расследовании инцидентов.
- Не логируйте чувствительную информацию (пароли, токены) в access.log.
- При использовании X-Forwarded-For убедитесь, что заголовок доверенный и корректно обрабатывается.
Полезные ссылки
- Apache Module mod_setenvif: https://httpd.apache.org/docs/current/mod/mod_setenvif.html
- Примеры и обсуждения: http://forums.digitalpoint.com/showthread.php?p=488716
- Локальные руководства и примеры: http://www.keithjbrown.co.uk/vworks/unix/logs.php
- Больше примеров правил: http://www.htaccesselite.com/htaccess/setenvif-examples-vt141.html
Краткое резюме
SetEnvIf и SetEnvIfNoCase — простой и эффективный способ пометить и исключить из логов нежелательные запросы на уровне Apache. Это снижает шум в access.log, улучшает качество статистики и помогает сосредоточиться на релевантных для вас обращениях. Тестируйте правила в контролируемой среде и не забывайте учитывать прокси и балансировщики.
Примечание: директива Server_Addr доступна только в версиях Apache позже 2.0.43.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента