Apache Web server может не только показывать
страницы пользователям, но и со всей
тщательностью записывать данные об их
активности и ошибках. По умолчанию, все
сведения о запросах пользователей пишутся
в один лог, а об ошибках - в другой.
Естественно, смысл записей и их положение
на сервере можно произвольно настраивать,
чем мы сегодня и займемся.

Default Logs

Как я уже сказал в предисловии, по
умолчанию сервер пишет лог в два файла - /var/log/httpd/access_log
и error_log в той же директории. Такое положение
дел определяется, конечно, в httpd.conf
параметрами TransferLog и ErrorLog. Примерно это
происходит так:

TransferLog /data/apache/logs/gen_msg
ErrorLog /data/apache/logs/error_msg

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


ServerName www.company_a.com
DocumentRoot /data/apache/co_a/html
TransferLog /data/apache/co_a/logs/gen_msg
ErrorLog /data/apache/co_a/logs/error_msg



ServerName www.company_b.com
DocumentRoot /data/apache/co_b/html
TransferLog /data/apache/co_b/logs/gen_msg
ErrorLog /data/apache/co_b/logs/error_msg

Ясно, что в таком конфиге не только
документы будут разделяться по разным
каталогам, но и логи. Отметьте, что записи лежат вне DocumentRoot,
что довольно неплохо для обеспечения
безопасности.

Уровень логов

Существует несколько уровней при помощи
которых можно настроить глубину записи
активности Web-сервера. Уровни логов такие: emerg,
alert, crit, error, warn, notice, info
и debug. Дописывая определение уровня в
конец директивы, управляющей логгированием,
мы можем определить, что именно писать.
Например, я хочу заставить Apache записывать
неотложные записи и предупреждения только
для одного из доменов. В контейнере нужного
домена делаем так:

 
... 
LogLevel alert 

Формат Логов 

Формат, в котором сервер делает записи,
так же можно произвольно менять. Делается
это директивой LogFormat все в том же htttpd.conf.
По дефолту выглядит запись примерно так:

12.127.17.72 - russell [21/Jun/2004:11:50:20 -0500] 
"GET /cgi-bin/admin/index.cgi HTTP/1.1" 200 5528

В примере записан IP адрес или имя хоста,
идентификационная информация клиента, имя
пользователя, дата и время. В кавычках -
метод запроса и имя запрашиваемого файла с
версией HTTP. После этого - результат, статус и
количество переданных байт. В примере видно,
что код 200 (ОК).

Для изменения формата  надо описать его
в LogFormat и передать имя потом в описание лога.
Если описание дается вне контейнера, то его
можно использовать для любого лога, в
данном примере задается путь и формат лога:

LogFormat "Date: %t, Host: %h, User: %u, File Requested: %r" simple 
... 

... 
CustomLog /data/apache/co_a/logs/gen_msg simple 
... 

Помимо приведенных в примере кодов можно
использовать %a для IP адреса, %b для
количества байт, %f для имени файла, %i для
заголовка запроса, %s для статуса. Полностью
список кодов можно найти
на сайте Apache
. Пример работы приведенного
выше лога:

Date: [21/Jun/2004:22:21:10 -0500], 
Host: 12.127.17.72, User: russell, 
File Requested: GET /cgi-bin/admin/index.cgi HTTP/1.1

Еще один пример - предположим я хочу
получить в лог только заголовок запроса от
другого сайта, поисковой машины.

CustomLog search_eng_log "%{Referer}i"

Обратите внимание, что {Referer} идет между %
и i, а так же на то, что пропущено
создание имени для упрощения описания.
Такой лог будет складировать адрес
поисковика и поисковый параметр - очень
удобно для понимания кто и что находит на
сайте. Для
примера можно попробовать писать {User-agent}
пытаясь узнать кто и каким броузером лазит
на сайт. 

Включение и исключение

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

SetEnvIf Remote_Addr "12.127.17.72" my_stuff
CustomLog logs/my_access complex env=my_stuff
CustomLog logs/gen_msg simple env=!my_stuff

Ротация

Всем понятно, что логи приличного сервера
разрастаются довольно быстро. По умолчанию
они очищаются каждую неделю: access_log
копируется в access_log.1, access_log.1 в access_log.2 и так
далее (в обратном порядке разумеется).
Однако если вы устанавливаете собственные
логи, то нужно задать и их ротацию. Сделать
это можно несколькими путями. ИМХО лучше
всего написать простой скрипт для cron, который
затем регулярно выполнять:

#!/bin/bash
mv -f gen_msg.2 gen_msg.3
mv -f gen_msg.1 gen_msg.2
mv -f gen_msg gen_msg.1
apachectl graceful

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии