Скрипт записи логов посещений Вашего сайта
При работе над сайтом бывает очень полезно проанализировать логи посещений Вашего сайта. Таким образом, можно узнать, как часто Ваш сайт посещают поисковые роботы, и какие переходы по сайту осуществляют пользователи. Но, например, при использовании бесплатного хостинга, функция доступа к log-файлам не предоставляется. Так как же быть в подобных случаях вебмастерам?
Предлагаем Вам написать свой собственный скрипт, который будет записывать все переходы на Вашем сайте в специальный файл, расположенный на сервере, который потом можно будет просмотреть и проанализировать.
Данный скрипт будет полезен для тех, кто пользуется хостингом без предоставления доступа к log-файлам. Для работы скрипта необходима поддержка хостингом PHP. Добавляете данный PHP код в начало страниц, при посещении которых будут писаться логи:
<?php
$file="base.log"; //куда пишем логи
$col_zap=4999; //строк в файле не более
function getRealIpAddr() {
if (!empty($_SERVER['HTTP_CLIENT_IP'])) // Определяем IP
{ $ip=$_SERVER['HTTP_CLIENT_IP']; }
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) // Если IP идёт через прокси
{ $ip=$_SERVER['HTTP_X_FORWARDED_FOR']; }
else { $ip=$_SERVER['REMOTE_ADDR']; }
return $ip;
}
if (strstr($_SERVER['HTTP_USER_AGENT'], 'YandexBot')) {$bot='YandexBot';}
elseif (strstr($_SERVER['HTTP_USER_AGENT'], 'Googlebot')) {$bot='Googlebot';}
else { $bot=$_SERVER['HTTP_USER_AGENT']; }
$ip = getRealIpAddr();
$date = date("H:i:s d.m.Y"); //дата события
$home = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; //какая страница сайта
$lines = file($file);
while(count($lines) > $col_zap) array_shift($lines);
$lines[] = $date."|".$bot."|".$ip."|".$home."|\r\n";
file_put_contents($file, $lines);
?>
Либо, если у Вас на каждой страничке подгружается какой-нибудь php-файл через include, то поместите данный выше код в тот самый подгружаемый php-файл.
Для просмотра результатов лога, создайте php-файл с любым названием и поместите в него следующий PHP код:
<?php
if (isset($_GET[col])) $col=$_GET[col];
else $col=50;
$file=file("base.log"); ?>
<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>sizeof($file)) { $col=sizeof($file); }
echo "Последние <b>".$col."</b> посещений сайта:"; ?>
<table style="width: 700px; border: 0;">
<tr bgcolor="#eeeeee">
<td class="zz" style="width: 100px;"><b>Время, дата</b></td>
<td class="zz" style="width: 220px;"><b>Кто посещал</b></td>
<td class="zz" style="width: 100px;"><b>IP, прокси</b></td>
<td class="zz" style="width: 280px;"><b>Посещенный URL</b></td>
</tr>
<?php
for ($si=sizeof($file)-1; $si+1>sizeof($file)-$col; $si--) {
$string=explode("|",$file[$si]);
$q1[$si]=$string[0]; // дата и время
$q2[$si]=$string[1]; // имя бота
$q3[$si]=$string[2]; // ip бота
$q4[$si]=$string[3]; // адрес посещения
echo '<tr bgcolor="#eeeeee"><td class="zz">'.$q1[$si].'</td>';
echo '<td class="zz">'.$q2[$si].'</td>';
echo '<td class="zz">'.$q3[$si].'</td>';
echo '<td class="zz">'.$q4[$si].'</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>.</div>';
echo '</body></html>';
?>
При обращении к файлу просмотра результатов лога, на экране будет отображаться примерно такая табличка:
Время, дата | Кто посещал | IP, прокси | Посещенный URL |
19:08:40 04.11 | Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) | 211.11.11.11 | /log_info.php |
19:06:19 04.11 | Mozilla/4.0 (Windows 98; US) Opera 10.00 [en] | 123.23.23.23 | /video_download.php |
19:00:06 04.11 | Mozilla/5.0 (Windows NT 6.1; rv:16.0) Gecko/20100101 Firefox/16.0 | 122.22.22.22 | current_time.php |
18:45:59 03.11 | Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.8.131 Version/11.11 | 111.11.11.11 | /script_menu_left.php |
18:45:59 03.11 | Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.8.131 Version/11.11 | 111.11.11.11 | /script_menu_left_example.php |
P.S. Из-за своей популярности и имеющегося спроса, данный скрипт был немного обновлен и теперь его более актуальная версия доступна по ссылке - Скрипт ведения логов посещения сайта.
Перед публикацией все комментарии проходят обязательную модерацию!
Если Вы хотите задать какой-либо вопрос, то сделайте это на нашем форуме.
Таким образом, Вы сможете быстрее получить ответ на интересующий Вас вопрос.
if (strstr($_SERVER['HTTP_USER_AGENT'], 'YandexBot')) {$bot='YandexBot';}
elseif (strstr($_SERVER['HTTP_USER_AGENT'], 'Googlebot')) {$bot='Googlebot';}
else { $bot=$_SERVER['HTTP_USER_AGENT']; }
P.S. В статье уже все исправил.
Только я сделал так $lines[] = $date."|".$bot."|".$ip."|".$user_id."|".$home."|";
и всё заработало, ещё раз благодарю Вас.
$date = date("H:i:s d.m.Y");
на такую:
$date = date("H:i:s d.m.Y", mktime(date("H")-3, date("i"), date("s"), date("m"), date("d"), date("Y")));
http://usefulscript.ru/forum/showthread.php?tid=50&page=2
if (isset($_GET[col])) { $col=$_GET[col]; } else { $col=50; }
на
if (isset($_GET[col])) { $col = substr(preg_replace('/[^0-9]+/i', '', $_GET[col]), 0, 3); } else { $col=50; }
Тогда хацкер не пройдет.
Так же можно заменить на строчку попроще:
if (isset($_GET[col]) and is_numeric($_GET[col]) { $col=$_GET[col]; } else { $col=50; }
Хотя в принципе тут даже htmlentities() или htmlspecialchars() хватит непосредственно на выводе всех данных, и уже очень проблематично будет XSS-ку всунуть.
Но все равно спасибо за скрипт, я его у себя серьезно переделал, заодно и сохранение данных в переменные сессии сделал, для нужд других скриптов, потом еще на скорость работы тестировал и переписывал, и в итоге конфетка получилась.
Главное, что начальный образец этот попался, а дальше легко его модифицировать и переписывать.
Самый нормальный образец из тех, которые находил в паблике.
Необходимо логировать все хедеры, или хотя бы браковать адреса типа 127... 192.168... 172... 10...
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="Очистить лог">
</form>
Учтите, что мы предполагаем, что кнопка будет расположена только на страничке админки (admin.php).
$to = "Ваш почтовый ящик";
$subject = "Заголовок сообщения";
$msg = "Текст сообщения";
mail($to, $subject, $msg);
А если бот обращается к sait.ru/images/fotka.gif, то это никак в логи не заносится, а мне нужно именно это.
С помощью чего в пхп можно захватить такой запрос? Ведь в типовых логах сервера такие запросы фоток или js-файлов присутствуют.
Подскажите пожалуйста! Заранее благодарю.
Скрипт ставил не с этой страницы, а с этой http://usefulscript.ru/log_info_2.php
И второе - по поводу редиректа: на страницу редиректа поставить код это не сложно, как бы поставить, чтоб скрипт записал не ссылку страницы где он стоит, а ссылку куда он совершил переход?
По редиректу... Если Вы передаете страничку (на которую делается переход) GET методом, то при записи лога добавьте в $l_cash.= переменную $_GET[url] или какая она у Вас там.
P.S. Дальнейшее общение перенес на форум - http://usefulscript.ru/forum/showthread.php?tid=255
Заранее благодарен за ответ!!!
Так же строчку $lines[] = $date."|".$bot."|".$ip."|".$home."|\r\n"; замените на такую:
$lines[] = '"'.$date.'";"'.$bot.'";"'.$ip.'";"'.$home.'"'."\r\n";
urldecode, иначе в логах вместо русских символов %##.
Также сохранять логи с указание адреса к логу как:
define('ROOT', '/home/папка_сайта/public_html/'); //путь к сайту на сервере.
$file=ROOT."/log.log"; чтоб логи не создавались в разных папках при запросах типа include/lib/header.php
Можно записывать сразу два IP, remote_addr и одновременно x-forwarder-for(client_ip).
Я такие фишки уже проделывал с вражескими сайтами :)
И у вас также присутствует XSS уязвимость в скрипте. Можно подменить useragent на <script>alert();</script> и получить результат выполнения в парсере лога. Можно потом будет и ваш IP узнать :D
Что я не так сделал?
Да и вообще уже давно пора на mySQL переходить.
$lines = file($file);
while(count($lines) > $col_zap) array_shift($lines);
$lines[] = $date."|".$bot."|".$ip."|".$home."|\r\n";
file_put_contents($file, $lines);
на такие:
$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."|".htmlspecialchars($bot)."|".$ip."|".htmlspecialchars($home)."\n";
ftruncate($fh,0);
fwrite($fh,$l_cash);
flock($fh,LOCK_UN);
fclose($fh);
P.S. Если на сайте установлен какой-либо счетчик, то советую изучить статистику посещений на момент отсутствия лога, т.к. может у Вас сервер "лежит" и дело вовсе не в скрипте.