Логирование Nginx с помощью модуля log в CentOS 7

Одним из наиболее важных источников информации для администратора являются логи, которые содержат данные о всех событиях в сети.

Логи веб-сервера (например, Nginx) хранят важную информацию о каждой попытке получить доступ к ресурсам через веб-сервер. Каждый посетитель сайта, открытое изображение или загруженный файл регистрируется в логе. Также в логах регистрируются ошибки. Для удобства работы рекомендуется поддерживать структуру логов.

Данное руководство поможет настроить модуль логирования Nginx и создать отдельные лог-файлы для виртуальных хостов. Также вы научитесь добавлять в стандартные логи дополнительную информацию о запросах (в данном случае это будет время обслуживания запроса).

Требования

  • Сервер CentOS 7 (инструкции по начальной настройке сервера – здесь).
  • Пользователь с доступом к sudo.
  • Предустановленный веб-сервер Nginx (чтобы установить Nginx, читайте эту статью).

1: Создание тестовых файлов

Сначала нужно создать несколько тестовых файлов в каталоге сайта, который поддерживает Nginx.

Когда Nginx (или любой другой веб-сервер) получает HTTP-запрос на файл, он открывает этот файл и обслуживает его содержимое пользователю, передавая его по сети. Чем меньше файл, тем проще его обслужить. Когда файл передается в полном объеме, запрос считается завершенным, после чего он регистрируется в логе.

Далее в этом руководстве вы узнаете, как изменять конфигурацию логов и добавить в них полезную информацию (например, продолжительность обработки каждого запроса). Научиться работать с логами, настраивать их и понять разницу между различными запросами вам помогут тестовые файлы разных размеров (на передачу которых уйдёт разное количество времени).

Создайте файл 1mb.test размером в один мегабайт в каталоге сайта:

sudo truncate -s 1M /usr/share/nginx/html/1mb.test

Затем создайте ещё два файла размером в 10 и 100 мегабайт:

sudo truncate -s 10M /usr/share/nginx/html/10mb.test
sudo truncate -s 100M /usr/share/nginx/html/100mb.test

Также для работы понадобится пустой файл:

sudo touch /usr/share/nginx/html/empty.test

2: Стандартные настройки логов

Модуль log встроен в ядро Nginx, потому его не нужно устанавливать.

Конфигурация модуля по умолчанию включает только основные настройки.

На свежем сервере Nginx регистрирует запросы в двух отдельных файлах:

  • /var/log/nginx/error.log (лог ошибок);
  • /var/log/nginx/access.log (лог, в котором хранится информация о запросах).

В /var/log/nginx/access.log вы можете узнать, среди прочего, к каким файлам обращаются пользователи, какие веб-браузеры они используют, их IP-адреса и код состояния HTTP, который Nginx отправляет на каждый запрос.

Чтобы увидеть, как выглядит стандартная строка лога access.log, запросите пустой файл:

curl -i http://localhost/empty.test

На экране появится ряд HTTP-заголовков:

HTTP/1.1 200 OK
Server: nginx/1.6.3
Date: Fri, 05 Aug 2016 22:05:03 GMT
Content-Type: application/octet-stream
Content-Length: 0
Last-Modified: Fri, 05 Aug 2016 22:04:55 GMT
Connection: keep-alive
ETag: "57a50d87-0"
Accept-Ranges: bytes

Этот ответ содержит следующие данные:

  • HTTP/1.1 200 OK – код состояния, отправленный Nginx (200 OK значит, что при обработке файла не возникло ошибки).
  • Content-Length: 0 – это значит, что возвращаемый документ нулевой длины.
  • Fri, 05 Aug 2016 22:05:03  – дата обработки процесса.

Теперь проверьте файл access.log.

sudo tail /var/log/nginx/access.log

В файле будет примерно такая запись:

::1 - - [05/Aug/2016:22:05:03 +0000] "GET /empty.test HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"

Nginx использует комбинированный формат логов; это стандартизированный формат логов доступа, который используется популярными веб-серверами для обеспечения интероперабельности. В этом формате все данные отделяются одним пробелом; черточки указывают на недостающие фрагменты информации.

Рассмотрим по порядку категории, присутствующие в файле:

  • Сначала указывается IP-адрес пользователя, сделавшего запрос (::1).
  • Затем идут данные об удалённом входе (здесь всегда будет прочерк, потому что Nginx не поддерживает такие данные).
  • Далее указано имя пользователя, создавшего подключение (в случае анонимного запроса в файле будет прочерк).
  • Дата запроса (она совпадает с датой из ответа веб-сервера).
  • Далее следует путь запроса, который включает в себя метод (GET), путь к запрашиваемому файлу (/empty.text) и протокол (HTTP/1.1).
  • Затем идёт код состояния ответа (в данном случае 200 ОК).
  • Длина передаваемого файла (0).
  • HTTP заголовок Referer, который содержит адрес документа, от которого поступил запрос. В этом примере он пуст, но если бы это был файл изображения, то Referer указал бы на страницу, на которой использовано это изображение. Заголовок Referer – это результат неправильного написания слова «referrer», что является частью стандарта HTTP.
  • Агент (в данном случае curl).
  • Заголовок X-Forwarded-For (содержит информацию об исходном IP-адресе, если запрос был направлен через прокси-сервер; в данном случае стоит прочерк).

Как видите, даже простая запись в логе access предоставляет много полезной информации о запросе. Однако на данный момент в файле отсутствует важный фрагмент данных – имя хоста в пути к файлу (localhost).

