Spec-Zone.ru › Apache HTTP Server

Лог-файлы

Для эффективного управления веб-сервером необходимо получать обратную связь о работе и производительности сервера, а также о возможных проблемах. Сервер Apache HTTP предоставляет очень полные и гибкие возможности ведения журнала. В данном документе описывается, как настроить возможности ведения журнала и как понимать, что содержат логи.

Обзор

Связанные модули Связанные директивы
  • mod_log_config
  • mod_log_forensic
  • mod_logio
  • mod_cgi

Сервер Apache HTTP предоставляет различные механизмы для ведения журнала всего, что происходит на сервере, от первоначального запроса через процесс сопоставления URL до окончательного завершения соединения, включая любые ошибки, которые могли возникнуть в процессе. Кроме того, сторонние модули могут предоставлять возможности ведения журнала или вставлять записи в существующие файлы журналов, а приложения, такие как CGI-программы, скрипты PHP или другие обработчики, могут отправлять сообщения в журнал ошибок сервера.

В данном документе рассматриваются модули ведения журнала, которые являются стандартной частью сервера http.

Предупреждение о безопасности

Любой, кто может записывать в каталог, куда Apache httpd записывает файл журнала, практически наверняка получит доступ к uid, под которым запущен сервер, который обычно является root. Не предоставляйте людям права записи в каталог, где хранятся логи, не осознавая последствий; обратитесь к документу советы по безопасности для получения подробной информации.

Кроме того, файлы журналов могут содержать информацию, предоставленную непосредственно клиентом, без экранирования. Поэтому злонамеренные клиенты могут вставлять управляющие символы в файлы журналов, поэтому при работе с сырыми логами следует проявлять осторожность.

Журнал ошибок

Связанные модули Связанные директивы
  • core
  • ErrorLog
  • ErrorLogFormat
  • LogLevel

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

Журнал ошибок обычно записывается в файл (обычно error_log в системах Unix и error.log в Windows и OS/2). В системах Unix также можно настроить сервер на отправку ошибок в syslog или перенаправить их в программу.

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

[Fri Sep 09 10:42:29.902022 2011] [core:error] [pid 35708:tid 4328636416] [client 72.15.99.187] File does not exist: /usr/local/apache2/htdocs/favicon.ico

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

В журнале ошибок может отображаться очень широкий спектр сообщений. Большинство из них похожи на пример выше. В журнал ошибок также будет включена отладочная информация из CGI-скриптов. Любая информация, записанная в stderr CGI-скриптом, будет скопирована непосредственно в журнал ошибок.

Размещение маркера %L в журнале ошибок и журнале доступа позволит получить идентификатор записи журнала, с помощью которого вы сможете сопоставить запись в журнале ошибок с записью в журнале доступа. Если загружен mod_unique_id, его уникальный идентификатор запроса также будет использоваться в качестве идентификатора записи журнала.

При тестировании часто бывает полезно непрерывно следить за журналом ошибок в поисках проблем. В системах Unix это можно сделать, используя:

tail -f error_log

Ведение журнала по модулям

Директива LogLevel позволяет задать уровень серьёзности журнала на уровне каждого модуля. Таким образом, если вы устраняете проблему только с одним конкретным модулем, вы можете увеличить объём ведения журнала для него, не получая при этом подробную информацию о других модулях, которые вас не интересуют. Это особенно полезно для модулей, таких как mod_proxy или mod_rewrite, где вам нужно узнать подробности о том, что он пытается сделать.

Сделайте это, указав имя модуля в вашей директиве LogLevel.

LogLevel info rewrite:trace5

Это устанавливает основной уровень LogLevel в info, но увеличивает его до trace5 для mod_rewrite.

Это заменяет директивы ведения журнала по модулям, такие как RewriteLog, которые присутствовали в более ранних версиях сервера.

Журнал доступа

Связанные модули Связанные директивы
  • mod_log_config
  • mod_setenvif
  • CustomLog
  • LogFormat
  • SetEnvIf

