<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>tail -f &#124; sysadmin &#187; access_log</title>
	<atom:link href="http://www.tail-f.com.ar/tag/access_log/feed" rel="self" type="application/rss+xml" />
	<link>http://www.tail-f.com.ar</link>
	<description>Noticias y recursos para sysadmins Unix</description>
	<lastBuildDate>Mon, 28 Nov 2011 21:44:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Python: Ver dominios de Apache que más transferencia consumen</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/python-ver-dominios-de-apache-que-mas-transferencia-consumen.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/python-ver-dominios-de-apache-que-mas-transferencia-consumen.html#comments</comments>
		<pubDate>Thu, 11 Mar 2010 01:47:12 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[access_log]]></category>
		<category><![CDATA[log]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=361</guid>
		<description><![CDATA[Hace un rato publiqué un post con un script para ver qué dominios de Apache consumen mayor transferencia. El script en BASH toma unos 7 segundos en procesar 750 archivos de uno de mis servidores. Ahora hice una versión en Python, para la que me dieron algunos consejos los chicos de PyAr, y toma aproximadamente [...]]]></description>
			<content:encoded><![CDATA[<p>Hace un rato publiqué un post con un script para ver <a href="http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/ver-dominios-de-apache-que-mas-transferencia-consumen.html">qué dominios de Apache consumen mayor transferencia</a>. El script en <a href="http://www.tail-f.com.ar/tag/bash">BASH</a> toma unos 7 segundos en procesar 750 archivos de uno de mis servidores. Ahora hice una versión en <a href="http://www.tail-f.com.ar/tag/python">Python</a>, para la que me dieron algunos consejos los chicos de <a href="http://python.org.ar/pyar/">PyAr</a>, y toma aproximadamente 4 segundos en procesar los mismos archivos. Aquí les dejo el código:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="co1">#!/usr/bin/env python</span><br />
<span class="st0">&quot;&quot;</span><span class="st0">&quot; Access Log Parser</p>
<p>Parses all the files in a directory<br />
treating them as access_log files<br />
and outputs the list of files sorted<br />
by transfered megabytes. Useful for<br />
identifying heavy users.</p>
<p>Usage:<br />
./access_log_parser.py &lt;base_dir&gt;<br />
base_dir = directory where the access_log files are<br />
&quot;</span><span class="st0">&quot;&quot;</span><br />
<span class="kw1">import</span> <span class="kw3">sys</span><br />
<span class="kw1">import</span> <span class="kw3">os</span><br />
<span class="kw1">import</span> <span class="kw3">time</span><br />
<span class="kw1">from</span> <span class="kw3">operator</span> <span class="kw1">import</span> itemgetter</p>
<p><span class="kw1">def</span> main <span class="br0">&#40;</span>args<span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; <span class="st0">&quot;&quot;</span><span class="st0">&quot;Main</p>
<p>&nbsp; &nbsp; Main function of the script.<br />
&nbsp; &nbsp; This is where the magic happens.<br />
&nbsp; &nbsp; It takes the script arguments<br />
&nbsp; &nbsp; and returns an exit code.<br />
&nbsp; &nbsp; &quot;</span><span class="st0">&quot;&quot;</span></p>
<p>&nbsp; &nbsp; <span class="co1"># Parameter checking</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span>args<span class="br0">&#41;</span> &lt; <span class="nu0">2</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Usage: %s &lt;base_dir&gt;&quot;</span> % args<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">1</span></p>
<p>&nbsp; &nbsp; <span class="kw1">if</span> <span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">isdir</span><span class="br0">&#40;</span>args<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; base_dir = args<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; <span class="kw1">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">print</span> <span class="st0">&quot;%s is not a directory&quot;</span> % args<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">return</span> <span class="nu0">2</span></p>
<p>&nbsp; &nbsp; <span class="co1"># Init vars</span><br />
&nbsp; &nbsp; t1 = <span class="kw3">time</span>.<span class="kw3">time</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; mbyte = <span class="nu0">1048576.0</span><br />
&nbsp; &nbsp; domains = <span class="br0">&#91;</span><span class="br0">&#93;</span></p>
<p>&nbsp; &nbsp; <span class="co1"># Start processing files</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> item <span class="kw1">in</span> <span class="kw3">os</span>.<span class="me1">listdir</span><span class="br0">&#40;</span>args<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; path = <span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">join</span><span class="br0">&#40;</span>base_dir, item<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">isfile</span><span class="br0">&#40;</span>path<span class="br0">&#41;</span> <span class="kw1">and</span> \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw3">os</span>.<span class="me1">path</span>.<span class="me1">getsize</span><span class="br0">&#40;</span>path<span class="br0">&#41;</span> &gt; <span class="nu0">0</span>:</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bytes = <span class="nu0">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init_date = <span class="kw2">None</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data = <span class="kw2">None</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># Process file lines</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> line <span class="kw1">in</span> <span class="kw2">open</span><span class="br0">&#40;</span>path, <span class="st0">&#8216;r&#8217;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data = line.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&quot; &quot;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> init_date <span class="kw1">is</span> <span class="kw2">None</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; init_date = data<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="nu0">1</span>:<span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bytes += <span class="kw2">long</span><span class="br0">&#40;</span>data<span class="br0">&#91;</span><span class="nu0">9</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">ValueError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pass</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; domains.<span class="me1">append</span><span class="br0">&#40;</span><span class="br0">&#123;</span><span class="st0">&#8216;domain&#8217;</span>: item, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;mbytes&#8217;</span>: bytes / mbyte, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;init_date&#8217;</span>: init_date, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;end_date&#8217;</span>: data<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="nu0">1</span>:<span class="br0">&#93;</span> <span class="br0">&#125;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="co1"># Print out sorted information</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> domain <span class="kw1">in</span> <span class="kw2">sorted</span><span class="br0">&#40;</span>domains, key=itemgetter<span class="br0">&#40;</span><span class="st0">&#8216;mbytes&#8217;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;%.2f MB | From: %s | To: %s | %s&quot;</span> % \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>domain<span class="br0">&#91;</span><span class="st0">&#8216;mbytes&#8217;</span><span class="br0">&#93;</span>, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;domain<span class="br0">&#91;</span><span class="st0">&#8216;init_date&#8217;</span><span class="br0">&#93;</span>, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;domain<span class="br0">&#91;</span><span class="st0">&#8216;end_date&#8217;</span><span class="br0">&#93;</span>, \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;domain<span class="br0">&#91;</span><span class="st0">&#8216;domain&#8217;</span><span class="br0">&#93;</span><span class="br0">&#41;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Generated in %d seconds&quot;</span> % <span class="br0">&#40;</span><span class="kw3">time</span>.<span class="kw3">time</span><span class="br0">&#40;</span><span class="br0">&#41;</span> &#8211; t1<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="nu0">0</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; <span class="kw3">sys</span>.<span class="me1">exit</span><span class="br0">&#40;</span>main<span class="br0">&#40;</span><span class="kw3">sys</span>.<span class="me1">argv</span><span class="br0">&#41;</span><span class="br0">&#41;</span></div>
<p>Para ejecutarlo:</p>
<pre>./access_log_parser.py /tmp/domain_logs
...
544.30 MB | From: 10/Mar/2010:02:48:33 | To: 10/Mar/2010:18:13:25 | dominio1.com.ar.log
602.34 MB | From: 10/Mar/2010:00:23:09 | To: 10/Mar/2010:23:39:45 | dominio2.com.ar.log
944.03 MB | From: 10/Mar/2010:00:49:35 | To: 10/Mar/2010:23:39:57 | dominio3.com.ar.log
Generated in 3 seconds
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/python-ver-dominios-de-apache-que-mas-transferencia-consumen.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ver dominios de Apache que más transferencia consumen</title>
		<link>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/ver-dominios-de-apache-que-mas-transferencia-consumen.html</link>
		<comments>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/ver-dominios-de-apache-que-mas-transferencia-consumen.html#comments</comments>
		<pubDate>Wed, 10 Mar 2010 19:07:44 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[BASH]]></category>
		<category><![CDATA[access_log]]></category>
		<category><![CDATA[logs]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=350</guid>
		<description><![CDATA[Frecuentemente me encuentro ante la necesidad de saber qué dominios de los que tengo alojados en mis servidores consumen más tráfico HTTP. Como éste es el tipo de tráfico más importante y que más incide en el desempeño general de mis servidores, saber qué dominios transfieren más datos por HTTP me orienta en la búsqueda [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tail-f.com.ar/wp-content/uploads/nerd.jpg"><img class="alignright size-medium wp-image-354" title="nerd" src="http://www.tail-f.com.ar/wp-content/uploads/nerd-300x227.jpg" alt="" width="300" height="227" /></a>Frecuentemente me encuentro ante la necesidad de saber qué dominios de los que tengo alojados en mis servidores consumen más tráfico HTTP. Como éste es el tipo de tráfico más importante y que más incide en el desempeño general de mis servidores, saber qué dominios transfieren más datos por HTTP me orienta en la búsqueda de heavy users. Para ello hice un script hace algún tiempo, y ahora lo estuve revisando, retocando y simplificando, y decidí compartirlo.</p>
<p>En el entorno de <a href="http://www.tail-f.com.ar/tag/directadmin">Directadmin</a>, los logs de <a href="http://www.tail-f.com.ar/tag/apache">Apache</a> se encuentran en /var/log/httpd. Allí hay una carpeta &#8220;domains&#8221; que guarda los logs de cada dominio. Por cada dominio hay tres logs: dominio.com.log, dominio.com.error.log y dominio.com.bytes. El primero es el access_log, el segundo el error_log y el tercero solamente guarda la cantidad de bytes de cada request. La opción más sencilla es trabajar con este último tipo de logs, pero el problema que tienen es que no indican la fecha. Si bien se supone que los logs de Directadmin rotan una vez por día, alguna vez me ha pasado que por razones que nunca pude descubrir, algunos logs no rotaban y generaban ciertas confusiones. Por lo tanto, el script que dejo usa los access_logs. Además esta opción es reutilizable en otras implementaciones de Apache que no tengan archivos de bytes.</p>
<p>El código:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="re3"># Access Log Parser</span><br />
<span class="re3">#</span><br />
<span class="re3"># Parses all the files <span class="kw1">in</span> a directory</span><br />
<span class="re3"># treating them <span class="kw2">as</span> access_log files</span><br />
<span class="re3"># and outputs the list of files sorted</span><br />
<span class="re3"># by transfered megabytes. Useful for</span><br />
<span class="re3"># identifying heavy <span class="kw2">users</span>.</span><br />
<span class="re3">#</span><br />
<span class="re3"># Usage:</span><br />
<span class="re3"># ./access_log_parser.<span class="kw2">sh</span> &lt;base_dir&gt;</span><br />
<span class="re3"># base_dir = directory where the access_log files are</span></p>
<p><span class="kw1">if</span> <span class="br0">&#91;</span> -z $<span class="nu0">1</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Usage: $0 &quot;</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">1</span><br />
<span class="kw1">fi</span></p>
<p><span class="re2">BASE_DIR=</span>$<span class="nu0">1</span><br />
<span class="re2">T1=</span>`<span class="kw2">date</span> +%s`<br />
<span class="kw1">for</span> <span class="kw2">file</span> <span class="kw1">in</span> <span class="re1">$BASE_DIR</span>/*;<br />
<span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="re2">size=</span>`<span class="kw2">stat</span> -c %s <span class="re1">$file</span>`<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re1">$size</span> -gt <span class="nu0">0</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">from=</span>`<span class="kw2">head</span> <span class="nu0">-1</span> <span class="re1">$file</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{print($4)}&#8217;</span> |sed <span class="st0">&#8216;s/^<span class="es0">\[</span>//&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">to=</span>`<span class="kw2">tail</span> <span class="nu0">-1</span> <span class="re1">$file</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{print($4)}&#8217;</span> |sed <span class="st0">&#8216;s/^<span class="es0">\[</span>//&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">bytes=</span>`<span class="kw2">cat</span> <span class="re1">$file</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{a+=$10}END{print a}&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">mbytes=</span>`<span class="kw3">echo</span> <span class="re1">$bytes</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{print $1 / 1048576}&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> &nbsp;<span class="st0">&quot;$mbytes MB ($bytes bytes) | From: $from | To: $to | ${file:${#BASE_DIR}+1}&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">fi</span><br />
<span class="kw1">done</span> \<br />
| <span class="kw2">sort</span> -nb<br />
<span class="re2">T=</span>`<span class="kw2">date</span> +%s`</div>
<p>Un detalle importante: el script levanta todos los archivos de un directorio que se especifica por parámetro. Esto es así porque yo lo invoco desde otro script:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="re3">#!/bin/bash</span><br />
<span class="re2">LOG_DIR=</span>/var/log/httpd/domains/<br />
<span class="re2">TMP=</span>/tmp/domain_logs<br />
<span class="kw1">if</span> <span class="br0">&#91;</span> ! -d <span class="re1">$TMP</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw2">mkdir</span> -p <span class="re1">$TMP</span><br />
<span class="kw1">fi</span></p>
<p><span class="kw2">rm</span> -f <span class="re1">$TMP</span>/*</p>
<p><span class="kw3">cd</span> <span class="re1">$LOG_DIR</span><br />
<span class="kw1">for</span> i <span class="kw1">in</span> `<span class="kw2">ls</span> *.log |grep -v error`; <span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="kw2">ln</span> <span class="re1">$i</span> <span class="re1">$TMP</span>/<span class="re1">$i</span><br />
<span class="kw1">done</span><br />
/root/access_log_parser.<span class="kw2">sh</span> <span class="re1">$TMP</span></div>
<p>Este último script lo que hace es crear un directorio temporal (si no existe). Vaciar su contenido. Y luego generar hardlinks a todos los access_logs de /var/log/httpd/domains. De esta forma, no me tengo que preocupar por si los logs son modificados mientras yo estoy ejecutando el script. Por último, ejecuta mi primer script (access_log_parser.sh) y le pasa como parámetro el directorio temporal donde están los access_logs.</p>
<p>Por último, la salida del script sería algo así:</p>
<pre>...
186.995 MB (196078184 bytes) | From: 10/Mar/2010:00:27:47 | To: 10/Mar/2010:16:51:09 | dominio1.com.ar.log
187.096 MB (196184596 bytes) | From: 10/Mar/2010:03:24:55 | To: 10/Mar/2010:16:51:24 | dominio2.com.ar.log
245.692 MB (257626221 bytes) | From: 10/Mar/2010:02:53:50 | To: 10/Mar/2010:16:39:54 | dominio3.com.log
273.46 MB (286743390 bytes) | From: 10/Mar/2010:02:48:33 | To: 10/Mar/2010:14:59:29 | dominio4.com.ar.log
306.344 MB (321224473 bytes) | From: 10/Mar/2010:00:23:09 | To: 10/Mar/2010:16:51:20 | dominio5.com.ar.log
444.097 MB (465669066 bytes) | From: 10/Mar/2010:00:49:35 | To: 10/Mar/2010:16:51:20 | dominio6.com.ar.log
Generated in 6 seconds</pre>
<p>Les dejo, de yapa, la opción del script utilizando los logs de bytes. Como dije, esta opción es un poco más sencilla y veloz, pero no nos dice las fechas de los logs.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="re3">#!/bin/bash</span></p>
<p><span class="kw1">if</span> <span class="br0">&#91;</span> -z $<span class="nu0">1</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Usage: $0 &quot;</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">1</span><br />
<span class="kw1">fi</span></p>
<p><span class="re2">BASE_DIR=</span>$<span class="nu0">1</span><br />
<span class="re2">T1=</span>`<span class="kw2">date</span> +%s`<br />
<span class="kw1">for</span> <span class="kw2">file</span> <span class="kw1">in</span> <span class="re1">$BASE_DIR</span>/*.bytes;<br />
<span class="kw1">do</span><br />
&nbsp; &nbsp; <span class="re2">size=</span>`<span class="kw2">stat</span> -c %s <span class="re1">$file</span>`<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re1">$size</span> -gt <span class="nu0">0</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">bytes=</span>`<span class="kw2">cat</span> <span class="re1">$file</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{a+=$1}END{print a}&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">mbytes=</span>`<span class="kw3">echo</span> <span class="re1">$bytes</span> | <span class="kw2">awk</span> <span class="st0">&#8216;{print $1 / 1048576}&#8217;</span>`<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> &nbsp;<span class="st0">&quot;$mbytes MB ($bytes bytes) ${file:${#BASE_DIR}+1}&quot;</span><br />
&nbsp; &nbsp; <span class="kw1">fi</span><br />
<span class="kw1">done</span> \<br />
| <span class="kw2">sort</span> -nb<br />
<span class="re2">T=</span>`<span class="kw2">date</span> +%s`<br />
<span class="kw3">echo</span> <span class="st0">&quot;Generated in $(($T-$T1)) seconds&quot;</span></div>
<p>Y la salida sería así:</p>
<pre># ./parser.sh /var/log/httpd/domains
...
181.716 MB (190543470 bytes) dominio1.com.bytes
187.115 MB (196203973 bytes) dominio2.com.ar.bytes
189.093 MB (198278283 bytes) dominio3.com.ar.bytes
245.692 MB (257626221 bytes) dominio4.com.bytes
273.472 MB (286756234 bytes) dominio5.com.ar.bytes
314.32 MB (329588717 bytes) dominio6.com.ar.bytes
444.516 MB (466108759 bytes) dominio7.com.ar.bytes
Generated in 2 seconds</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/servicios/httpd/apache-httpd-servicios/ver-dominios-de-apache-que-mas-transferencia-consumen.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Contar requests por IP de un access_log de Apache en BASH</title>
		<link>http://www.tail-f.com.ar/programacion/bash/contar-requests-por-ip-de-un-access_log-de-apache-en-bash.html</link>
		<comments>http://www.tail-f.com.ar/programacion/bash/contar-requests-por-ip-de-un-access_log-de-apache-en-bash.html#comments</comments>
		<pubDate>Tue, 10 Feb 2009 23:15:38 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[BASH]]></category>
		<category><![CDATA[access_log]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=237</guid>
		<description><![CDATA[Bueno, en mi último post publiqué un script muy sencillo en Python para contar la cantidad de requests por IP en un access_log de Apache. Como sospechaba, había una forma quizás más sencilla y más óptima de hacer lo mismo en BASH, así que hace un rato jugando un poco me salió y se los [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_37" class="wp-caption alignright" style="width: 160px"><a href="http://www.tail-f.com.ar/wp-content/uploads/apache1.gif"><img class="size-thumbnail wp-image-37" title="apache1" src="http://www.tail-f.com.ar/wp-content/uploads/apache1-150x150.gif" alt="Apache Web Server" width="150" height="150" /></a><p class="wp-caption-text">Apache Web Server</p></div>
<p>Bueno, en <a href="http://www.tail-f.com.ar/2009/02/09/programacion/python/script-para-contar-requests-por-ip-de-un-access_log-de-apache.html">mi último post</a> publiqué un script muy sencillo en Python para contar la cantidad de requests por IP en un access_log de Apache. Como sospechaba, había una forma quizás más sencilla y más óptima de hacer lo mismo en BASH, así que hace un rato jugando un poco me salió y se los muestro aquí.</p>
<pre># cat /var/log/httpd/access_log |awk '{print($1)}'|sort |uniq -c |sort</pre>
<p><strong>¿Cómo funciona?</strong></p>
<p>Lo primero que hacemos es abrir el archivo con cat, el contenido se pasa a awk con el cual obtenemos la primera columna (lo mismo lo podríamos hacer con cut, pero estoy más acostumbrado a awk). Eso nos devuelve la lista de las IPs. Eso lo pasamos a sort que ordena las IPs antes de poder pasarselo a uniq. Éste último comando, con el parámetro -c se ocupa de contar las líneas repetidas en un listado ordenado (por eso el sort anterior). Y por último le volvemos a pasar todo a sort para que lo ordene en forma ascendente de acuerdo a la cantidad de ocurrencias de cada IP.</p>
<p>En realidad el script de Python lo ordenaba al revés (en forma descendente), para ello deberíamos pasarle el parámetro &#8220;-r&#8221; al último sort.</p>
<p>Espero que les sea de utilidad. La versión de Python queda sobre todo como base por si es necesario hacer algo un poco más interesante jeje.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/programacion/bash/contar-requests-por-ip-de-un-access_log-de-apache-en-bash.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Script para contar requests por IP de un access_log de Apache</title>
		<link>http://www.tail-f.com.ar/programacion/python/script-para-contar-requests-por-ip-de-un-access_log-de-apache.html</link>
		<comments>http://www.tail-f.com.ar/programacion/python/script-para-contar-requests-por-ip-de-un-access_log-de-apache.html#comments</comments>
		<pubDate>Mon, 09 Feb 2009 13:04:15 +0000</pubDate>
		<dc:creator>elbarto</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[access_log]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://www.tail-f.com.ar/?p=234</guid>
		<description><![CDATA[El otro día necesitaba saber si había alguna/s IP/s que estuvieran haciendo muchos requests a un dominio, así que escribí un muy sencillo script en Python para obtener la cantidad de peticiones por IP en un access_log de Apache. Se los dejo por si a alguien le sirve. Se me ocurre que con bash y [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_100" class="wp-caption alignright" style="width: 160px"><a href="http://www.tail-f.com.ar/wp-content/uploads/python-logo.gif"><img class="size-thumbnail wp-image-100" title="python-logo" src="http://www.tail-f.com.ar/wp-content/uploads/python-logo-150x71.gif" alt="Python" width="150" height="71" /></a><p class="wp-caption-text">Python</p></div>
<p>El otro día necesitaba saber si había alguna/s IP/s que estuvieran haciendo muchos requests a un dominio, así que escribí un muy sencillo script en Python para obtener la cantidad de peticiones por IP en un access_log de Apache. Se los dejo por si a alguien le sirve. Se me ocurre que con bash y las distintas herramientas de unix para manipular archivos y strings quizás habría podido hacer algo un poco más óptimo (aunque esto anda bastante rápido), pero me sentía más cómodo con Python.</p>
<p><strong>Script</strong></p>
<pre>#!/usr/bin/python
import sys
from operator import itemgetter

file = open(sys.argv[1], "r")
ips = {}
line = None
while line != "":
    line = file.readline()
    ip = line.rsplit(" ")[0]
    if ip != "":
        if ips.has_key(ip):
            ips[ip] = ips[ip] + 1
        else:
            ips[ip] = 1

file.close()
list = sorted(ips.items(), key=itemgetter(1), reverse=True)
for item in list:
        print item[0].rjust(15, " "), ": ", item[1]</pre>
<p><strong>Cómo usarlo</strong></p>
<p>Guardar el script en un archivo por ejemplo countip.py. Luego darle permisos de ejecución y correrlo.</p>
<pre># chmod +x countip.py
# ./countip.py /var/log/httpd/access_log</pre>
<p>Según mis pruebas el script procesa un log de más de 14 mil líneas en aproximadamente 0,09 segundos.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tail-f.com.ar/programacion/python/script-para-contar-requests-por-ip-de-un-access_log-de-apache.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

