NGINX | Отдельный лог для ботов

NGINX | Отдельный лог для ботов

Как вести отдельные логи (журналы) доступа для запросов от автоматизированных систем ботов в nginx?

Из документации NGINX нужно знать о существовании двух модулей:

  1. Модуль ngx_http_log_module
  2. Модуль ngx_http_map_module

Первый отвечает за сами файлы логов и стиль наполнения. Второй задаёт правила фильтрации HTTP-запросов, которые должны будут попадать в нужный нам лог.

Первый пишем внутри настроек файла «виртуального хоста» — например «efim360.ru.conf«. Второй пишем в главном конфигурационном файле «nginx.conf«.

Первый попадает в директиву «server«. Второй попадает в директиву «http«.

 

Как фильтрация ботов по логам будет выглядеть в файлах?

папка «/etc/nginx/sites-available» —>> «efim360.ru.conf» —>> «server»

server {

   # какие-то ваши настройки

   access_log /var/log/nginx/efim360.ru_access_amazon_bot.log combined if=$ua_amazon_bot;
   access_log /var/log/nginx/efim360.ru_access_google_bot.log combined if=$ua_google_bot;
   access_log /var/log/nginx/efim360.ru_access_yandex_bot.log combined if=$ua_yandex_bot;
   access_log /var/log/nginx/efim360.ru_access_semrush_bot.log combined if=$ua_semrush_bot;

   # какие-то ваши настройки

}

access_log — это само название директивы в NGINX. Это часть его синтаксиса.

/var/log/nginx/efim360.ru_access_amazon_bot.log — это путь до файла журнала, в который мы запишем нужный запрос

combined — это предопределённый формат записи элементов HTTP-запроса (значение по умолчанию). В вашем случаем могут быть любые дополнительные форматы, если их кто-то создавал.

if=$ua_amazon_bot — это условная конструкция, которая дёргает значение из переменной $ua_amazon_bot. В нашем примере получается так: если пользовательский агент содержит в своей строке что-то вида «amazonbot«, то в переменную $ua_amazon_bot попадает значение 1 в секции «http» основного конфигурационного файла. Когда проброс дойдёт до виртуального хоста до секции «server«, тогда там директива access_log распознает значение данной переменной и запишет его в соответствующий лог (журнал). Цифра 1 приведётся к логическому типу и вернёт true — значит нужно писать.

 

папка «/etc/nginx» —>> «nginx.conf» —>> «http»

http {

   # какие-то ваши настройки

   map $http_user_agent $ua_amazon_bot {
      default 0;
      ~*amazonbot 1;
   }
   map $http_user_agent $ua_google_bot {
      default 0;
      ~*googlebot 1;
   }
   map $http_user_agent $ua_semrush_bot {
      default 0;
      ~*semrushbot 1;
   }
   map $http_user_agent $ua_yandex_bot {
      default 0;
      ~*yandexbot 1;
   }

   # какие-то ваши настройки

}

 

Вместо нескольких директив «map», можно сделать одну, если вы чётко понимаете каких ботов по каким логам нужно разложить.

Мы же рассмотрели пример, где каждый конкретный вид бота пишется в отдельный файл журнала. Это удобно, потому что можно сразу получить детальную статистику по количество совершённых запросов ботом.

 

Как отделить логи с ботами и без них в nginx?

Мы можем пойти немного дальше и добавить ещё две директивы «map» в директиву «http» файла «nginx.conf«.

map $http_user_agent $ua_bot {
   default 0;
   ~*googlebot 1;
   ~*yandexbot 1;
   ~*semrushbot 1;
   ~*amazonbot 1;
}

map $ua_bot $ua_notbot {
   0 1;
}

Первая частично дублирует логику предыдущих четырёх директив «map«. Её цель — точно определить ботов и все им расставить 1. Если запрос придёт от бота, то в переменной $ua_bot будет храниться значение 1.

Вторая директива «map» примет значение из этой переменной. Если будет 1 то в $ua_notbot ничего не попадёт и тогда в новый файл лога НЕБОТОВ мы не получим запись. Если примет 0, тогда $ua_notbot получит значение 1 — оно приведётся к true и мы запишем запись.

access_log /var/log/nginx/efim360.ru_access_notbot.log combined if=$ua_notbot;

Мы как бы реализовали отрицание вида «if not».