Возник вопрос, как в конфигурационных файлах NGINX переопределяется логирование доступа. В документации вроде всё написано понятно, но, чтобы до конца разобраться, мне пришлось выполнить несколько тестов.
Без директив error_log, access_log
В конфигурационном файле nginx.conf, а также во всех подключаемых файлах отсутствуют директивы error_log, access_log.
Результат. Сообщения пишутся в файлы: /var/log/nginx/access.log (лог доступа) и /var/log/nginx/error.log (лог ошибок).
Директивы access_log в секции http
В секции http объявляем директиву access_log
http { ... access_log /var/log/nginx-access.log main; ... }
Результат. После перезагрузки NGINX сообщения пишутся в файл /var/log/nginx-access.log
Добавляем второй access_log сразу за первым
http { ... access_log /var/log/nginx-access.log main; access_log /var/log/nginx-access-2.log compress; ... }
Результат. После перезагрузки NGINX сообщения пишутся в оба лога. Мы получаем одни и те же записи в логах, но записи имеют разную структур: зависит от того, как настроены log_format main и log_format compress.
Отмена access_log
Сразу за строками access_log добавляем access_log off
http { ... access_log /var/log/nginx-access.log main; access_log /var/log/nginx-access-2.log compress; access_log off; ... }
Результат. После перезагрузки NGINX сообщения в логи не пишутся.
Добавим следом еще одну директиву access_log
http { ... access_log /var/log/nginx-access.log main; access_log /var/log/nginx-access-2.log compress; access_log off; access_log /var/log/nginx-access.log main; ... }
Результат. После перезагрузки NGINX сообщения в логи не пишутся. Директива access_log off действует на всем уровне секции http независимо, где она определена в конце или в самом начале.
Удалим все директивы access_log из секции http, кроме access_log off и добавим access_log в секцию server.
http { ... access_log off; server { server_name host.name.one; access_log /var/log/nginx-access.log main; } server { server_name host.name.two; } }
Результат. После перезагрузки NGINX для сервера host.name.one сообщения пишутся в лог, а для сервера host.name.two – нет. Если директива access_log off однажды определена, то переопределить ее можно только во вложенной секции.
Переместим директиву access_log в самый низ секции server
http { ... access_log off; server { server_name host.name.one; # Блокировка нежелательных ботов if ($black_agent = "1") { return 404; } # Редирект на адреса без слеша в конце rewrite ^/(.*)/$ /$1 permanent; access_log /var/log/nginx-access.log main; } }
Результат. Сообщения блокировки (404) и редиректа (301) в лог пишутся, на них не действует родительский access_log off, потому что в дочерней секции server определена директива access_log – пусть и в самом конце, это неважно.
Дополнение. Команды для тестов логирования
Удалить журналы и перезапустить NGINX
sudo rm /var/log/nginx/*; sudo systemctl restart nginx;
Проверить конфигурацию на корректность и перезапустить NGINX
sudo nginx -t && sudo systemctl restart nginx
Запрос для ответа с кодом 200 (динамический файл)
wget --spider -S "http://site/sitemap.xml" 2>&1 | grep "HTTP/" | awk '{print $2}'
Запрос для ответа с кодом 200 (статический файл)
wget --spider -S "http://site.ru/robots.txt/" 2>&1 | grep "HTTP/" | awk '{print $2}'
Запрос для ответа с кодами 301, 200 (настроена переадресация)
wget --spider -S "http://sub.site.ru/robots.txt" 2>&1 | grep "HTTP/" | awk '{print $2}'
Блокировка без ответа, код 444 (настроена блокировка)
wget --method=PUT "http://site.ru/file.txt"
Блокировка бота c ответом, код 404 (настроена блокировка)
wget -U SemrushBot --spider -S "http://site.ru/" 2>&1 | grep "HTTP/" | awk '{print $2}'