¡Ya estamos en Twitter!

Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad

Como crear un sistema de estadísticas

por Uriel Lizama

Introducción

En uno de los primeros tutoriales que hice para este sitio de perl, fue acerca de como crear un contador web, para poder saber la cantidad de visitas que recibimos en una página determinada.

Pues esta vez les voy a mostrar como hacer un pequeño sistema de estadísticas para que puedan ver de donde vienen las visitas de su sitio y que es lo que visitan.

Aunque muy sencillo al final de este tutorial habrán aprendido a crear un poderoso sistema de estadísticas.

Contenido:

Los puntos que vamos a tratar en este tutoria serán:

  • 1. Creando nuestro log.
  • 2. Desplegar páginas más visitadas.
  • 3. Desplegar User Agents(navegadores) más utilizados.
  • 4. Desplegar referers al sitio.
  • 5. Días más visitados.
  • 6. Horas más visitadas.
  • 7. Armando todo.

Recuerda que para que le saques el provecho necesario a este tutorial, debes de tener amplio conocimiento básico de perl, así como cierto conocimiento de HTML, de lo contrario podría resultarte dificil comprender ciertas cosas.

Creando nuestro log

Lo primero que necesitamos hacer es guardar en un log todas las visitas que entran a nuestro sitio, para después leerlo y desplegar la información como querramos.
Como primer paso hay que decidir la manera en la que vamos a guardar la información, en este caso vamos a guardar cada visita en una nueva linea, con la información separada por "::".

La información que vamos a guardar es: página que visita, página de donde vino, user agent, ip, fecha, hora.
De esta manera un ejemplo de log de una visita podría ser:

/pagina.htm::http://google.com/serch?query=pagina::Mozilla 4.0::64.234.23.45::10-05-2004::06

Ya que tenemos decidido esto creemos nuestro CGI con el cual vamos a guardar la información. El nombre de este CGI va a ser stats.cgi.

Antes de inciar debemos de hacer algo para evitar que se guarden estadísticas de visitas que se dan dentro del mismo sitio, pues esto en realidad no nos va a ayudar mucho.

Vamos a crear una nueva variable a la cual vamos a llamar "$server", en la cual vamos a poner el nombre de nuestro servidor o dominio:

my $server = "perlenespanol.com";

También necesitamos otra variable en la cual vamos a poner el directorio donde queremos guardar el log de estadísticas:

my $dir = "logs/";

Ahora vamos a crear una donde decidimos hacer el flock(), recuerda que si usas Windows debes de poner esta variable en 0.

my $flock = 1;

Ya con esto ahora si vamos con el código en si, lo primero que vamos a hacer es guardar las variables con la fecha y hora actual:

#VARIABLES DE HORA Y FECHA
my $date = strftime('%Y-%m-%d', localtime(time));
my $hour = strftime('%H', localtime(time));

Lo siguiente son las variables de el usuario que acaba de visitar el sitio, las cuales las ponemos con las variables de entorno:

#VARIABLES DE ENTORNO
my $ref = "$ENV{'HTTP_REFERER'}";
my $ua = "$ENV{'HTTP_USER_AGENT'}";
my $ip = "$ENV{'REMOTE_ADDR'}";
my $document = "$ENV{'REQUEST_URI'}";

Ahora todo lo que tenemos que hacer es escribir el log en caso de que la visita no venga desde el sitio:

if($ref !~ /^http\:\/\/(www\.)?$server/){
open(FILE, ">>$dir" . "log.txt");
flock(FILE,2) if $flock;
my $string = join("::",$document,$ref,$ua,$ip,$date,$hour);
print FILE "$string\n";
close(FILE);
}

Listo ya tenemos nuestro CGI que guardará los datos de nuestras visitas:

Código Final


#!/usr/bin/perl -w

# Baboon Software Log
# por Uriel Lizama

use strict;
use POSIX qw[strftime];

#VARIABLES DE CONFIGURACIÓN
my $server = "perlenespanol.com";

my $dir = "logs/";

my $flock = 1;

#ENVIRONMENT VARS
my $ref = "$ENV{'HTTP_REFERER'}";
my $ua = "$ENV{'HTTP_USER_AGENT'}";
my $ip = "$ENV{'REMOTE_ADDR'}";
my $document = "$ENV{'REQUEST_URI'}";