Журнал доступа сервера записывает все запросы, обработанные сервером. Расположение и содержимое журнала доступа контролируются директивой CustomLog . Директива LogFormat может быть использована для упрощения выбора содержимого логов. В этом разделе описывается, как настроить сервер на запись информации в журнал доступа.

Конечно, хранение информации в журнале доступа — это только начало управления логами. Следующий шаг — анализ этой информации для получения полезных статистических данных. Анализ логов в общем случае выходит за рамки данного документа и не является непосредственной задачей веб-сервера. Для получения дополнительной информации по этой теме и для приложений, выполняющих анализ логов, ознакомьтесь с Open Directory.

Различные версии Apache httpd использовали другие модули и директивы для управления ведением журнала доступа, включая mod_log_referer, mod_log_agent и директиву TransferLog . Директива CustomLog теперь объединяет функциональность всех более старых директив.

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

Общий формат журнала

Типичная конфигурация для журнала доступа может выглядеть следующим образом.

LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog logs/access_log common

Это определяет псевдоним common и связывает его с определённой строкой формата журнала. Строка формата состоит из директив процента, каждая из которых сообщает серверу о регистрации определённой части информации. Буквенные символы также могут быть включены в строку формата и будут скопированы непосредственно в выходные данные журнала. Символ кавычки (") должен быть экранирован, поместив перед ним обратную косую черту, чтобы предотвратить его интерпретацию как окончания строки формата. Строка формата также может содержать специальные управляющие символы "\n" для новой строки и "\t" для табуляции.

Директива CustomLog создаёт новый файл журнала, используя определённый псевдоним. Имя файла журнала доступа является относительным к ServerRoot, если оно не начинается с косой черты.

Приведённая выше конфигурация запишет записи журнала в формате, известном как общий формат журнала (CLF). Этот стандартный формат может быть создан многими различными веб-серверами и прочитан многими программами анализа логов. Записи файла журнала, созданные в формате CLF, будут выглядеть примерно так:

127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

Ниже описана каждая часть этой записи журнала.

127.0.0.1 (%h)
Это IP-адрес клиента (удаленного хоста), который отправил запрос серверу. Если HostnameLookups установлено в On, сервер попытается определить имя хоста и записать его вместо IP-адреса. Однако, эта настройка не рекомендуется, так как она может значительно замедлить сервер. Вместо этого лучше использовать постпроцессор журналов, такой как logresolve, для определения имен хостов. Указанный здесь IP-адрес не обязательно является адресом машины, на которой находится пользователь. Если между пользователем и сервером существует прокси-сервер, этот адрес будет адресом прокси, а не исходной машины.
- (%l)
Дефис в выводе указывает, что запрашиваемая информация недоступна. В данном случае недоступна информация о личности клиента RFC 1413, определяемая identd на машине клиента. Эта информация очень ненадежна и почти никогда не должна использоваться, за исключением строго контролируемых внутренних сетей. Apache httpd даже не попытается определить эту информацию, если IdentityCheck не установлено в On.
frank (%u)
Это идентификатор пользователя, запрашивающего документ, как определено аутентификацией HTTP. Такое же значение обычно предоставляется скриптам CGI в переменной окружения REMOTE_USER. Если код состояния запроса (см. ниже) равен 401, то этому значению нельзя доверять, потому что пользователь еще не аутентифицирован. Если документ не защищен паролем, эта часть будет "-", как и предыдущая.
[10/Oct/2000:13:55:36 -0700] (%t)
Время получения запроса. Формат:
[day/month/year:hour:minute:second zone]
day = 2*digit
month = 3*letter
year = 4*digit
hour = 2*digit
minute = 2*digit
second = 2*digit
zone = (`+' | `-') 4*digit

Можно отобразить время в другом формате, указав %{format}t в строке формата журнала, где format это либо, как в strftime(3) из стандартной библиотеки C, либо один из поддерживаемых специальных маркеров. Подробности см. в mod_log_config строках формата.

"GET /apache_pb.gif HTTP/1.0" (\"%r\")
Строка запроса от клиента приводится в двойных кавычках. Строка запроса содержит много полезной информации. Во-первых, метод, используемый клиентом, это GET. Во-вторых, клиент запросил ресурс /apache_pb.gif, и, в-третьих, клиент использовал протокол HTTP/1.0. Также можно записывать одну или несколько частей строки запроса независимо. Например, строка формата "%m %U%q %H" запишет метод, путь, строку запроса и протокол, что даст такой же вывод, как "%r".
200 (%>s)
Это код состояния, который сервер отправляет клиенту. Эта информация очень ценна, потому что она показывает, привело ли обращение к успешному ответу (коды, начинающиеся с 2), перенаправлению (коды, начинающиеся с 3), ошибке, вызванной клиентом (коды, начинающиеся с 4), или ошибке на сервере (коды, начинающиеся с 5). Полный список возможных кодов состояния можно найти в спецификации HTTP (раздел 10 RFC2616).
2326 (%b)
Последняя часть указывает размер объекта, возвращенного клиенту, не включая заголовки ответа. Если клиенту не было возвращено никакого содержимого, это значение будет "-". Чтобы записать "0" для отсутствия содержимого, используйте %B.

Комбинированный формат журнала

Еще один часто используемый формат строки называется комбинированным форматом журнала. Его можно использовать следующим образом.

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
CustomLog log/access_log combined

Этот формат точно такой же, как общий формат журнала, с добавлением двух дополнительных полей. Каждое из дополнительных полей использует %{header}i, где заголовок может быть любым заголовком HTTP-запроса. Журнал доступа в этом формате будет выглядеть так:

127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"

Дополнительные поля:

"http://www.example.com/start.html" (\"%{Referer}i\")
Заголовок HTTP-запроса "Referer". Он указывает сайт, с которого, по заявлениям клиента, был произведён запрос. (Это должна быть страница, которая ссылается на или включает /apache_pb.gif).
"Mozilla/4.08 [en] (Win98; I ;Nav)" (\"%{User-agent}i\")
Заголовок HTTP-запроса User-Agent. Это идентификационная информация, которую клиентский браузер сообщает о себе.

Множественные журналы доступа

Несколько журналов доступа можно создать, просто указав несколько CustomLog директив в файле конфигурации. Например, следующие директивы создадут три журнала доступа. Первый содержит основную информацию CLF, а второй и третий — информацию о ссылке и браузере. Последние две CustomLog строки показывают, как имитировать эффект ReferLog и AgentLog директив.

LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog logs/access_log common
CustomLog logs/referer_log "%{Referer}i -> %U"
CustomLog logs/agent_log "%{User-agent}i"

Этот пример также показывает, что не обязательно определять псевдоним с помощью LogFormat директивы. Вместо этого, формат журнала можно указать непосредственно в CustomLog директиве.

Условные журналы

Иногда удобно исключать определённые записи из журналов доступа на основе характеристик запроса клиента. Это легко достигается с помощью переменных среды. Во-первых, переменная среды должна быть установлена для указания того, что запрос соответствует определённым условиям. Это обычно достигается с помощью SetEnvIf. Затем используется env= часть CustomLog директивы для включения или исключения запросов, где переменная среды установлена. Некоторые примеры:

# Mark requests from the loop-back interface
SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog
# Mark requests for the robots.txt file
SetEnvIf Request_URI "^/robots\.txt$" dontlog
# Log what remains
CustomLog logs/access_log common env=!dontlog

Например, рассмотрите регистрацию запросов от англоговорящих пользователей в один файл журнала, а от пользователей, не говорящих по-английски, — в другой.

SetEnvIf Accept-Language "en" english
CustomLog logs/english_log common env=english
CustomLog logs/non_english_log common env=!english

В сценарии кеширования хотелось бы узнать об эффективности кеша. Очень простой способ узнать это:

SetEnv CACHE_MISS 1
LogFormat "%h %l %u %t "%r " %>s %b %{CACHE_MISS}e" common-cache
CustomLog logs/access_log common-cache

mod_cache будет выполнено до mod_env и, при успехе, предоставит контент без него. В этом случае попадание в кеш запишется как -, а промах в кеше — как 1.

В дополнение к синтаксису env=, LogFormat поддерживает логирование значений в зависимости от кода HTTP-ответа:

LogFormat "%400,501{User-agent}i" browserlog
LogFormat "%!200,304,302{Referer}i" refererlog

В первом примере User-agent будет записан, если код HTTP-статуса равен 400 или 501. В других случаях вместо этого будет записан литеральный "-". Аналогично, во втором примере Referer будет записан, если код HTTP-статуса не равен 200, 204 или 302. (Обратите внимание на "!" перед кодами статуса).

Хотя мы только что показали, что условное логирование очень мощное и гибкое, это не единственный способ контролировать содержимое журналов. Журналы более полезны, когда они содержат полный учёт серверной активности. Часто проще просто обработать файлы журналов после того, как удалите запросы, которые не хотите учитывать.

Вращение журналов

Даже на умеренно загруженном сервере количество информации, хранящейся в файлах журналов, очень велико. Файл журнала доступа обычно увеличивается на 1 МБ или более на каждые 10 000 запросов. Поэтому периодически необходимо вращать файлы журналов, перемещая или удаляя существующие журналы. Это нельзя делать во время работы сервера, так как Apache httpd будет продолжать запись в старый файл журнала, пока он его держит открытым. Вместо этого сервер необходимо перезапустить после перемещения или удаления файлов журналов, чтобы он открыл новые файлы журналов.

Используя плавную перезагрузку, серверу можно дать указание открыть новые файлы журналов без потери каких-либо существующих или ожидающих подключений от клиентов. Однако для достижения этой цели серверу необходимо продолжать запись в старые файлы журналов, пока он завершает обработку старых запросов. Поэтому необходимо подождать некоторое время после перезагрузки, прежде чем выполнять какую-либо обработку файлов журналов. Типичный сценарий, который просто вращает журналы и сжимает старые журналы для экономии места, выглядит так:

mv access_log access_log.old
mv error_log error_log.old
apachectl graceful
sleep 600
gzip access_log.old error_log.old

Другой способ выполнить вращение журналов — использование трубопроводных журналов, как обсуждается в следующем разделе.

Трубопроводные журналы

Apache httpd может записывать файлы журнала ошибок и доступа через канал в другой процесс, а не напрямую в файл. Это значительно увеличивает гибкость логирования, без добавления кода в основной сервер. Чтобы записать журналы в канал, просто замените имя файла символом канала "|", а затем имя исполняемого файла, который должен принимать записи журналов на свой стандартный ввод. Сервер запустит процесс трубопроводного журнала при запуске сервера и перезапустит его, если он аварийно завершится во время работы сервера. (Это последнее свойство, почему мы можем называть этот метод "надёжным трубопроводным логированием").

Процессы трубопроводных журналов запускаются родительским процессом Apache httpd и наследуют идентификатор пользователя этого процесса. Это означает, что программы трубопроводных журналов обычно запускаются как root. Поэтому очень важно, чтобы программы были простыми и безопасными.

Одно важное применение трубопроводных журналов — возможность вращения журналов без перезагрузки сервера. В Apache HTTP Server есть простая программа под названием rotatelogs для этой цели. Например, чтобы вращать журналы каждые 24 часа, вы можете использовать:

CustomLog "|/usr/local/apache/bin/rotatelogs /var/log/access_log 86400" common

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

Как и в случае с условным логированием, трубопроводные журналы — очень мощный инструмент, но их не следует использовать, когда доступно более простое решение, такое как обработка журналов офлайн.

По умолчанию процесс трубопроводного журнала запускается без вызова оболочки. Используйте "|$" вместо "|", чтобы запустить с помощью оболочки (обычно с /bin/sh -c):

# Invoke "rotatelogs" using a shell
CustomLog "|$/usr/local/apache/bin/rotatelogs   /var/log/access_log 86400" common

Это было стандартным поведением для Apache 2.2. В зависимости от особенностей оболочки это может привести к дополнительному процессу оболочки на всё время работы программы трубопроводного журнала и проблемам обработки сигналов во время перезапуска. Для совместимости с Apache 2.2 также поддерживается запись "||" и эквивалентна использованию "|".

Примечание для Windows

Обратите внимание, что в Windows могут возникнуть проблемы при запуске многих процессов журналирования с использованием конвейера, особенно при работе HTTPD в качестве службы. Это вызвано недостатком оперативной памяти для рабочего стола. Объем оперативной памяти для рабочего стола, предоставляемый каждой службе, задается третьим аргументом параметра SharedSection в значении реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\SubSystems\Windows. Изменяйте это значение с осторожностью; обычные предосторожности при изменении реестра Windows применяются, но вы также можете исчерпать пул оперативной памяти для рабочего стола, если значение будет слишком высоким.

Виртуальные хосты

При запуске сервера с множеством виртуальных хостов существует несколько вариантов обработки файлов журналов. Во-первых, возможно использовать журналы так же, как и на сервере с одним хостом. Просто поместив директивы журналирования за пределами секций <VirtualHost> в основном контексте сервера, можно записывать все запросы в один и тот же журнал доступа и журнал ошибок. Этот метод не позволяет легко собирать статистику по отдельным виртуальным хостам.

Если директивы CustomLog или ErrorLog размещаются внутри секции <VirtualHost>, все запросы или ошибки для данного виртуального хоста будут записываться только в указанный файл. Любой виртуальный хост, для которого не заданы директивы журналирования, по-прежнему будет отправлять свои запросы в главные журналы сервера. Этот метод очень полезен для небольшого числа виртуальных хостов, но при большом количестве хостов он может быть сложным в управлении. Кроме того, он часто может создавать проблемы с недостаточным количеством дескрипторов файлов.

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

LogFormat "%v %l %u %t \"%r\" %>s %b" comonvhost
CustomLog logs/access_log comonvhost

Поле %v используется для записи имени виртуального хоста, обслуживающего запрос. Затем программу, такую как split-logfile, можно использовать для последующей обработки журнала доступа с целью разделения его на один файл на каждый виртуальный хост.

Другие файлы журналов

Связанные модули Связанные директивы
  • mod_logio
  • mod_log_config
  • mod_log_forensic
  • mod_cgi
  • LogFormat
  • BufferedLogs
  • ForensicLog
  • PidFile
  • ScriptLog
  • ScriptLogBuffer
  • ScriptLogLength

Запись фактического количества отправленных и полученных байтов

mod_logio добавляет два дополнительных LogFormat поля (%I и %O), которые записывают фактическое количество байтов, полученных и отправленных по сети.

Аудиторный журнал

mod_log_forensic обеспечивает аудиторную запись запросов клиентов. Журналирование выполняется до и после обработки запроса, поэтому в аудиторном журнале содержится две строки журнала на каждый запрос. Аудиторный регистратор очень строгий и не допускает настроек. Он может быть неоценимым инструментом для отладки и обеспечения безопасности.

Файл PID

При запуске Apache httpd сохраняет идентификатор процесса родительского процесса httpd в файл logs/httpd.pid. Это имя файла может быть изменено с помощью директивы PidFile. Идентификатор процесса предназначен для использования администратором при перезапуске и завершении демона путем отправки сигналов родительскому процессу; в Windows вместо этого используется опция командной строки -k. Дополнительную информацию см. на странице Остановка и перезапуск.

Журнал сценариев

Для облегчения отладки директива ScriptLog позволяет записывать входные и выходные данные CGI-скриптов. Это следует использовать только в тестовых условиях — не для активных серверов. Дополнительную информацию можно найти в документации по mod_cgi.

© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/logs.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API