LinuxParty
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:
(Antes de copiar éste código, sepa que abajo se encuentra la versión más reciente y actualizada del mismo)
#!/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.
LA VERSIÓN MEJORADA,MÁS RECIENTE:
#!/bin/sh # # Versión del script. 2.0 - Junio de 2022 # # webaccess - analyze an Apache-format access_log file, extracting # useful and interesting statistics # # webaccess.sh logfile title # # Example # # webaccess.sh /var/log/access_ssl_log LINUXPARTY # # bytes_in_gb=22048576 # scriptbc="$HOME/bin/scriptbc" # nicenumber="$HOME/bin/nicenumber" # # Parámetro 1 pasado por comandos Param1=$1 # Parámetro 2 pasado por comandos Param2=$2 # # Cómo se usa: #
# webaccess /var/log/nombrefichero.log NOMBREDELREPORTE
# if [ $# -eq 0 -o ! -f "$1" ] ; then echo "Uso: $(basename $0) logfile REPORTNAME" >&2 exit 1 fi # Título para el fichero. if [ "$Param2" == "" ] ; then mytitle="$Param1" else mytitle="$Param2" fi LANG=es_ES.UTF-8 echo '<html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>'$mytitle'</title> </head> <body>' echo "<pre>" firstdate="$(head -1 "$1" | awk '{print $4}' | sed 's/\[//')" lastdate="$(tail -1 "$1" | awk '{print $4}' | sed 's/\[//')" echo "Resultados de analizar el fichero log: $1" echo " " echo `uname -a` echo "-------------------------------" echo `TZ='Europe/Madrid' date` echo `date` echo `date -u` 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 "Las 150 páginas más populares fueron:" echo "-----------------------------------------------" echo " " # Podemos poner detrás del grep, los valores a no mostrar y otro grep que siga discriminando. awk '{print $7}' "$1" | grep -ivE '(.gif|.jpg|.png|.css|.js|.woff|.ico)' | grep -ivE "templates" | \ sed 's/\/$//g' | sort | \ uniq -c | sort -rn | head -150 echo " " echo "-----------------------------------------------" echo "Las 50 páginas MENOS populares fueron:" echo "-----------------------------------------------" echo " " # Podemos poner detrás del grep, los valores a no mostrar y otro grep que siga discriminando. awk '{print $7}' "$1" | grep -ivE '(.gif|.jpg|.png|.css|.js|.woff|.ico)' | grep -ivE "templates" | \ sed 's/\/$//g' | sort | \ uniq -c | sort -rn | tail -50 echo " " echo "-----------------------------------------------" echo "Los 150 EXTERNAL referencias más comunes -URLs- fueron:" echo "-----------------------------------------------" echo " " awk '{print $11}' "$1" | \ # grep -vE "(^"-"|/www.$host|/$host)" | \ grep -vE "-" | \ # Es importante poner un grep que discrimine NUESTRO nombre de dominio, o si # usa el mismo script para varios dominios, todos los dominios a discriminar # como por ejemplo: # grep -vE "dominio1.com" | grep -vE "dominio2.com" | \ # grep -vE "ajuca.com|dedodigital.com|linuxparty.es" | \ sort | uniq -c | sort -rn | head -150 # Aquí debemos poner otra cosa que no coincida con el el valor actual # Y por supuesto, que TAMPOCO coincida con el nonbre del dominio, deje # El ejemplo puesto por ser suficientemente válido. host="CHANGETOOTHER" echo " " echo "-----------------------------------------------" echo "Los 150 referencias INTERNAS más comunes -URLs- fueron:" echo "-----------------------------------------------" echo " " awk '{print $11}' "$1" | \ # PUEDE JUGAR a poner un grep que discrimine NUESTRO nombre de dominio, o si # usa el mismo script para varios dominios, todos los dominios a discriminar # como por ejemplo: # # grep -vE "(^"-"$|/www.$host|/$host)" | grep -vE "dominio1.com" | grep -vE "dominio2.com" | \ # grep -vE "(^"-"$|/www.$host|/$host)" | grep -ivE '(.gif|.jpg|.png|.css|.js|.woff|.ico)' | grep -ivE "templates" | \ sort | uniq -c | sort -rn | head -150 echo " " echo "-----------------------------------------------" echo "Los 30 referencias INTERNAS MENOS comunes -URLs- fueron:" echo "-----------------------------------------------" echo " " awk '{print $11}' "$1" | \ grep -vE "(^"-"$|/www.$host|/$host)" | \ sort | uniq -c | sort -rn | tail -30 # Lo de los navegadores lo dejamos comentado, porque bueno... No parece muy interesante. # Si lo quieres hacer funcionar, basta que le quites el comentario delante "#" y listo. # echo " " # echo "Los 100 navegadores mas populares aqui:" # echo "----------------------------------------" # echo "</pre>" # echo " " # echo '<table style="width: 12%;" border="1" cellpadding="0" cellspacing="0"> ' # echo "<tr><td>" # awk '{print "</td><td> Su IP.: <a href=\"http://network-tools.com/default.asp?prog=express&host="$1"\" target=\"_blank\">"$1"</a></td><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=sbl&host="$1"\" target=\"_blank\">"$1"</a></td><tr><td>\n"}' "$1" | \ # grep -vE "(^"-"$|/www.$host|/$host)" | \ # sort | uniq -c | sort -rn | head -100 #echo '</table>' echo '</pre> </body> </html>'
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.
-
Scripting
- Iniciar una aplicación o un programa automáticamente desde el Cron en Linux
- Operaciones matemáticas en Shell Scripts
- 30 formas de validar archivos de configuración o scripts en Linux
- Operaciones artiméticas en Shell Scripts
- Cómo intercambiar el contenido de dos archivos en Linux
- Buscar directorios vacíos en Linux y borrarlos si procede.
- Shell Script Linux: Renombra quitando espacios
- Usar con crontab - último sábado del mes
- Shell Script de Linux para analizar un Fichero Access.log
- Analizar ficheros log de Linux con Scripts
- woof Código fuente
- Como tener seguro, protegido y encriptado tu Navegador Web Firefox (versión mejorada - versión 3)
- Arrays en Bash y Loops: iterar a través de los valores de la matriz
- Pasar una variable a AWK mediante la Shell.
- System Tar and Restore: un versátil script de copia de seguridad del sistema para Linux