#DATE HOUR VARS
my $date = strftime('%Y-%m-%d', localtime(time));
my $hour = strftime('%H', localtime(time));


if($ref !~ /^http\:\/\/(www\.)?$server/){
open(FILE, ">>$dir" . "log.txt");
flock(FILE,2) if $flock;
my $string = join("::",$document,$ref,$ua,$ip,$date,$hour);
print FILE "$string\n";
close(FILE);
}

print "Content-type: text/html\n\n";

Ahora para poder guardar el log, todo lo que tienes que hacer es poner una linea de SSI en todas las páginas de las cuales quieres guardar log. Recuerda que puedes ver el tutorial de SSI aquí en "Perl en Español".

Desplegar páginas más visitadas

Ahora vamos a crear un nuevo CGI al que le vamos a poner ver_stats.cgi donde vamos a ir poniendo varias funciones.

Recuerda poner al principio las variables del archivo y de nuestro servidor:

# Variables
my $server = "perlenespanol.com";
my $dir = "logs";
my $flock = 1;

Usando el log que tenemos ahora, lo primero que vamos a aprender hacer es desplegar las páginas más visitadas del sitio:

sub mas_visitadas{

open(FILE,"$dir/log.txt") or die("No se pudo abrir archivo $dir/$_[0]");
flock(FILE,1) if $flock;
my @array = <FILE>;
close(FILE);

my %Items;

foreach my $array(@array){
chomp($array);
my($page,@garbage) = split("::", $array);

$Items{$page}++;
}


print "Content-type: text/html\n\n";
print "<table align=\"center\" cellpadding=\"3\" cellspacing=\"3\">\n";

print "<tr>\n";
print "<td style=\"background-color:lightblue;color:blue;\">\n";
print "<b>Página</b>\n";
print "</td>\n";
print "<td style=\"background-color:lightblue;color:blue;\">\n";
print "<b>Visitas</b>\n";
print "</td>\n";
print "</tr>\n";

my $color = "FFFFFF";
my $count = 0;

foreach my $llave (sort {$Items{$b} <=> $Items{$a}} keys %Items){

if($color eq "FFFFFF"){
$color = "EEEEEE";
}else{
$color = "FFFFFF";
}
print "<tr>\n";
print "<td style=\"background-color:\#$color;\">\n";
print "<a href=\"http://$server$llave\" target=\"blank\">$llave</a>\n";
print "</td>\n";
print "<td style=\"background-color:\#$color;\">\n";
print "$Items{$llave}\n";
print "</td>\n";
print "</tr>\n";

$count += $Items{$llave};
}

print "<tr>\n";
print "<td style=\"background-color:dimgray;color:white;\" align=\"right\">\n";
print "<b>Total</b>\n";
print "</td>\n";
print "<td style=\"background-color:dimgray;color:white;\">\n";
print "<b>$count</b>\n";
print "</td>\n";
print "</tr>\n";

print "</table>\n";
exit(1);

} #sub mas_visitadas

Básicamente lo que hacemos es crear un hash donde vamos a ir agregando las páginas visitadas, al hacer esto vamos a subiendo un contador, por lo cual al final lo podemos desplegar sin ningun problema.

Este modelo lo vamos a usar con todas las partes de las estadísticas, lo único que cambia es la variable que usamos como la principal.

Desplegar User Agents(navegadores) más utilizados.

sub ua{

open(FILE,"$dir/log.txt") or die("No se pudo abrir archivo $dir/$_[0]");
flock(FILE,1) if $flock;
my @array = <FILE>;
close(FILE);

my %Items;

foreach my $array(@array){
chomp($array);
my @data = split("::", $array);

$Items{$data[2]}++;
}


print "Content-type: text/html\n\n";
print "<table align=\"center\" cellpadding=\"3\" cellspacing=\"3\">\n";

print "<tr>\n";
print "<td style=\"background-color:lightblue;color:blue;\">\n";
print "<b>UA</b>\n";
print "</td>\n";
print "<td style=\"background-color:lightblue;color:blue;\">\n";
print "<b>Visitas</b>\n";
print "</td>\n";
print "</tr>\n";

my $color = "FFFFFF";
my $count = 0;

foreach my $llave (sort {$Items{$b} <=> $Items{$a}} keys %Items){

if($color eq "FFFFFF"){
$color = "EEEEEE";
}else{
$color = "FFFFFF";
}
print "<tr>\n";
print "<td style=\"background-color:\#$color;\">\n";
print "$llave\n";
print "</td>\n";
print "<td style=\"background-color:\#$color;\">\n";
print "$Items{$llave}\n";
print "</td>\n";
print "</tr>\n";

$count += $Items{$llave};
}

print "<tr>\n";
print "<td style=\"background-color:dimgray;color:white;\" align=\"right\">\n";
print "<b>Total</b>\n";
print "</td>\n";
print "<td style=\"background-color:dimgray;color:white;\">\n";
print "<b>$count</b>\n";
print "</td>\n";
print "</tr>\n";

print "</table>\n";
exit(1);

} #sub ua


