Analizar el registro log, de apache web server

Ratio: 5 / 5

Inicio activadoInicio activadoInicio activadoInicio activadoInicio activado
 

Si está ejecutando Apache o un servidor de web similar que utiliza el formato de registro común -log-, Podrá hacer un rápido análisis estadístico, que además podrá hacerlo desde la línea de comandos, a través de un shell script. La configuración estándar para un servidor tiene un access.log y error.log escrito para el sitio; Su ISP incluso tendrá estos archivos de datos raw disponibles para los clientes, pero si tienes tu propio servidor, debe tener definitivamente acceso a estos archivos guardando esta valiosa información. Una línea típica tiene un access.log tiene el siguiente aspecto:


63.203.109.38 - - [02/Sep/2003:09:51:09 -0700] "GET /custer HTTP/1.1" 301 248 "http://search.msn.com/results.asp?RS=CHECKED&FORM=MSNH& v=1&q=%22little+big+Horn%22" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)


El cuadro 1 muestra el valor, por columna, para el formato de registro común.

Tabla 1: Diseño Común de archivo de registro

El número de visitas al sitio puede determinarse rápidamente haciendo un recuento de palabras en el archivo de registro, y el intervalo de fechas de entradas en el archivo puede determinarse mediante la comparación de las líneas de la primeras y la últimas en él:


$ wc -l access_log
10991 access_log
$ head -1 access_log ; tail -1 access_log
64.12.96.106 - - [13/Sep/2003:18:02:54 -0600] ...
216.93.167.154 - - [15/Sep/2003:16:30:29 -0600] ...

Con estos puntos en mente, aquí es un script que genera una serie de estadísticas útiles, habida cuenta de un archivo de registro de formato de Apache access_log.


Columna Valor
1 IP de acceso al servidor host
2-3 Información de seguridad de https / SSL conexiones
4 Fecha y zona horaria de la petición específica
5 Método invocado
6 URL solicitada
7 Protocolo utilizado
8 Resultados de código
9 Número de bytes transferidos
10 Referrer
11 cadena de identificación del Navegador

El código de resultado (campo 8) valor 301 indica éxito. La referencia (campo 10) indica la dirección URL de la página que el surfista se encontraba de visita inmediatamente anterior a la solicitud de la página en este sitio: Usted puede ver que el usuario estaba en search.msn.com (MSN) y buscado "Little Big Horn ". Los resultados de esa búsqueda incluido un enlace a la dirección custer en este servidor.

Código Shell Script:


#!/bin/sh


# webaccess - analyze an Apache-format access_log file, extracting
# useful and interesting statistics

bytes_in_gb=1048576
scriptbc="$HOME/bin/scriptbc"
nicenumber="$HOME/bin/nicenumber"
host="intuitive.com"

