Анализ файла протокола веб-сервера

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

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

Приведенное ниже регулярное выражение соответствует комбинированному формату протокола NCSA:

$pattern = '/^([^ ]+) ([^ ]+) ([^ ]+) (\[[^\]]+\]) "(.*) (.*) (.*)" ([0-9\-]+)
([0-9\-]+) "(.*)" "(.*)"$/';

Обсуждение
Эта программа анализирует строки в комбинированном формате протокола (Combined Log Format) NCSA и показывает список страниц, отсортированных по количеству запросов к каждой странице:

$log_file = '/usr/local/apache/logs/access.log';
$pattern = '/^([^ ]+) ([^ ]+) ([^ ]+) (\[[^\]]+\]) "(.*) (.*) (.*)" ([0-9\-]+)
([0-9\-]+) "(.*)" "(.*)"$/';
$fh = fopen($log_file,'r') or die($php_errormsg);
$i = 1;
$requests = array();
while (! feof($fh)) {
// читаем каждую строку и удаляем начальные и конечные пробельные символы
if ($s = trim(fgets($fh,16384))) {
// сравниваем строку с шаблоном
if (preg_match($pattern,$s,$matches)) {
/* помещаем каждую совпавшую часть в переменную
* с соответствующим именем */
list($whole_match,$remote_host,$logname,$user,$time,
$method,$request,$protocol,$status,$bytes,$referer,
$user_agent) = $matches;
// ведем учет каждого запроса
$requests[$request]++;
} else {
// выводим предупреждение, если строка не соответствует шаблону
error_log("Can't parse line $i: $s");
}
}
$i++;
}
fclose($fh) or die($php_errormsg);
// сортируем массив (в обратном порядке) по количеству запросов
arsort($requests);
// выводим отформатированные результаты
foreach ($requests as $request => $accesses) {
printf("%6d %s\n",$accesses,$request);
}

Шаблон, используемый в функции preg_match(), соответствует строкам в комбинированном формате протокола, таким как:

10.1.1.162 - david [20/Jul/2001:13:05:02 -0400] "GET /sklar.css HTTP/1.0" 200
278 "-" "Mozilla/4.77 [en] (WinNT; U)"
10.1.1.248 - - [14/Mar/2002:13:31:37 -0500] "GET /php-cookbook/colors.html
HTTP/1.1" 200 460 "-" "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)"

В первой строке значение 10.1.1.162 представляет IP-адрес, с которого пришел запрос.


В зависимости от настроек сервера, вместо него может стоять имя хоста. Когда значения массива $matches присваиваются списку отдельных переменных, то имя хоста запоминается в переменной $remote_host. Следующий дефис (-) означает, что удаленный хост не предоставил имя пользователя через identd,1 поэтому переменной $logname присвоено значение «-».

Строка david содержит имя пользователя, предоставленное броузером с помощью базовой аутентификации HTTP, и присваивается переменной $user. Дата и время запроса, сохраненные в переменной $time, заключены в скобки. Этот формат даты и времени не распознается функцией strtotime(), поэтому, если вы хотите сделать вычисления, основанные на дате и времени запроса, то должны выполнить обработку для выделения каждой части форматированной строки времени. Следом, в кавычках, стоит первая строка запроса. Она состоит из метода (GET, POST, HEAD и т. д.), хранимого в переменной $method; запрошенного URI, хранящегося в переменной $request, и протокола, находящегося в переменной $protocol. Для запросов GET строка запроса является частью URI. Для запросов POST тело запроса, содержащее переменные, в протокол не заносится.

После запроса идет статус запроса, хранящийся в переменной $status.


Статус 200 означает, что запрос успешно выполнен. После статуса находится размер ответа в байтах, присвоенный переменной $bytes. Последние два элемента строки, причем каждый из них в кавычках, это страница, с которой сделана ссылка, если таковая имеется, хранящаяся в переменной $referer, и строка пользовательского агента, идентифицирующая броузер, который послал запрос, и хранящаяся в переменной $user_agent.

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

Такой способ определения статистики протоколов доступа к веб-серверу легок, но не очень гибок. Требуется модификация программы для различных видов отчетов, ограниченных диапазонов данных, форматирования отчетов и многих других целей. Наилучшим решением для получения всесторонней статистики веб-сайта является применение таких программ, как analog, свободно доступной на http://www.analog.cx. Она
предоставляет много типов отчетов и настроек конфигурации, которые должны удовлетворить практически любое ваше пожелание..



Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Выделение информации на веб-странице
Извлечение содержимого URL с помощью метода POST
Извлечение ссылок из HTML-файла
Использование шаблонов системы Smarty
Отладка обмена заголовками HTTP

Вернуться в раздел: PHP / 11. Автоматизация работы с Web