3: Настройка дополнительного лога запросов

Теперь попробуйте переопределить настройки логов Nginx по умолчанию (имеется в виду использование одного лога запросов для регистрации всех запросов). Создайте дополнительный лог для стандартного виртуального хоста (server-блока), который поставляется с Nginx.

Примечание: Узнать о виртуальных хостах Nginx больше можно по этой ссылке.

Рекомендуется использовать отдельный лог для каждого виртуального хоста – это позволяет отделить запросы одного сайта от другого. Более того, отдельные логи будут гораздо меньше, а потому их проще анализировать.

Откройте виртуальный хост Nginx по умолчанию в редакторе:

sudo vi /etc/nginx/nginx.conf

Найдите блок server:

. . .
server {
listen       80 default_server;
listen       [::]:80 default_server;
. . .

Добавьте в него следующие строки:

. . .
server {
listen 80 default_server;
listen [::]:80 default_server;
access_log /var/log/nginx/default-access.log;
error_log /var/log/nginx/default-error.log;
. . .

Директива access_log задаёт путь к логу запросов, а error_log указывает путь к логу ошибок. Эти файлы хранятся в одном каталоге со стандартными логами Nginx (/var/log/nginx).

Примечание: Если на одном сервере размещено несколько сайтов, можно использовать описательные имена логов (например, домены).

Сохраните и закройте файл.

Чтобы поддерживать отдельные логи для каждого виртуального хоста, вы должны применять предложенные выше настройки в новых виртуальных хостах Nginx.

Обновите настройки Nginx:

sudo systemctl restart nginx

Чтобы протестировать новую настройку, снова отправьте запрос:

curl -i http://localhost/empty.test

Теперь проверьте новый лог-файл:

sudo tail /var/log/nginx/default-access.log

4: Пользовательский формат логов

Теперь настройте пользовательский формат логов, поместив в них дополнительную информацию.

Примечание: В руководстве показано, как добавить в лог время обработки запроса.

Сначала нужно определить новый формат. Nginx позволяет устанавливать форматам уникальные имена.

Чтобы определить новый формат логов, создайте конфигурационный файл timed-log-format.conf в каталоге дополнительных конфигураций Nginx.

sudo nano /etc/nginx/conf.d/timed-log-format.conf

Поместите в файл такой код:

log_format timed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" "$http_x_forwarded_for" $request_time';

Сохраните и закройте его.

Директива log_format определяет новый формат лога. За ней следует уникальный идентификатор формата (в данном случае используется timed, но вы можете использовать любой другой).

Далее идёт сам формат. Для удобства он разделён на три строки. Для отображения информации о запросах Nginx использует переменные, перед которыми стоит символ $. Вместо них веб-сервер добавит в лог нужную информацию о запросах.

Этот формат почти полностью повторяет стандартный формат логов, но есть одно отличие: переменная $request_time в конце. Nginx использует эту переменную для регистрации времени обработки запроса.

Теперь у вас есть пользовательский формат логов, который называется timed. Но пока что этот формат не используется хостами. Настройте стандартный виртуальный хост для поддержки этого формата.

sudo vi /etc/nginx/nginx.conf

Найдите блок server и добавьте  имя нового формата в директиву access_log:

. . .
server {
listen 80 default_server;
listen [::]:80 default_server;
access_log /var/log/nginx/default-access.log timed;
error_log /var/log/nginx/default-error.log;
. . .

Сохраните и закройте файл.

Перезапустите Nginx:

sudo systemctl restart nginx

5: Тестирование новых настроек

Убедитесь, что всё работает должным образом. Для этого снова отправьте запрос curl всем тестовым файлам:

curl -i http://localhost/empty.test
curl -i http://localhost/1mb.test
curl -i http://localhost/10mb.test
curl -i http://localhost/100mb.test

Вы увидите, что на выполнение каждой последующей команды уходит всё больше времени.

Просмотрите лог:

sudo tail /var/log/nginx/default-access.log

Теперь в логе будет больше строк. Последние четыре записи относятся к сделанным только что запросам:

::1 - - [05/Aug/2016:22:14:04 +0000] "GET /empty.test HTTP/1.1" 200 0 "-" "curl/7.29.0" "-" 0.000
::1 - - [05/Aug/2016:22:14:04 +0000] "GET /1mb.test HTTP/1.1" 200 1048576 "-" "curl/7.29.0" "-" 0.000
::1 - - [05/Aug/2016:22:14:07 +0000] "GET /10mb.test HTTP/1.1" 200 10485760 "-" "curl/7.29.0" "-" 2.063
::1 - - [05/Aug/2016:22:15:10 +0000] "GET /100mb.test HTTP/1.1" 200 104857600 "-" "curl/7.29.0" "-" 47.318

Обратите внимание: каждая запись содержит новый путь, а размер запроса постоянно увеличивается.  Особенно важно последнее выделенное число. Это – время обработки запроса в миллисекундах.

Теперь виртуальный хост Nginx поддерживает пользовательский формат логов.

Заключение

Время обработки запроса в логе Nginx очень полезно при обслуживании динамических веб-сайтов. Этот показатель поможет обнаружить узкие места сайта и быстро найти запрос, на обработку которого уходит много времени.

Переменная $request_time – это только одна из многих доступных переменных Nginx. Другие переменные позволяют дополнить лог важными данными (например, добавить заголовок ответа).

Полный список переменных можно найти в документации модуля log.

Tags: , ,

Добавить комментарий