if [ $# -eq 0 -o ! -f "$1" ] ; then
echo "Usage: $(basename $0) logfile" >&2
exit 1
fi

firstdate="$(head -1 "$1" | awk '{print $4}' | sed 's/\[//')"
lastdate="$(tail -1 "$1" | awk '{print $4}' | sed 's/\[//')"

echo "Results of analyzing log file $1"
echo ""
echo " Start date: $(echo $firstdate|sed 's/:/ at /')"
echo " End date: $(echo $lastdate|sed 's/:/ at /')"

hits="$(wc -l < "$1" | sed 's/[^[:digit:]]//g')"

echo " Hits: $($nicenumber $hits) (total accesses)"

pages="$(grep -ivE '(.txt|.gif|.jpg|.png)' "$1" | wc -l | sed 's/[^[:digit:]]//g')"

echo " Pageviews: $($nicenumber $pages) (hits minus graphics)"

totalbytes="$(awk '{sum+=$10} END {print sum}' "$1")"

echo -n " Transferred: $($nicenumber $totalbytes) bytes "

if [ $totalbytes -gt $bytes_in_gb ] ; then
echo "($($scriptbc $totalbytes / $bytes_in_gb) GB)"
elif [ $totalbytes -gt 1024 ] ; then
echo "($($scriptbc $totalbytes / 1024) MB)"
else
echo ""
fi

# now let's scrape the log file for some useful data:

echo ""
echo "The ten most popular pages were:"

awk '{print $7}' "$1" | grep -ivE '(.gif|.jpg|.png)' | \
sed 's/\/$//g' | sort | \
uniq -c | sort -rn | head -10

echo ""

echo "The ten most common referrer URLs were:"

awk '{print $11}' "$1" | \
grep -vE "(^"-"$|/www.$host|/$host)" | \
sort | uniq -c | sort -rn | head -10

echo ""
exit 0



Cómo funciona:

Aunque esta secuencia de comandos parece compleja, no lo es. Es más fácil ver esto si consideramos cada bloque como un  pequeño e independiente script. Por ejemplo, las primeras líneas de extraen la primera y la última fecha del cuarto campo de las primeras y últimas líneas del archivo. El número de visitas se calcula por el recuento de las líneas en el archivo (mediante wc), y el número de páginas vistas son simplemente hits menos solicitudes de archivos de imágenes o archivos de texto sin formato (es decir, archivos con .gif, .jpg, .png o .txt como su extensión). El Total de bytes transferidos se calcula por resumir el valor del campo décimo en cada línea y, a continuación, invocar "nicenumber" para presentarlo atractivo. Las páginas más populares pueden calcularse mediante la extracción de sólo las páginas solicitadas desde el archivo de registro; cribado cualquier archivos de imagen; clasificación, utilizando uniq -c para calcular el número de apariciones de cada línea única; y finalmente una vez más para asegurarse de que las líneas más frecuente se presentan en primer lugar de la clasificación. En el código, ve así:


 awk '{print $7}' "$1" | grep -ivE '(.gif|.jpg|.png)' | \
sed 's/\/$//g' | sort | \
uniq -c | sort -rn | head -10

Nota: para normalizar las cosas un poco: las tiras de la invocación sed fuera barras al final, para asegurarse de que /subdir/ y /subdir son considerados como la misma petición.

Similar a la sección que recupera las diez páginas más solicitadas, la siguiente sección saca la información de referencia:


awk '{print $11}' "$1" | \
grep -vE "(^\"-\"$|/www.$host|/$host)" | \
sort | uniq -c | sort -rn | head -10


Esto extrae del campo 11 del archivo de registro, cribado ambas entradas que fueron remitidos desde el host actual y las  entradas que están "-" (el valor enviado cuando el navegador web está bloqueando los datos de referencia) y, a continuación,  alimenta el resultado a la misma secuencia de sort|uniq -c|sort -rn|head -10 para obtener los diez referrers más comunes.

Para ejecutar este script, especifique el nombre de un Apache (u otro formato de registro común) del archivo de registro como único argumento.
Los Resultados

El resultado de ejecutar este script en un archivo de registro típico es bastante informativo:

$ webaccess /web/logs/intuitive/access_log

Results of analyzing log file /web/logs/intuitive/access_log
Start date: 13/Sep/2003 at 18:02:54
End date: 15/Sep/2003 at 16:39:21
Hits: 11,015 (total accesses)
Pageviews: 4,217 (hits minus graphics)
Transferred: 64,091,780 bytes (61.12 GB)
The ten most popular pages were:
862 /blog/index.rdf
327 /robots.txt
266 /blog/index.xml
183
115 /custer
96 /blog/styles-site.css
93 /blog
68 /cgi-local/etymologic.cgi
66 /origins
60 /coolweb
The ten most common referrer URLs were:
96 "http://booktalk.intuitive.com/"
18 "http://booktalk.intuitive.com/archives/cat_html.shtml"
13 "http://search.msn.com/results.asp?FORM=MSNH&v=1&q=little+big+horn"
12 "http://www.geocities.com/capecanaveral/7420/voc1.html"
10 "http://search.msn.com/spresults.aspx?q=plains&FORM=IE4"
9 "http://www.etymologic.com/index.cgi"
8 "http://www.allwords.com/12wlinks.php"
7 "http://www.sun.com/bigadmin/docs/"
7 "http://www.google.com/search?hl=en&ie=UTF-8&oe=UTF-8&q=cool+web+pages"
6 "http://www.google.com/search?oe=UTF-8&q=html+4+entities"

Un desafío de analizar archivos de registro de Apache es que hay situaciones en las que dos diferentes direcciones URL realmente se refieren a la misma página. Por ejemplo, /custer/ y /custer/index.shtml son la misma página, por lo que el cálculo de las diez páginas más populares realmente debe tenerlo en cuenta. La conversión realizada por la invocación de sed ya asegura que /custer y /custer/ no son tratados por separado, pero sabiendo que el nombre de archivo predeterminado para un directorio determinado podría ser un poco más complicado. La utilidad del análisis de las diez más populares referrers puede mejorarse por Recortar URL referente a sólo el nombre de base de dominio (por ejemplo, slashdot.org).

Algunos scripts, no se incorporan en este artículo y tampoco son necesarios, no sabemos que contienen, así que lo único que vamos a hacer es ignorarlos al ponerles delante un comentario "#". Además lo hemos mejorado "ligeramente"... para que puedas apreciar todos los cambios que se pueden hacer, este script es para LinuxParty, pero puedes "cambiarlo" para tu host/dominio.


 #!/bin/sh

# webaccess - analyze an Apache-format access_log file, extracting
# useful and interesting statistics

# bytes_in_gb=22048576
# scriptbc="$HOME/bin/scriptbc"
# nicenumber="$HOME/bin/nicenumber"
host="linux-party.com"

if [ $# -eq 0 -o ! -f "$1" ] ; then
echo "Usage: $(basename $0) logfile" >&2
exit 1
fi

LANG=es_ES.UTF-8

echo '<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
<title>'$host'</title>
</head>
<body>'

echo "<pre>"

firstdate="$(head -1 "$1" | awk '{print $4}' | sed 's/\[//')"
lastdate="$(tail -1 "$1" | awk '{print $4}' | sed 's/\[//')"

echo "Results of analyzing log file $1"
echo " "
echo `uname -a`
echo "-------------------------------"
echo `date`
echo "-------------------------------"
echo " Start date: $(echo $firstdate|sed 's/:/ at /')"
echo " End date: $(echo $lastdate|sed 's/:/ at /')"

hits="$(wc -l < "$1" | sed 's/[^[:digit:]]//g')"

# echo " Hits: $($nicenumber $hits) (total accesses)"

pages="$(grep -ivE '(.txt|.gif|.jpg|.png)' "$1" | wc -l | sed 's/[^[:digit:]]//g')"

# echo " Pageviews: $($nicenumber $pages) (hits minus graphics)"

totalbytes="$(awk '{sum+=$10} END {print sum}' "$1")"

# echo -n " Transferred: $($nicenumber $totalbytes) bytes "

#if [ $totalbytes -gt $bytes_in_gb ] ; then
# echo "($($scriptbc $totalbytes / $bytes_in_gb) GB)"
#elif [ $totalbytes -gt 1024 ] ; then
# echo "($($scriptbc $totalbytes / 1024) MB)"
#else
# echo ""
#fi

# now let's scrape the log file for some useful data:
echo "-----------------------------------------------"
echo " "
echo "The 70 most popular pages were:"
echo "-----------------------------------------------"
echo " "
awk '{print $7}' "$1" | grep -ivE '(.gif|.jpg|.png)' | \
sed 's/\/$//g' | sort | \
uniq -c | sort -rn | head -70

echo " "
echo " "
echo "The 50 most common referrer URLs were:"
echo "---------------------------------------"

echo " "
echo " "
awk '{print $11}' "$1" | \
grep -vE "(^"-"$|/www.$host|/$host)" | \
sort | uniq -c | sort -rn | head -50

echo " "
echo "Los 100 navegadores mas populares aqui:"
echo "----------------------------------------"
echo "</pre>"
echo " "
echo '<table style="width: 12%;" border="1" cellpadding="0" cellspacing="0"> '
echo " "
echo "<pre>"
awk '{print "<tr> <td> "$12" </td> <td> "$13" </td><td> "$14" </td><td> "$15" </td><td> "$16" </td><td> "$17" </td><td> "$18" </td><td> Su IP.: <a href=\"http://network-tools.com/default.asp?prog=express&host="$1"\">"$1"</a> </td>\n"}' "$1" | \
grep -vE "(^"-"$|/www.$host|/$host)" | \
sort | uniq -c | sort -rn | head -100
echo "</pre>"
echo
echo '</table>
</body>
</html>'

exit 0

 


Si, tienes ideas para mejorar el código, o lo has mejorado, te agradeceríamos (todos los lectores) que publicaras el código en los comentarios, esa es la idea del código abierto.

Correo electrónico

Desarrollo e Internet

Internet

  • Webs
  • eCommerce
  • Templates
  • Migraciones

Móviles

  • Android
  • iPhone
  • Multiplataformas
  • WebApps

Equipos

  • Windows/Linux
  • Ficheros
  • Databases
  • Servidores.