Desplegar referers al sitio.

sub ref{

open(FILE,"$dir/log.txt") or die("No se pudo abrir archivo $dir/log.txt");
flock(FILE,1) if $flock;
my @array = <FILE>;
close(FILE);

my %Items;

foreach my $array(@array){
chomp($array);
my @data = split("::", $array);

$Items{$data[1]}++;
}


print "Content-type: text/html\n\n";
print "<table align=\"center\" cellpadding=\"3\" cellspacing=\"3\">\n";

print "<tr>\n";
print "<td style=\"background-color:lightblue;color:blue;\">\n";
print "<b>Referer</b>\n";
print "</td>\n";
print "<td style=\"background-color:lightblue;color:blue;\">\n";
print "<b>Visitas</b>\n";
print "</td>\n";
print "</tr>\n";

my $color = "FFFFFF";
my $count = 0;

foreach my $llave (sort {$Items{$b} <=> $Items{$a}} keys %Items){

if($color eq "FFFFFF"){
$color = "EEEEEE";
}else{
$color = "FFFFFF";
}
print "<tr>\n";
print "<td style=\"background-color:\#$color;\">\n";
print "<a href=\"$llave\" target\"_blank\">$llave</a>\n";
print "</td>\n";
print "<td style=\"background-color:\#$color;\">\n";
print "$Items{$llave}\n";
print "</td>\n";
print "</tr>\n";

$count += $Items{$llave};
}

print "<tr>\n";
print "<td style=\"background-color:dimgray;color:white;\" align=\"right\">\n";
print "<b>Total</b>\n";
print "</td>\n";
print "<td style=\"background-color:dimgray;color:white;\">\n";
print "<b>$count</b>\n";
print "</td>\n";
print "</tr>\n";

print "</table>\n";
exit(1);

} #sub ref


Días más visitados.

sub dias_mas_visitados{

open(FILE,"$dir/log.txt") or die("No se pudo abrir archivo $dir/log.txt");
flock(FILE,1) if $flock;
my @array = <FILE>;
close(FILE);

my %Items;

foreach my $array(@array){
chomp($array);
my @data = split("::", $array);

$Items{$data[4]}++;
}


print "Content-type: text/html\n\n";
print "<table align=\"center\" cellpadding=\"3\" cellspacing=\"3\">\n";

print "<tr>\n";
print "<td style=\"background-color:lightblue;color:blue;\">\n";
print "<b>Fecha</b>\n";
print "</td>\n";
print "<td style=\"background-color:lightblue;color:blue;\">\n";
print "<b>Visitas</b>\n";
print "</td>\n";
print "</tr>\n";

my $color = "FFFFFF";
my $count = 0;

foreach my $llave (sort {$Items{$b} <=> $Items{$a}} keys %Items){

if($color eq "FFFFFF"){
$color = "EEEEEE";
}else{
$color = "FFFFFF";
}
print "<tr>\n";
print "<td style=\"background-color:\#$color;\">\n";
print "$llave\n";
print "</td>\n";
print "<td style=\"background-color:\#$color;\">\n";
print "$Items{$llave}\n";
print "</td>\n";
print "</tr>\n";

$count += $Items{$llave};
}

print "<tr>\n";
print "<td style=\"background-color:dimgray;color:white;\" align=\"right\">\n";
print "<b>Total</b>\n";
print "</td>\n";
print "<td style=\"background-color:dimgray;color:white;\">\n";
print "<b>$count</b>\n";
print "</td>\n";
print "</tr>\n";

print "</table>\n";
exit(1);

} #sub dias_mas_visitados


Horas más visitadas.

