Скрипт ведения логов посещения сайта
Ранее мы уже рассматривали Скрипт записи логов посещений Вашего сайта, но как потом выяснилось, у него имелось пару недочетов. Главный недочет заключался в том, что при большой посещаемости могла потеряться часть лога из-за того, что не было блокировки файла лога на момент записи/чтения. Дополнительно наши посетители просили разнести логи поисковиков и обычных посетителей в разные файлы.
Таким образом, в данной теме мы хотим предложить Вам "доработанный" сприпт записи логов посещений Вашего сайта. Напомним, что при помощи нашего скрипта можно узнать, как часто Ваш сайт посещают поисковые роботы, и какие странички посещают пользователи. Скрипт полезен тем, кто пользуется услугами бесплатного хостинга, т.к. им не предоставляется доступ к log-файлам и приходится писать свои логи.
Для работы скрипта необходима поддержка хостингом PHP.
Для того чтобы писать логи в файл, добавьте в шаблон, либо в начало страниц, при посещении который будут писаться логи, следующий PHP код:
<?php
$file="base_bot"; //имя файла с логами ботов
$col_zap=2499; //записей в логе ботов
$xxx=trim(strip_tags($_SERVER['HTTP_USER_AGENT']));
if (strpos($xxx, 'YandexBot')!==false) {$bot='YandexBot';}
elseif (strpos($xxx, 'Googlebot')!==false) {$bot='Googlebot';}
elseif (strpos($xxx, 'bingbot')!==false) {$bot='Bingbot';}
elseif (strpos($xxx, 'Mail')!==false) {$bot='Mail.ru';}
elseif (strpos($xxx, 'YandexBlogs')!==false) {$bot='YandexBlogs';}
elseif (strpos($xxx, 'YandexImage')!==false) {$bot='YandexImages';}
elseif (strpos($xxx, 'YandexFavicons')!==false) {$bot='YandexFavicons';}
elseif (strpos($xxx, 'YandexDirect')!==false) {$bot='YandexDirect';}
elseif (strpos($xxx, 'YandexNews')!==false) {$bot='YandexNews';}
elseif (strpos($xxx, 'YandexSomething')!==false) {$bot='YandexSomething';}
elseif (strpos($xxx, 'YandexMetrika')!==false) {$bot='YandexMetrika';}
elseif (strpos($xxx, 'YandexAntivirus')!==false) {$bot='YandexAntivirus';}
elseif (strpos($xxx, 'Feedfetcher-Google')!==false) {$bot='Feedfetcher-Google';}
elseif (strpos($xxx, 'Googlebot-Image')!==false) {$bot='Googlebot-Image';}
elseif (strpos($xxx, 'Yahoo')!==false) {$bot='Yahoo!';}
elseif (strpos($xxx, 'WebCrawler')!==false) {$bot='WebCrawler';}
elseif (strpos($xxx, 'ZyBorg')!==false) {$bot='ZyBorg';}
elseif (strpos($xxx, 'Scooter')!==false) {$bot='AltaVista';}
elseif (strpos($xxx, 'StackRambler')!==false) {$bot='Rambler';}
elseif (strpos($xxx, 'Aport')!==false) {$bot='Aport';}
elseif (strpos($xxx, 'lycos')!==false) {$bot='Lycos';}
elseif (strpos($xxx, 'fast')!==false) {$bot='Fast Search';}
elseif (strpos($xxx, 'msnbot')!==false) {$bot='MSN';}
elseif (strpos($xxx, 'Nigma.ru')!==false) {$bot='Nigma';}
elseif (strpos($xxx, 'ia_archiver')!==false) {$bot='Alexa';}
elseif (strpos($xxx, 'Baiduspider')!==false) {$bot='Baidu';}
elseif (strpos($xxx, 'Exabot')!==false) {$bot='Exabot';}
elseif (strpos($xxx, 'archive.org_bot')!==false) {$bot='Archive.org';}
elseif (strpos($xxx, 'Ezooms')!==false) {$bot='Ezooms';}
elseif (strpos($xxx, 'GrepNetstat.com Bot')!==false) {$bot='GrepNetstat.com';}
elseif (strpos($xxx, 'MJ12bot')!==false) {$bot='Majestic-12';}
elseif (strpos($xxx, 'AhrefsBot')!==false) {$bot='Ahrefs';}
elseif (strpos($xxx, 'TurnitinBot')!==false) {$bot='Turnitin';}
elseif (strpos($xxx, 'discobot')!==false) {$bot='Discobot';}
elseif (strpos($xxx, 'Subscribe.Ru')!==false) {$bot='Subscribe';}
elseif (strpos($xxx, 'TOP.NET.RU')!==false) {$bot='TOP.NET.RU';}
elseif (strpos($xxx, 'SISTRIX Crawler')!==false) {$bot='SISTRIX';}
elseif (strpos($xxx, 'Wotbox')!==false) {$bot='Wotbox';}
else {
$file="base_user"; //имя файла с логами пользователей
$col_zap=3499; //записей в логе пользователей
$bot=htmlspecialchars(substr($xxx,0,80));//обрезаем USER-AGENT до 80 символов
}
//записываем логи в файл с блокировкой
$l_cash='';
$fh=fopen($file,"a+");
flock($fh,LOCK_EX);
fseek($fh,0);
while (!feof($fh)) $l_cash.= fread($fh,8192);
$lines=explode("\n",$l_cash);
while(count($lines)>$col_zap) array_shift($lines);
$l_cash=implode("\n",$lines);
$l_cash.=date("H:i:s d.m")."|".$bot."|".$_SERVER['REMOTE_ADDR']."|".
htmlspecialchars($_SERVER['REQUEST_URI'])."\n";
ftruncate($fh,0);
fwrite($fh,$l_cash);
flock($fh,LOCK_UN);
fclose($fh);
?>
Как видно, код стал гораздо больше, но это связано с тем, что в него мы добавили проверку на ботов, которые по нашему опыту чаще всего посещают наш сайт.
Для просмотра результатов лога нужно создать отдельный PHP файл с любым названием и поместить в него следующий PHP код:
<?php
if (isset($_GET["col"])) $col=$_GET["col"]; else $col=50;
$lines_cashe=file_get_contents("base_user", LOCK_EX);
$file=explode("\n",$lines_cashe);
$size_f=count($file)-1;
?>
<html>
<head>
<style type='text/css'>
td.zz { padding-left: 3px; font-size: 9pt; padding-top: 2px; font-family: Arial; }
</style>
</head>
<body>
<div style="text-align: center;">
<?php
if ($col>$size_f) $col=$size_f;
echo 'Последние <b>'.$col.'</b> посещений сайта ботами:';
?>
<table style="width: 750px; table-layout: fixed; border: 0;">
<tr bgcolor="#eeeeee">
<td class="zz" style="width: 100px;"><b>Время, дата</b></td>
<td class="zz" style="width: 250px;"><b>Кто посещал</b></td>
<td class="zz" style="width: 100px;"><b>IP, прокси</b></td>
<td class="zz" style="width: 300px;"><b>Посещенный URL</b></td>
</tr>
<?php
for ($si=$size_f-1; $si>=$size_f-$col; $si--) {
$str=explode("|",$file[$si]);
echo '<tr bgcolor="#eeeeee"><td class="zz">'.$str[0].'</td>';
echo '<td class="zz">'.$str[1].'</td>';
echo '<td class="zz">'.$str[2].'</td>';
echo '<td class="zz"><a href="http://usefulscript.ru'.$str[3].'">'.$str[3];
echo '</a></td></tr>';
}
echo '</table>';
echo '<br>Просмотреть последние <a href=?col=100>100</a> <a href=?col=500>500</a> ';
echo '<a href=?col=1000>1000</a> посещений.';
echo '<br>Просмотреть <a href=?col='.sizeof($file).'>все посещения</a>.';
echo '</div></body></html>';
?>
При обращении к PHP файлу для просмотра результатов лога, на экране Вы увидите примерно вот такую табличку:
Время, дата | Кто посещал | IP, прокси | Посещенный URL |
12:49:33 07.04 | Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:16.0) Gecko/20100101 Firefox/16.0 | 221.21.21.21 | /script.php |
12:48:16 07.04 | Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:16.0) Gecko/20100101 Firefox/16.0 | 221.21.21.21 | /calendar.php |
12:43:04 07.04 | Mozilla/5.0 (Windows NT 6.1; rv:16.0) Gecko/20100101 Firefox/16.0 | 233.33.33.33 | /advego.php |
12:38:00 07.04 | Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/20100101 Firefox/13.0.1 | 144.44.44.44 | /video_download.php |
12:36:37 07.04 | Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.8.131 Version/11.11 | 112.12.12.12 | /rotator_banner.php |
Как Вы могли заметить, в данной табличке будут отображаться только визиты простых пользователей (т.к. в base_user содержатся логи пользователей). Для того чтобы просмотреть логи ботов, Вам необходимо по аналогии создать еще один точно такой же PHP файл, в котором необходимо будет заменить имя файла с логами (base_user на base_bot).
Перед публикацией все комментарии проходят обязательную модерацию!
Если Вы хотите задать какой-либо вопрос, то сделайте это на нашем форуме.
Таким образом, Вы сможете быстрее получить ответ на интересующий Вас вопрос.
Warning: file_get_contents(base_user) [function.file-get-contents]: failed to open stream: No such file or directory in /home/b/...
Подскажите, пожалуйста, где моя ошибка?
Проверьте, находятся ли файл просмотра результата лога и файл base_user в одной папке. Если файлы в разных папках, то к файлу base_user указывайте полный путь (например, usefulscript.ru/logs/base_user).
В нашем примере предполагается, что скрипт записи логов, сам файл логов (base_user) и файл просмотра логов будут находиться в одной папке.
Fatal error: Maximum execution time of 30 seconds exceeded in /home/vhosts/www...eu/index.php on line 118
На 118 строке у меня следующий код:
while (!feof($fh)) $l_cash.= fread($fh,8192);
Что здесь не так?
if (isset($_GET["col"])) $col=$_GET["col"]; else $col=50;
Спасибочки Вам ОГРОМНЫЕ!!!
И где вы набрали такой список? (Это про яндекс_бот и др.), что делать если что-то изменится? Как об этом узнать и где? Заранее благодарю.
Список ботов был сформирован на основе данных логов нашего сайта. Количество разнообразных ботов со временем меняется и за всеми не уследить. Мы привели самые популярные, но всегда можно посмотреть в логах в файле base_bot какие еще боты приходят к Вам на сайт и при желании добавить их в скрипт.
Скрипт работает. Вопрос - в логе видно, что с моего хостинга (77.222.61.14) идут постоянно запросы вида:
19:11:15 05.10 77.222.61.14 //index.php?option=com_content&view=article&id=77,
номер 77 это страница 404. Что могут означать эти запросы?
Добавить реферера можно путем добавления в строку "$l_cash.=date("H:i:s d.m")."|"..." данных из переменной $_SERVER['HTTP_REFERER']. Для определения ОС - могу порекомендовать выделять ее из переменной $_SERVER['HTTP_USER_AGENT'], а вот с разрешением монитора хуже, т.к. его можно получить только на JavaScript.
Спасибо за быстрый ответ. С уважением.
Спасибо за труды!
Как установить код очистки логов! При помощи вашего данного кода:
if (isset($_POST[del_log])) {
file_put_contents('base.log', '');
header("Location: admin.php");
}
<form method="POST" action="admin.php">
<input type="submit" name="del_log" value="Очистить лог">
<?php $des = fopen("base_user","w"); fclose("base_user"); ?>.
Файл разместил на сервере, где лежат файлы сайта.
Теперь при нажатии на ссылку "ваш сайт.ru/rbase_user.php"
статистика очищается. Также делаем другой файл rbase_bot.php для очистки статистики ботов, или можно очищать одним файлом, вписав:
<?php $des = fopen("base_bot","w"); fclose("base_bot"); ?> в файл "rbase_user.php".
P.S. Следующий комментарий был вынесен на форум.
А не подскажете код капчи? Что в этой форме?
И еще, а у вас на сайте нет скрипта по блокировки ип адресов для не доступа к сайту?
Как заблокировать доступ к сайту или Временная блокировка доступа к сайту.
Есть же поиск по сайту, пользуйтесь.
Добавьте: if ($_SERVER['REMOTE_ADDR']!='127.0.0.1') {
127.0.0.1 естественно замените на нужный IP адрес. Не забудьте после fclose($fh); добавить закрывающую скобку!
Замените $l_cash.=date("H:i:s d.m")."|".$bot."|".$_SERVER['REMOTE_ADDR']."|".
на $l_cash.=$_SERVER['REMOTE_ADDR']."|".date("H:i:s d.m")."|".$bot."|".
А в коде просмотра результатов лога после $size_f=count($file)-1; добавьте сортировку rsort($file);
<?php
$file = fopen("bases.txt","a+");
$ip = getenv(REMOTE_ADDR);
$time = date("H:i:s d M Y");
$url_o = getenv(HTTP_REFERER);
$url_k = getenv(REQUEST_URI);
$soft = getenv(HTTP_USER_AGENT);
$all = "$ip ; $time ; $url_o ; $url_k ; \n";
fwrite($file,$all );
fclose($file);
?>
$url_o; $url_k - две переменные откуда и куда по сайту перешёл посетитель, как будет выглядеть код для переменной $url_k в вашем скрипте?
Мне понравился скрипт добавления комментария к теме, можно у Вас код позаимствовать?
Все необходимые для записи данные нужно добавлять в переменную l_cash.
Код скрипт комментариев можете посмотреть в теме Добавление комментариев на сайт.
1) У меня возник вопрос в строке
while (!feof($fh)) $l_cash.= fread($fh,8192);
Я так понимаю, что в этой строке идет накопление содержимого файла со статистикой в переменную $l_cash. Скажите, что за магическое число 8192. И нельзя ли эту строку заменить на: $l_cash = fread($fh, filesize($fh));
либо строку: $l_cash = file_get_contents (“имя лог файла”);
2) В коде чтения статистики из лог-файла использована функция file_get_contents с запиранием файла.
$lines_cashe=file_get_contents("base_user", LOCK_EX);
Скажите, а отпирание файла происходит автоматически после его прочтения?
2) Да. Данный скрипт (с минимальными изменениями) долгое время был установлен и на данном сайте. Проблем не возникало.
Смысла переводить каретку в начало пустой строки нет, а в старом скрипте просто перестраховались.
При повторном обновлении текущей страницы где выводится, например, online.php, записи просто дублируются. То есть одни и те же данные по несколько раз. Как исправить?
При повторном обновлении чтобы старая запись удалялась, то остается смысл использовать этот скрипт, иначе как-то странно все получается. Просто путаница...
ini_set('date.timezone', 'Europe/Kiev');
Скажите, пожалуйста, а как же быть, если будет пару тысяч записей, как же они все покажутся на странице? Есть что-то типа вроде пагинации?
Остальная часть комментария, как и последующие два перенесены на форум.
Сначала не понял в чем дело, потом включил отображение ошибок и он выдал мне это:
$col_zap) array_shift($lines);$l_cash=implode("\n",$lines);...
//определяем код страны, из которой пришел посетитель:
include("sxgeo/SxGeo.php");//включаем апи Sypex для определения места положения юзера
$ip= $_SERVER['REMOTE_ADDR'];//получаем ip юзера
$SxGeo = new SxGeo('sxgeo/SxGeo.dat');//создаем новый объект, если используется база sxgeo.dat
$country = $SxGeo->getCountry($ip);//получаем из базы Sypex код страны по известному ip
unset($SxGeo);//освобождаем ресурсы сервера
при этом в $country получим iso код страны, который нужно дописать в базу, например:
$l_cash.=date("d.m.y")."|".date("H:i:s")."|".$bot."|".$ip."|".$country"\n";
Сам подключаемый скрипт базами стран, скачать у Sypex и положить в папку: sxgeo/SxGeo.php , тогда все стандартно сработает. Не забудьте, конечно же добавить еще одно поле для вывода $country во втором файле.
$ip = getRealIpAddr();
$date = date("d.m.Y H:i"); // определяем дату и время события
$home = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; // определяем страницу сайта
$ref = $_SERVER["HTTP_REFERER"];
$lines = file($file);
while(count($lines) > $col_zap) array_shift($lines);
$lines[] = $ip." » ".$date." | ".$home." | ".$ref." |".$bot."\r\n";
file_put_contents($file, $lines);
Скрипт сохраняет записи только с корня сайта а вот такие запроси не сохраняются например: site.ru/forum/them.php?id=1
Подскажите, пожалуйста, что не так?
Заранее спасибо за ответ!
С кракозябрами проблему решила (стыдно даже за вопрос)))
В коде пыталась менять путь на полное имя файла (скопировала его из названия файла, которое видно при редактировании), но ошибка никуда не делась...
Похоже, что в кавычки забыли взять base_user.
Вот ошибка целиком
Warning: file_get_contents(base_user) [function.file-get-contents]: failed to open stream: No such file or directory in /var/www/vhosts/...ru/httpdocs/...ru/nashi_logi.php on line 3
Сделайте, например, так: echo '<td class="zz"><span style="color: #FF0000;">'.$str[2].'</span></td>';
Возможно ли в главном логе добавить отображение количества строк в файле base_bot?
while(count($lines)>$col_zap) array_shift($lines);
$l_cash=implode("\n",$lines);
начинает отображаться на сайте строки кода $col_zap) array_shift($lines);
$l_cash=implode("\n",$lines); и далее до конца, в чем может быть причина
И второй вопрос как сделать еще колонку где бы считалось количество посещений одним IP адресом.
Спасибо.