logotipo de el mundo de deckerix
El mundo de deckerix
mascotas
El mundo de deckerix. [x]
logotipo de el mundo de deckerix

El mundo de Deckerix 0.4


by Oscar Carrascosa Blanco


Deprecated: Function split() is deprecated in /homepages/43/d272195232/htdocs/src/utiles/Fecha.php on line 65

Deprecated: Function split() is deprecated in /homepages/43/d272195232/htdocs/src/utiles/Fecha.php on line 66
Septiembre 01 2008 21:56:22

Analizando los Logs del Apache con PHP (II) by deckerix

El parseador del servidor Web Apache tiene como función procesar todos los datos que guarda el servidor en los ficheros de registros (logs) para posteriormente introducirlos con una cierta estructura y orden en una base de datos para poder analizar toda la información y realizar con ella estadísticas variadas tales como conocer desde qué páginas nos visitan más, que navegador es el más utilizado para navegar por nuestro sistema, etc.


if (stristr(PHP_OS,"win"))
      $logHoy = "$ruta/../../logs/access.log"; # el fichero de log's de hoy para windows
else  $logHoy = "$ruta/../../logs/access_log"; # el fichero de log's de hoy para linux

El script va a continuar preguntándose por la plataforma bajo la que se está ejecutando, ya que el fichero de logs del que tendrá que sacar la información tiene un nombre diferente dependiendo si se ejecuta en un Linux (access_log) o un windows (access.log). Una vez conocido el fichero procederá a abrirlo en modo lectura, para poder leer todos y cada uno de los registros que introduce el servidor por cada petición recibida.


$fd = fopen("$logHoy","r"); //abrimos el fichero de logs de acceso del apache

Por cada uno de estos logs, se produce lo que llamamos parseo, es decir un proceso de normalizar los datos de entrada para darle una salida específica. En nuestro caso la salida será una base de datos Mysql. Un registro de acceso tiene como ya hemos comentado con anterioridad la siguiente forma :


127.0.0.1 - deckerix [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)" 

Lo primero que se hace con el registro es separarlo por campos vacíos e introducir cada uno de ellos en una posición de un vector. La primera posición tendrá por tanto la IP del cliente, la siguiente el guión, y así sucesivamente. Algo a tener en cuenta es que la posición 10 tendrá la referencia, y que desde la 11 hasta el final todos los campos deberían ser solo uno, el Agente de usuario, ya que es probable que esté formado por varios blancos. (por lo tanto hay un mecanismo que unifican esas posiciones del vector).


 while ($x = fgets($fd,1024)){//mientras no sea final de fichero leemos registros y almacenamos 
  $agente         ="";
  $elHost         ="";
  $fechaSinParsear="";
  $bytes          ="";

  $arraya          = explode(" ", $x); //separamos el registro por blancos y lo insertamos al array
  $elHost          = $arraya[0];       //primera posicion tiene la IP
  //1 seria -
  //2 seria user uid
  $fechaSinParsear = $arraya[3];       //toda la fecha sin parsear
  //4 seria la zona
  //5 seria post o get
  $peticion        = $arraya[6];       //peticion
  $codigo          = $arraya[8];       //codigo
  $bytes           = $arraya[9];       //bytes ocupa el registro
  $referencia      = $arraya[10];      //referer

for ($i=11; $i< count($arraya);$i++){//no sabemos por cuantos blancos está formado el agente.
  //pillamos toda la información que quede
  $agente=$agente." ".$arraya[$i];
}


$peticion   = str_replace("\"","", $peticion);//parseando...
$referencia = str_replace("\"","", $referencia);//parseando...


Una vez tenemos los campos bien separados, son estos los que sufren el parseo final. Por ejemplo la fecha, que aparece así 10/Oct/2000, deberá tener el siguiente formato para ser introducida en la base de datos Mysql : 2000-10-10. El parseo más importante y complicado es el del agente de usuario. De él se puede sacar tanto el sistema operativo y el navegador del cliente. Mediante una serie de expresiones regulares que ya expliqué en un post anterior, seremos capaces de cotejar todos los posibles casos de los valores del Agente de Usuario con los SO y los navegadores. Pero cabe la posibilidad de que el agente de usuario no sea un navegador, si no un robot Web, caso que también hemos registrado.


/******************PARSEAR FECHA******************/

$fechaParseada = str_replace("[", "", $fechaSinParsear);
list($day, $month, $year)            = explode("/",$fechaParseada,3);//recuperamos el dia
list($year, $hour, $minute, $second) = explode(":",$year,4);//recuperamos la hora


/*****PARSEAR EL MES********/
if     ($month=="Jan") $month="01";
elseif ($month=="Feb") $month="02";
elseif ($month=="Mar") $month="03";
elseif ($month=="Apr") $month="04";
elseif ($month=="May") $month="05";
elseif ($month=="Jun") $month="06";
elseif ($month=="Jul") $month="07";
elseif ($month=="Aug") $month="08";
elseif ($month=="Sep") $month="09";
elseif ($month=="Oct") $month="10";
elseif ($month=="Nov") $month="11";
elseif ($month=="Dec") $month="12";


$fecha = "$year-$month-$day"; //unimos la info
$hora  = "$hour:$minute:$second";//unimos la info

/******************FIN PARSEAR FECHA******************/

/******************************PARSEAR BYTES**********************************/

 if ($bytes == "-") $bytes=0;

/***************************FIN PARSEAR BYTES*********************************/


/****************************PARSEAR AGENTE***********************************/
$sistemaOperativo   = reconocedorSistemaOperativo($agente);
$navegador          = reconocedorNavegador($agente);
$robot              = reconocerRobot($agente);
/**************************FIN PARSEAR AGENTE*********************************/


Una vez se tienen todos los datos parseados, éstos se introducen en la base de datos. Estos datos al estar ya en la base de datos, se borran del fichero de logs del apache para no malgastar disco duro.


//insertamos la información parseada en la base de datos

mysql_query("INSERT  stadisticas (codigo,bytes,so,nav,agente,ip,dia,hora,referencia,peticion) VALUES 

('$codigo','$bytes','$sistemaOperativo','$navegador','$agente','$elHost','$fecha','$hora','$referenc

ia','$peticion')", $conexion);
}

 fclose($fd);//cerramos el fichero de logs

Por último comentar que en la base de datos guardamos los siguientes campos: el código de estado de la petición, los Bytes que ocupa el recurso solicitado, el sistema operativo, el navegador, el agente completo, la IP, el país, el día en el que se realizó la petición, la hora, el referer y el recurso pedido. Con toda esta información hemos sido capaces de mostrar gran cantidad de información de alta importancia.

Nombre * (obligatorio)

Email

Web

El mundo de Deckerix es una creación de Óscar Carrascosa Blanco.

deckerix@gmail.com