sub horas_mas_visitadas{

open(FILE,"$dir/log.txt") or die("No se pudo abrir archivo $dir/log.txt");
flock(FILE,1) if $flock;
my @array = <FILE>;
close(FILE);

my %Items;

foreach my $array(@array){
chomp($array);
my @data = split("::", $array);

$Items{$data[5]}++;
}


print "Content-type: text/html\n\n";
print "<table align=\"center\" cellpadding=\"3\" cellspacing=\"3\">\n";

print "<tr>\n";
print "<td style=\"background-color:lightblue;color:blue;\">\n";
print "<b>Hora</b>\n";
print "</td>\n";
print "<td style=\"background-color:lightblue;color:blue;\">\n";
print "<b>Visitas</b>\n";
print "</td>\n";
print "</tr>\n";

my $color = "FFFFFF";
my $count = 0;

foreach my $llave (sort {$Items{$b} <=> $Items{$a}} keys %Items){

if($color eq "FFFFFF"){
$color = "EEEEEE";
}else{
$color = "FFFFFF";
}
print "<tr>\n";
print "<td style=\"background-color:\#$color;\">\n";
print "$llave\n";
print "</td>\n";
print "<td style=\"background-color:\#$color;\">\n";
print "$Items{$llave}\n";
print "</td>\n";
print "</tr>\n";

$count += $Items{$llave};
}

print "<tr>\n";
print "<td style=\"background-color:dimgray;color:white;\" align=\"right\">\n";
print "<b>Total</b>\n";
print "</td>\n";
print "<td style=\"background-color:dimgray;color:white;\">\n";
print "<b>$count</b>\n";
print "</td>\n";
print "</tr>\n";

print "</table>\n";
exit(1);

} #sub horas_mas_visitadas

Armando todo

Ya que tenemos todas nuestras funciones listas, ahora lo que falta es ponerlas en un mismo CGI y crear una manera que podamos llamar cada una de las funciones por separado. Esto es muy sencillo, lo primero que tenemos que hacer es recibir las variables, y lo vamos a hacer con el módulo CGI:

use CGI;


my %Input;

my $query = new CGI;
my @pairs = $query->param;

foreach my $pair(@pairs){
$Input{$pair} = $query->param($pair);
}

Ahora cremos unos pequeños enunciados de control de esta manera:

if($Input{'accion'} eq "ref"){ &ref; }
elsif($Input{'accion'} eq "ua"){ &ua; }

Así le hacemos con cada una de nuestras funciones, de manera que al llamar por ejemplo: http://misitio.com/cgi-bin/mis_estadisticas.cgi?acccion=ref, nuestro CGI despliegue los referers. Sencillo ¿no?

Listo, ahora si tenemos nuestro primer sistema básico pero poderoso de estadísticas.

Recuerda que si tienes alguna duda lo puedes hacer en el foro de perl.

Los Archivos

Hice un archivo zip que contiene los scripts que se muestran en este tutorial. Recuerden que no incluye ningun archivo de instalación, ni instrucciones de instalación. ES PARA MOTIVOS DE APRENDIZAJE.

http://perlenespanol.com/pub/stats.zip

POR FAVOR NO RE-DISTRIBUYAN LOS ARCHIVOS, LOS ESTOY REGALANDO PERO EL CÓDIGO SIGUE SIENDO MÍO. PUEDEN USARLO EN LOS SITIOS QUE USTEDES QUIERAN SIEMPRE Y CUANDO MANTENGAN MI FIRMA.

¿Quiéres más tutoriales como este? Escribir tutoriales toma una gran cantidad de tiempo y esfuerzo. Si este tutorial te ayudó a aprender o a solucionar algo, por favor considera dejar alguna donación en apoyo a Perl en Español.

Cliquea en el botón de abajo para dejar tu donación por medio de PayPal.

Comparte:
Categorías de Tutoriales:
En Nuestros Foros:

    Software error:

    junk after document element at line 1, column 32, byte 32 at /usr/lib64/perl5/vendor_perl/XML/Parser.pm line 187.
    

    For help, please send mail to the webmaster ([email protected]), giving this error message and the time and date of the error.

  • Entra a los foros »
Socializa:
Síguenos por Twitter

Suscríbete GRATUITAMENTE al Boletín de Perl en Español

Perl en Español es mantenido con Movable Type
Todo el contenido de Perl en Español está bajo una licencia CC:
Creative Commons License