<?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>Shakaran &#187; Apache</title> <atom:link href="http://shakaran.net/blog/category/open-source/apache/feed/" rel="self" type="application/rss+xml" /><link>http://shakaran.net/blog</link> <description>Blog de un estudiante de ingeniería informática y sysadmin</description> <lastBuildDate>Wed, 25 Apr 2012 15:02:15 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <image><link>http://shakaran.net/blog</link> <url>http://www.shakaran.net/blog/wp-content/favicon.png</url><title>Shakaran</title> </image> <item><title>Depurar y perfilar funciones PHP gráficamente con XDebug, KCacheGrind y Webgrind en Ubuntu 11.10</title><link>http://shakaran.net/blog/2012/01/depurar-y-perfilar-funciones-php-graficamente-con-xdebug-kcachegrind-y-webgrind-en-ubuntu-11-10/</link> <comments>http://shakaran.net/blog/2012/01/depurar-y-perfilar-funciones-php-graficamente-con-xdebug-kcachegrind-y-webgrind-en-ubuntu-11-10/#comments</comments> <pubDate>Wed, 18 Jan 2012 22:19:48 +0000</pubDate> <dc:creator>shakaran</dc:creator> <category><![CDATA[Apache]]></category> <category><![CDATA[Open Source]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[software libre]]></category> <category><![CDATA[Ubuntu]]></category> <category><![CDATA[benchmark]]></category> <category><![CDATA[dbg]]></category> <category><![CDATA[debug]]></category> <category><![CDATA[debugger]]></category> <category><![CDATA[depurar]]></category> <category><![CDATA[design]]></category> <category><![CDATA[eficiencia]]></category> <category><![CDATA[ejecución]]></category> <category><![CDATA[escalabe]]></category> <category><![CDATA[github]]></category> <category><![CDATA[grafico]]></category> <category><![CDATA[grafo]]></category> <category><![CDATA[kcachegrind]]></category> <category><![CDATA[migracion]]></category> <category><![CDATA[nusphere]]></category> <category><![CDATA[path]]></category> <category><![CDATA[pear]]></category> <category><![CDATA[perfilar]]></category> <category><![CDATA[performance]]></category> <category><![CDATA[php5]]></category> <category><![CDATA[phped]]></category> <category><![CDATA[profiler]]></category> <category><![CDATA[profiling]]></category> <category><![CDATA[remote]]></category> <category><![CDATA[scalability]]></category> <category><![CDATA[stats]]></category> <category><![CDATA[tiempo]]></category> <category><![CDATA[webgrind]]></category> <category><![CDATA[xdebug]]></category> <category><![CDATA[zend]]></category><guid isPermaLink="false">http://shakaran.net/blog/?p=1143</guid> <description><![CDATA[En desarrollo web y por lo general, en cualquier aplicación que requiera tener una demanda escalable, son muy importantes los algoritmos empleados, las llamadas a funciones nativas y las estructuras de datos utilizadas. En aplicaciones PHP con miles de líneas de código se necesita un diseño eficiente para poder manejar una buena ejecución del código [...]<br /><div><img src="http://shakaran.net/blog/wp-content/plugins/gd-star-rating/gfx.php?value=0.0" /></div><div>Rating: 0.0/<strong>10</strong> (0 votes cast)</div><br />]]></description> <content:encoded><![CDATA[<div class="wpbuzzer_button" style="float: right"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="normal-button" data-url="http://shakaran.net/blog/2012/01/depurar-y-perfilar-funciones-php-graficamente-con-xdebug-kcachegrind-y-webgrind-en-ubuntu-11-10/" data-imageurl=""></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div><div class="wp-caption aligncenter" style="width: 580px"><a href="http://shakaran.net/blog/wp-content/uploads/2012/01/the-art-of-debuggin-with-php.jpg"><img class=" wp-image-1145 " title="El arte de depurar y perfilar con PHP" src="http://shakaran.net/blog/wp-content/uploads/2012/01/the-art-of-debuggin-with-php.jpg" alt="El arte de depurar y perfilar con PHP" width="570" /></a><p class="wp-caption-text"><strong>El arte de depurar y perfilar con PHP</strong></p></div><p>En desarrollo web y por lo general, en cualquier aplicación que requiera tener una <strong>demanda escalable</strong>, son muy importantes los algoritmos empleados, las llamadas a funciones nativas y las estructuras de datos utilizadas.</p><p>En aplicaciones PHP con miles de líneas de código se necesita un <strong>diseño eficiente</strong> para poder manejar una buena ejecución del código PHP.</p><p>Principalmente se busca <strong>reducir el consumo</strong> de memoria y CPU al máximo posible, sin que la aplicación pierda funcionalidad, ni características. Para lograr este objetivo y que la aplicación sea <strong>escalable</strong>, se busca utilizar buenas herramientas de <strong>depuración y profiling</strong> (perfilado de rendimiento). Con ello se consigue que el programador o ingeniero disponga de una buena perspectiva de lo que esta haciendo a<strong> bajo nivel</strong> su aplicación y decidir en consecuencia que técnica aplicar.</p><p>El perfilado o medición del rendimiento (<em>performance profiling</em>) permite ejecutar código en un entorno controlado y devolver un listado con <strong>estadísticas</strong> de tiempo gastado en cada funcion, longitud de consultas a la base de datos o la cantidad de memoria que ha sido usada. De esta forma, se puede desechar codígo lento o superfluo de una manera muy rápida o incluso realizar pequeños trucos en partes críticas para ganar más rendimiento.</p><h3><span style="color: #993300;">Herramientas</span></h3><p>En PHP existen varias <strong>herramientas de depuración</strong>(debugging) y localización de <strong>cuellos de botella</strong>(bottleneck) para perfilado de rendimiento.</p><p>Las herramientas más utilizadas son:</p><ul><li><a title="BenchMark PEAR PHP project" href="http://pear.php.net/package/benchmark" target="_blank">BenchMark</a> es un proyecto PEAR de PHP, pero actualmente no esta mantenido.</li><li><a title="DBG PHP Debugger" href="http://www.php-debugger.com/dbg/" target="_blank">DBG PHP Debugger</a> es otra herramienta de depuración que dispone de una <strong>versión comercial</strong> y otra gratuita. La versión gratuita sólo permite depurar la rama de versión 5.2 y la comercial la versión 5.3. La aplicación es bastante cara y parece que no tiene mucha actividad y estar sólo integrada con el IDE <a title="NuSphere PhpED" href="http://www.nusphere.com/products/phped.htm" target="_blank">NuSphere PhpED</a>.</li><li>El <a title="Depurador avanzado de PHP - APD - Advanced PHP Debugger" href="http://es.php.net/manual/es/book.apd.php" target="_blank">Depurador Avanzado de PHP</a> (APD, del inglés &#8220;<em>Advanced PHP Debugger</em>&#8220;) es un proyecto PEAR de PHP escrito en C por George Schlossnagle and Daniel Cowgill. Es cargado como una <strong>extensión en el motor Zend</strong> y funciona enlazando e interceptando las llamadas a funciones en el núcleo de Zend. Esto permite la medición del tiempo de ejecución de una función, la vuelta atrás de pilas, etc. La documentación es mínima y los informes de depurado junto con funcionalidades son algo reducidas, por lo que en la práctica no es la opción más utilizada.</li><li><a title="Xdebug for debuggind and profiling" href="http://xdebug.org/" target="_blank">Xdebug</a> es el depurador y perfilador por excelencia de PHP escrito por <a href="http://www.derickrethans.nl/" rel="nofollow">Derick Rethans</a>. Tiene una gran variedad de <a title="XDebug listado de configuraciones" href="http://xdebug.org/docs/all_settings" target="_blank">parámetros de configuración</a>, depuración remota, <strong>integración</strong> con muchos IDEs (Eclipse, Netbeans, etc), reportes coloreados, niveles máximos de anidación para el depurado, accionadores (triggers) para el perfilador, un <a title="Functions on Xdebug" href="http://xdebug.org/docs/all_functions" target="_blank">conjunto de funciones</a> (para puntos de ruptura, analisis de tiempos, etiquetado de código, etc), reemplazo de var_dump por <a title="Display functions on Xdebug" href="http://xdebug.org/docs/display" target="_blank">funciones de visualización</a>, <a title="Stack trace on Xdebug" href="http://xdebug.org/docs/stack_trace" target="_blank">trazas de la pila de ejecución</a>,  <a title="Function traces on Xdebug" href="http://xdebug.org/docs/execution_trace" target="_blank">trazas de funciones</a>, <a title="Code coverage on Xdebug" href="http://xdebug.org/docs/code_coverage" target="_blank">análisis de cobertura de código</a>,   etc.</li></ul><h3><span style="color: #993300;">Instalación y configuración de Xdebug</span></h3><p>Puesto que Xdebug ofrece las mejores características y facilidades, es la <strong>opción preferida</strong>, ademas la instalación y configuración en Ubuntu 11.10 es bastante sencilla.</p><p>Se pueden <a title="Github de Xdebug" href="https://github.com/derickr/xdebug" target="_blank">bajar los f uentes</a> y compilarlos, pero resulta más cómodo bajar del repositorio PEAR la aplicación e instalarla.</p><p>Para instalar el <strong>paquete PEAR</strong>, debemos tener previamente PEAR instalado:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code29'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114329"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code29"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php-pear php5-dev</pre></td></tr></table></div><p>Despues, instalamos Xdebug a través de PECL</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code30'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114330"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code30"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> pecl <span style="color: #c20cb9; font-weight: bold;">install</span> xdebug</pre></td></tr></table></div><p>Una vez finalizada la instalación, podemos encontrar la <strong>biblioteca compartida</strong> compilada en <tt>/usr/lib/php5/20090626+lfs/xdebug.so</tt></p><p>Pasamos a configurar el <tt>php.ini</tt> para que cargue Xdebug. Por defecto Ubuntu 11.10 tiene varios <tt>php.ini</tt>, como son <tt>/etc/php5/cli/php.ini</tt> y <tt>/etc/php5/apache2/php.ini</tt>. Este último es que se utiliza para la <strong>configuración global</strong>.</p><p>Pasamos a modo root:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code31'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114331"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code31"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">su</span> -</pre></td></tr></table></div><p>Añadimos Xdebug al <tt>php.ini</tt> cargándolo como extensión zend y con el path completo, en nuestro caso el path es <tt>/usr/lib/php5/20090626+lfs/xdebug.so</tt></p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code32'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114332"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code32"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo 'zend_extension = &quot;/usr/lib/php5/20090626+lfs/xdebug.so&quot;' &gt;&gt; /etc/php5/apache2/php.ini</span></pre></td></tr></table></div><p>Después lo cargamos como <strong>extensión PHP</strong>:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code33'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114333"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code33"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo &quot;extension=xdebug.so&quot; &gt;&gt; /etc/php5/apache2/php.ini</span></pre></td></tr></table></div><p>Para comprobar que ha sido cargado, podemos mirar los <strong>módulos cargados</strong> de PHP:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code34'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114334"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1143code34"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># php -m | grep Xdebug</span>
Xdebug</pre></td></tr></table></div><p>O bien en la <strong>información general</strong>:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code35'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114335"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1143code35"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># php -i | grep Xdebug</span>
with Xdebug v2.1.2, Copyright <span style="color: #7a0874; font-weight: bold;">&#40;</span>c<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000;">2002</span>-<span style="color: #000000;">2011</span>, by Derick Rethans</pre></td></tr></table></div><p>Si filtramos en minúsculas para la información general, podemos ver todas las opción de configuración:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code36'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114336"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
</pre></td><td class="code" id="p1143code36"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># php -i | grep xdebug</span>
xdebug
xdebug support =<span style="color: #000000; font-weight: bold;">&gt;</span> enabled
xdebug.auto_trace =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.collect_assignments =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.collect_includes =<span style="color: #000000; font-weight: bold;">&gt;</span> On =<span style="color: #000000; font-weight: bold;">&gt;</span> On
xdebug.collect_params =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">0</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">0</span>
xdebug.collect_return =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.collect_vars =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.default_enable =<span style="color: #000000; font-weight: bold;">&gt;</span> On =<span style="color: #000000; font-weight: bold;">&gt;</span> On
xdebug.dump.COOKIE =<span style="color: #000000; font-weight: bold;">&gt;</span> no value =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.dump.ENV =<span style="color: #000000; font-weight: bold;">&gt;</span> no value =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.dump.FILES =<span style="color: #000000; font-weight: bold;">&gt;</span> no value =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.dump.GET =<span style="color: #000000; font-weight: bold;">&gt;</span> no value =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.dump.POST =<span style="color: #000000; font-weight: bold;">&gt;</span> no value =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.dump.REQUEST =<span style="color: #000000; font-weight: bold;">&gt;</span> no value =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.dump.SERVER =<span style="color: #000000; font-weight: bold;">&gt;</span> no value =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.dump.SESSION =<span style="color: #000000; font-weight: bold;">&gt;</span> no value =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.dump_globals =<span style="color: #000000; font-weight: bold;">&gt;</span> On =<span style="color: #000000; font-weight: bold;">&gt;</span> On
xdebug.dump_once =<span style="color: #000000; font-weight: bold;">&gt;</span> On =<span style="color: #000000; font-weight: bold;">&gt;</span> On
xdebug.dump_undefined =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.extended_info =<span style="color: #000000; font-weight: bold;">&gt;</span> On =<span style="color: #000000; font-weight: bold;">&gt;</span> On
xdebug.file_link_format =<span style="color: #000000; font-weight: bold;">&gt;</span> no value =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.idekey =<span style="color: #000000; font-weight: bold;">&gt;</span> root =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.manual_url =<span style="color: #000000; font-weight: bold;">&gt;</span> http:<span style="color: #000000; font-weight: bold;">//</span>www.php.net =<span style="color: #000000; font-weight: bold;">&gt;</span> http:<span style="color: #000000; font-weight: bold;">//</span>www.php.net
xdebug.max_nesting_level =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">100</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">100</span>
xdebug.overload_var_dump =<span style="color: #000000; font-weight: bold;">&gt;</span> On =<span style="color: #000000; font-weight: bold;">&gt;</span> On
xdebug.profiler_aggregate =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.profiler_append =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.profiler_enable =<span style="color: #000000; font-weight: bold;">&gt;</span> On =<span style="color: #000000; font-weight: bold;">&gt;</span> On
xdebug.profiler_enable_trigger =<span style="color: #000000; font-weight: bold;">&gt;</span> On =<span style="color: #000000; font-weight: bold;">&gt;</span> On
xdebug.profiler_output_dir =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>webgrind<span style="color: #000000; font-weight: bold;">/</span>tmp =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>webgrind<span style="color: #000000; font-weight: bold;">/</span>tmp
xdebug.profiler_output_name =<span style="color: #000000; font-weight: bold;">&gt;</span> cachegrind.out.<span style="color: #000000; font-weight: bold;">%</span>t.<span style="color: #000000; font-weight: bold;">%</span>p =<span style="color: #000000; font-weight: bold;">&gt;</span> cachegrind.out.<span style="color: #000000; font-weight: bold;">%</span>t.<span style="color: #000000; font-weight: bold;">%</span>p
xdebug.remote_autostart =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.remote_connect_back =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.remote_cookie_expire_time =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">3600</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">3600</span>
xdebug.remote_enable =<span style="color: #000000; font-weight: bold;">&gt;</span> On =<span style="color: #000000; font-weight: bold;">&gt;</span> On
xdebug.remote_handler =<span style="color: #000000; font-weight: bold;">&gt;</span> dbgp =<span style="color: #000000; font-weight: bold;">&gt;</span> dbgp
xdebug.remote_host =<span style="color: #000000; font-weight: bold;">&gt;</span> 127.0.0.1 =<span style="color: #000000; font-weight: bold;">&gt;</span> 127.0.0.1
xdebug.remote_log =<span style="color: #000000; font-weight: bold;">&gt;</span> no value =<span style="color: #000000; font-weight: bold;">&gt;</span> no value
xdebug.remote_mode =<span style="color: #000000; font-weight: bold;">&gt;</span> req =<span style="color: #000000; font-weight: bold;">&gt;</span> req
xdebug.remote_port =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">9000</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">9000</span>
xdebug.scream =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.show_exception_trace =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.show_local_vars =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.show_mem_delta =<span style="color: #000000; font-weight: bold;">&gt;</span> Off =<span style="color: #000000; font-weight: bold;">&gt;</span> Off
xdebug.trace_format =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">0</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">0</span>
xdebug.trace_options =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">0</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">0</span>
xdebug.trace_output_dir =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>tmp =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>tmp
xdebug.trace_output_name =<span style="color: #000000; font-weight: bold;">&gt;</span> trace.<span style="color: #000000; font-weight: bold;">%</span>c =<span style="color: #000000; font-weight: bold;">&gt;</span> trace.<span style="color: #000000; font-weight: bold;">%</span>c
xdebug.var_display_max_children =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">128</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">128</span>
xdebug.var_display_max_data =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">512</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">512</span>
xdebug.var_display_max_depth =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">3</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">3</span></pre></td></tr></table></div><p><strong>Activando configuraciones en Xdebug</strong></p><p>Para generar información de depuración, debemos activar como mínimo las siguientes configuraciones de la familia <tt>xdebug.profiler_*</tt>:</p><ul><li>Primero escribimos la <strong>cabecera de configuración</strong>para xdebug:<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code37'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114337"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code37"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo &quot;[xdebug]&quot; &gt;&gt; /etc/php5/cli/php.ini</span></pre></td></tr></table></div></li><li><a title="Xdebug profiler_enable opción" href="http://xdebug.org/docs/all_settings#profiler_enable" target="_blank">xdebug.profiler_enable</a> activa el perfilador de xdebug para que genere archivos de perfilado en un <a title="Directorio de salida de Xdebug" href="http://xdebug.org/docs/all_settings#profiler_output_dir" target="_blank">directorio de salida</a>. Estos archivos puedes leerse por programas visualizadores gráficos de llamadas como <a title="KCacheGrind" href="http://kcachegrind.sourceforge.net/html/Home.html" target="_blank">KCacheGrind</a> o <a title="Webgrind" href="http://code.google.com/p/webgrind/" target="_blank">Webgrind</a>que será explicado más adelante. Esta configuración también puede habilitarse mediante la función ini_set() por lo que resulta interesante para activar selectivamente el perfilador en nuestras aplicaciones. Se activa con:<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code38'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114338"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code38"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo &quot;xdebug.profiler_enable = 1&quot; &gt;&gt; /etc/php5/cli/php.ini</span></pre></td></tr></table></div></li><li><a title="xdebug.profiler_enable_trigger en xdebug" href="http://xdebug.org/docs/all_settings#profiler_enable_trigger" target="_blank">xdebug.profiler_enable_trigger</a>permite generar archivos de perfilador usando el parámetro XDEBUG_PROFILE por peticiones GET/POST o establecer una cookie. Lo activamos con:<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code39'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114339"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code39"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo &quot;xdebug.profiler_enable_trigger = 1&quot; &gt;&gt; /etc/php5/cli/php.ini</span></pre></td></tr></table></div></li><li><a title="xdebug.profiler_output_dir en xdebug" href="http://xdebug.org/docs/all_settings#profiler_output_dir" target="_blank">xdebug.profiler_output_dir</a> el valor por defecto donde el perfilador escribira su salida. Debe tener permisos de escritura para PHP y no puede ser establecida con ini_set(). Para propósitos posteriores, la estableceremos como:<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code40'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114340"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code40"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo 'xdebug.profiler_output_dir = &quot;/var/www/webgrind/tmp&quot;' &gt;&gt; /etc/php5/cli/php.ini</span></pre></td></tr></table></div></li><li><a title="http://xdebug.org/docs/all_settings#profiler_output_name" href="http://xdebug.org/docs/all_settings#profiler_output_name" target="_blank">xdebug.profiler_output_name</a> determina el nombre del archivo usado para las trazas de depuración. La configuración especifica el formato del nombre con los especificares de formato que son muy similares a sprintf() y strtime(). Por defecto es cachegrind.out.%p. Existe un un <a title="Listado de especificadores para archivos de nombre de depuración de Xdebug" href="http://xdebug.org/docs/all_settings#trace_output_name" target="_blank">listado completo de los especificadores</a>documentados. Lo configuramos con:<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code41'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114341"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code41"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo &quot;xdebug.profiler_output_name = cachegrind.out.%t.%p&quot; &gt;&gt; /etc/php5/cli/php.ini</span></pre></td></tr></table></div></li></ul><p>La configuración mínima recomendada que resultaría al final del <tt>php.ini</tt> quedaría como:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code42'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114342"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p1143code42"><pre class="bash" style="font-family:monospace;">zend_extension = <span style="color: #ff0000;">&quot;/usr/lib/php5/20090626+lfs/xdebug.so
extension=xdebug.so
&nbsp;
[xdebug]
xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_dir = &quot;</span><span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>webgrind<span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #ff0000;">&quot;
xdebug.profiler_output_name = cachegrind.out.%t.%p</span></pre></td></tr></table></div><p>Si queremos activar ademas la depuración remota en un puerto y máquina (o bien en la misma), usaremos la familia de configuraciones <tt>xdebug.remote_*</tt>. Las mínimas recomendadas son:</p><ul><li><a title="xdebug.remote_enable config option" href="http://xdebug.org/docs/all_settings#remote_enable" target="_blank">xdebug.remote_enable</a> si esta activado, Xdebug tratará de contactar con el cliente que este escuchando en el puerto y host configurad. Si la conexión no puede ser establecidad, el script continuará ejecutado como si estuviera desactivado. Lo activamos con:<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code43'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114343"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code43"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo &quot;xdebug.&lt;a title=&quot;xdebug.remote_enable config option&quot; href=&quot;http://xdebug.org/docs/all_settings#remote_enable&quot; target=&quot;_blank&quot;&gt;remote_enable&lt;/a&gt; = 1&quot; &gt;&gt; /etc/php5/cli/php.ini</span></pre></td></tr></table></div></li><li><a title="xdebug.remote_host config option" href="http://xdebug.org/docs/all_settings#remote_host" target="_blank">xdebug.remote_host</a> selecciona el host donde el cliente de depuración se ejecutará. Puede utilizar un nombre de host o una dirección IP. Lo configuramos con:<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code44'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114344"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code44"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo &quot;xdebug.remote_host=127.0.0.1&quot; &gt;&gt; /etc/php5/cli/php.ini</span></pre></td></tr></table></div></li><li><a title="xdebug.remote_port config option" href="http://xdebug.org/docs/all_settings#remote_port" target="_blank">xdebug.remote_port</a> el puerto al que Xdebug tratara de conectar en el host remoto. Por defecto es el puerto 9000, para el cliente y cliente de debug integrado. Lo configuramos con:<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code45'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114345"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code45"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo &quot;xdebug.remote_port=9000&quot; &gt;&gt; /etc/php5/cli/php.ini</span></pre></td></tr></table></div></li><li><a title="xdebug.remote_handler config option" href="http://xdebug.org/docs/all_settings#remote_handler" target="_blank">xdebug.remote_handler</a> puede ser &#8216;php3&#8242; que selecciona el <a title="Depurador antiguo para PHP3" href="http://www.php.net/manual/en/debugger.php" target="_blank">depurador antiguo para PHP3</a>, tambiíen puede ser &#8217;gdb&#8217; que habilita el depurador GDB o bien el protocolo de depuración con &#8216;dbgp&#8217;. El <a title="Protocolo de depuración de Xdebug" href="http://xdebug.org/docs-dbgp.php" target="_blank">protocolo de depuración</a>esta por lo general más soportado por los clientes. Lo configuramos con:<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code46'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114346"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code46"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo &quot;xdebug.remote_handler=dbgp&quot; &gt;&gt; /etc/php5/cli/php.ini</span></pre></td></tr></table></div></li></ul><p>Puedes ver más información en la <a title="Introducción al depurado remoto con Xdebug" href="http://xdebug.org/docs/remote" target="_blank">introducción al depurado remoto</a> de Xdebug.</p><p>Por lo que el resultado final sería:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code47'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114347"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1143code47"><pre class="bash" style="font-family:monospace;">zend_extension = <span style="color: #ff0000;">&quot;/usr/lib/php5/20090626+lfs/xdebug.so
extension=xdebug.so
&nbsp;
[xdebug]
xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_dir = &quot;</span><span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>webgrind<span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #ff0000;">&quot;
xdebug.profiler_output_name = cachegrind.out.%t.%p
xdebug.remote_enable=true
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp</span></pre></td></tr></table></div><h3><span style="color: #993300;">Instalando KCacheGrind</span></h3><p><a title="KCacheGrind - Página de inicio" href="http://kcachegrind.sourceforge.net/html/Home.html" target="_blank">KCacheGrind</a> es un programa de escritorio (en especial para diseñado para KDE, pero compatible para GNOME) escrito para <strong>visualizar los archivos de depuración</strong> generados por xdebug. Es un frontend de <a title="Manual de Callgrind" href="http://valgrind.org/docs/manual/cl-manual.html" target="_blank">Callgrind</a>, que a su vez usa en tiempo de ejecución al framework de <a title="Valgrind profiler" href="http://kcachegrind.sourceforge.net/html/Valgrind.html" target="_blank">Valgrind</a> para <strong>simulación de caches</strong> y generación de las llamadas gráficas. Un aspecto a recalcar es que incluso las bibliotecas compartidas que son abiertas dinamicamente son perfiladas. Podemos abrir con el archivos de depuración con <a title="Formato Callgrind - Archivos de depuración" href="http://kcachegrind.sourceforge.net/html/CallgrindFormat.html" target="_blank">formato Callgrind</a> generados con xdebug de forma bastante rápida.</p><p>Para instalarlo simplemente:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code48'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114348"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code48"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> kcachegrind</pre></td></tr></table></div><p>Por ejemplo podemos crear un archivo con la información de PHP para ver un <strong>ejemplo sencillo</strong> de depuración y ejecutarlo para que se genere un archivo cachegrind.out, que podamos abrir con KCacheGrind:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code49'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114349"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code49"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># echo &quot;&amp;lt;?php phpinfo(); ?&gt;&quot; &gt;&gt; /var/www/phpinfo.php</span></pre></td></tr></table></div><p>Como resultado, obtendríamos un grafo y los<strong> tiempos de ejecución</strong> globales y relativos implicados:</p><div class="mceTemp mceIEcenter"><dl id="attachment_1144" class="wp-caption aligncenter" style="width: 570px;"><dt class="wp-caption-dt"><a href="http://shakaran.net/blog/wp-content/uploads/2012/01/kcachegrind.png"><img class=" wp-image-1144 " title="KCacheGrind - Ejemplo sencillo con phpinfo()" src="http://shakaran.net/blog/wp-content/uploads/2012/01/kcachegrind.png" alt="KCacheGrind - Ejemplo sencillo con phpinfo()" width="570" /></a>Ejemplo de depuración de phpinfo() con KCacheGrind</dt></dl></div><p>Es una aplicación<strong> bastante notabl</strong>e, pero en su lugar es más recomendable usar Webgrind como frontend web, que veremos a continuación.</p><h3><span style="color: #993300;">Instalar webgrind</span></h3><div class="mceTemp mceIEcenter"><dl id="attachment_1158" class="wp-caption aligncenter" style="margin:auto;width: 162px;"><dt class="wp-caption-dt"><a href="http://shakaran.net/blog/wp-content/uploads/2012/01/webgrind_logo.png"><img class="size-full wp-image-1158" title="Webgrind 1.0 logo" src="http://shakaran.net/blog/wp-content/uploads/2012/01/webgrind_logo.png" alt="Webgrind 1.0 logo" width="152" height="60" /></a></dt></dl></div><p>Webgrind es un perfilador gráfico de PHP via web escrito en PHP por <a href="http://jokke.dk/" rel="nofollow">Joakim Nygård</a> y <a href="http://oettinger.dk/" rel="nofollow">Jacob Oettinger</a>. Tiene como dependencia Xdebug ya que es en realidad un wrapper web no completo de las funciones de KCacheGrind como reemplazo de <a title="Xdebug profiling web frontend" href="https://wiki.php.net/gsoc/2008#xdebug_profiling_web_frontend" target="_blank">frontend web de xdebug</a> (existe incluso una proposición de Google Summer of Code <a title="Google Summer of code xdebug web frontend" href="http://code.google.com/soc/2008/php/appinfo.html?csaid=F74E5E31D92F95D0" target="_blank">aceptada por Chung-Yang Lee</a>).</p><p>Su apareciencia es simple y agradable para <strong>depurar aplicaciones</strong> PHP. Es multiplataforma (al ser vía web) y permite seguimiento de los tiempos empleados por cada llamada de función, por coste de ellas misma o <strong>coste inclusivo</strong> (el coste inclusivo es el tiempo dentro de la función mas llamadas internas de esa función a otras).</p><p>También permite ver tiempo de <strong>llamadas internas</strong> y llamadas de usuario diciendo la llamada por la que fue invocada previamente.</p><p>Descargamos la aplicación de github, ya que en el momento de escribir este artículo están haciendo una <strong>migración de google code</strong> a github (también puedes hacer un checkout del repo, aunque puede ser inestable):</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code50'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114350"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code50"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">wget</span> https:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>downloads<span style="color: #000000; font-weight: bold;">/</span>jokkedk<span style="color: #000000; font-weight: bold;">/</span>webgrind<span style="color: #000000; font-weight: bold;">/</span>webgrind-release-<span style="color: #000000;">1.0</span>.zip</pre></td></tr></table></div><p>Descomprimos:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code51'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114351"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code51"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">unzip</span> webgrind-release-<span style="color: #000000;">1.0</span>.zip</pre></td></tr></table></div><p>En ubuntu el <em>DocumentRoot</em> de Apache esta establecido <strong>por defecto</strong> en <em>/var/www</em> según <em>/etc/apache2/sites-available/default</em></p><p>Luego, copiaremos los fuentes de webgrind y crearemos los <strong>archivos temporales</strong> que configuramos como directorio de salida en el perfilador de Xdebug:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code52'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114352"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1143code52"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mv</span> webgrind <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>webgrind<span style="color: #000000; font-weight: bold;">/</span>tmp
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #000000;">777</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>webgrind<span style="color: #000000; font-weight: bold;">/</span>tmp</pre></td></tr></table></div><p>Editamos el <strong>archivo de configuración</strong> e introducimos la ruta de directorio de salida de xdebug:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code53'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114353"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code53"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">vi</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>webgrind<span style="color: #000000; font-weight: bold;">/</span>config.php</pre></td></tr></table></div><p>Busca las variables $storageDir y $profilerDir y escribe:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code54'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114354"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1143code54"><pre class="bash" style="font-family:monospace;">static <span style="color: #007800;">$storageDir</span> = <span style="color: #ff0000;">'/var/www/webgrind/tmp'</span>;
static <span style="color: #007800;">$profilerDir</span> = <span style="color: #ff0000;">'/var/www/webgrind/tmp'</span>;</pre></td></tr></table></div><p>Nos aseguramos de todos los archivos tienen los <strong>permisos de grupo</strong> correctos de Apache:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code55'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114355"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code55"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chown</span> <span style="color: #660033;">-R</span> www-data.www-data <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>webgrind<span style="color: #000000; font-weight: bold;">/</span></pre></td></tr></table></div><p>Si además queremos que no se creen archivos de depuración para el propio webgrind, creamos un <strong>archivo .htaccess</strong> en el directorio de webgrind desactivandolo:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1143code56'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p114356"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1143code56"><pre class="bash" style="font-family:monospace;">php_flag xdebug.profiler_enable <span style="color: #000000;">0</span></pre></td></tr></table></div><p>Para entrar a la interfaz web de Webgrind, simplemente escribe en tu navegador <a href="http://localhost/webgrind/" title="Webgrind">http://localhost/webgrind/</a> y aparecerá disponible un <strong>listado de archivos</strong> cachegrind* donde podemos ver la traza y tiempos de depuración del perfilador:</p><div class="mceTemp mceIEcenter"><dl id="attachment_1159" class="wp-caption aligncenter" style="width: 580px;"><dt class="wp-caption-dt"><a href="http://shakaran.net/blog/wp-content/uploads/2012/01/webgrind_trace.png"><img class=" wp-image-1159 " title="Traza de depuración de phpinfo() con Webgrind" src="http://shakaran.net/blog/wp-content/uploads/2012/01/webgrind_trace-1024x231.png" alt="Traza de depuración de phpinfo() con Webgrind" width="570" /></a><strong>Traza de depuración de phpinfo() con Webgrind</strong></dt></dl></div> <br /><div><img src="http://shakaran.net/blog/wp-content/plugins/gd-star-rating/gfx.php?value=0.0" /></div><div>Rating: 0.0/<strong>10</strong> (0 votes cast)</div><br />]]></content:encoded> <wfw:commentRss>http://shakaran.net/blog/2012/01/depurar-y-perfilar-funciones-php-graficamente-con-xdebug-kcachegrind-y-webgrind-en-ubuntu-11-10/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Apache error 500: eAccelerator: shmmax should be at least 2MB</title><link>http://shakaran.net/blog/2011/03/apache-error-500-eaccelerator-shmmax-should-be-at-least-2mb/</link> <comments>http://shakaran.net/blog/2011/03/apache-error-500-eaccelerator-shmmax-should-be-at-least-2mb/#comments</comments> <pubDate>Sat, 12 Mar 2011 09:04:04 +0000</pubDate> <dc:creator>shakaran</dc:creator> <category><![CDATA[Apache]]></category> <category><![CDATA[Cpanel]]></category> <category><![CDATA[Open Source]]></category> <category><![CDATA[OpenVZ]]></category> <category><![CDATA[Servidores]]></category> <category><![CDATA[500]]></category> <category><![CDATA[eaccelerator]]></category> <category><![CDATA[error]]></category> <category><![CDATA[error 500]]></category> <category><![CDATA[failcnt]]></category> <category><![CDATA[kernel 2.6]]></category> <category><![CDATA[memoria]]></category> <category><![CDATA[memoria compartida]]></category> <category><![CDATA[nano]]></category> <category><![CDATA[openvz]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[php.ini]]></category> <category><![CDATA[problema]]></category> <category><![CDATA[quijost]]></category> <category><![CDATA[sed]]></category> <category><![CDATA[shmmax]]></category> <category><![CDATA[shm_max]]></category> <category><![CDATA[shm_size]]></category> <category><![CDATA[solución]]></category> <category><![CDATA[sysctl.conf]]></category> <category><![CDATA[vps]]></category><guid isPermaLink="false">http://shakaran.net/blog/?p=1068</guid> <description><![CDATA[Este molesto error aparece en algunos servidores que puedan tener instalados cPanel con eAccelerator. Puede ser que alguna actualización de cPanel cambie valores por defecto del php.ini de PHP y en mi opinión una de las posibles y frecuentes causas de este fallo. Para solucionarlo, encuentra el php.ini de tu sistema cPanel, normalmente ubicado en [...]<br /><div><img src="http://shakaran.net/blog/wp-content/plugins/gd-star-rating/gfx.php?value=0.0" /></div><div>Rating: 0.0/<strong>10</strong> (0 votes cast)</div><br />]]></description> <content:encoded><![CDATA[<div class="wpbuzzer_button" style="float: right"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="normal-button" data-url="http://shakaran.net/blog/2011/03/apache-error-500-eaccelerator-shmmax-should-be-at-least-2mb/" data-imageurl=""></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div><p style="text-align: justify;">Este molesto error aparece en algunos servidores que puedan tener instalados cPanel con <a title="eAccelerator: a free open-source PHP accelerator &amp; optimizer" href="eaccelerator.net" target="_blank">eAccelerator</a>. Puede ser que <strong>alguna actualización</strong> de cPanel cambie valores por defecto del php.ini de PHP y en mi opinión una de las posibles y frecuentes causas de este fallo.</p><p style="text-align: justify;">Para solucionarlo, encuentra el php.ini de tu sistema cPanel, normalmente ubicado en <tt>/usr/local/lib/php.ini</tt></p><p style="text-align: justify;">Se trata de<strong> buscar la variable</strong> &#8220;<tt>eaccelerator.shm_max</tt>&#8221; y ponerle un valor mayor o igual a 2 MB. Puedes hacer un filtrado de la cadena para asegurarte que la tienes y con que valor con:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1068code64'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p106864"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1068code64"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>php.ini <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> eaccelerator.shm_max</pre></td></tr></table></div><p style="text-align: justify;">Por ejemplo puede salirte algo como:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1068code65'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p106865"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1068code65"><pre class="bash" style="font-family:monospace;">eaccelerator.shm_max=<span style="color: #ff0000;">&quot;0&quot;</span></pre></td></tr></table></div><p style="text-align: justify;">Es decir, que usa 0 o el valor por defecto.</p><p style="text-align: justify;">Luego si tienes dicha variable puedes cambiarlo con este <strong>comando de sed</strong> (stream editor) rápidamente:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1068code66'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p106866"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1068code66"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-i</span> <span style="color: #ff0000;">'s/eaccelerator.shm_max=\&quot;0\&quot;/eaccelerator.shm_max=\&quot;2M\&quot;/g'</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>php.ini</pre></td></tr></table></div><p style="text-align: justify;">O bien editar por ejemplo con el editor nano:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1068code67'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p106867"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1068code67"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">nano</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>php.ini</pre></td></tr></table></div><p style="text-align: justify;">Y poner:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1068code68'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p106868"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1068code68"><pre class="bash" style="font-family:monospace;">eaccelerator.shm_max=<span style="color: #ff0000;">&quot;2&quot;</span></pre></td></tr></table></div><p style="text-align: justify;">También puedes jugar con la variable <tt>eaccelerator.shm_size</tt>.</p><p style="text-align: justify;">Si te <strong>sigue dando problemas</strong> eAccelerator otra solución más drástica es desactivarlo, es decir, poner un &#8220;;&#8221; delante del <tt>extension="eaccelerator.so"</tt> (puede variar la ruta).</p><p style="text-align: justify;">Debes tener en cuenta que el valor por defecto del <strong>tamaño de memoria compartida</strong> para el <strong>kernel 2.6 es de 32 mb</strong>.</p><p style="text-align: justify;">Puedes cambiar este tamaño al valor deseado en <tt>/proc/sys/kernel/shmmax</tt>.</p><p style="text-align: justify;">Por ejemplo con:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1068code69'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p106869"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1068code69"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> VALOR <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>proc<span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>kernel<span style="color: #000000; font-weight: bold;">/</span>shmmax</pre></td></tr></table></div><p style="text-align: justify;">O añadir la linea <tt>kernel.shmmax=VALOR</tt> a <tt>/etc/sysctl.conf</tt> así no tendrás que establecerlo manualmente cada vez que reinicies.</p><p style="text-align: justify;">Por otro lado, si estas usando un <a title="Que es un VPS. Quijost VPS servicio profesional VPS" href="http://quijost.com/vps/" target="_blank">VPS</a>, asegúrate de que la memoria compartida y los buffers para sockets en la configuración del VPS son suficientes.</p><p style="text-align: justify;">Para <a title="OpenVZ una tecnología de virtualización en el nivel de sistema operativo para Linux" href="http://openvz.org" target="_blank">OpenVZ</a> o tipos similares, puede comprobarlo con:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p1068code70'); return false;">Ver código</a> BASH</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p106870"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1068code70"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>proc<span style="color: #000000; font-weight: bold;">/</span>user_beancounter</pre></td></tr></table></div><p style="text-align: justify;">Para un caso normal, el fail count (<tt>failcnt</tt>) debería ser cero. Si necesitaras más, deberías preguntar a tu proveedor VPS para agrandar el límite hasta que eAccelerator no fallara.</p><p style="text-align: justify;"><span style="text-decoration: underline;"><strong>Fuentes</strong></span></p><p style="text-align: justify;"><a title="Documentación eAccelerator shm_max" href="http://eaccelerator.net/wiki/Settings#eaccelerator.shm_max" target="_blank">Documentacion eAccelerator: shm_max</a></p><p style="text-align: justify;"><a title="Documentación eAccelerator shm_size" href="http://eaccelerator.net/wiki/Settings#eaccelerator.shm_size" target="_blank">Documentacion eAccelerator: shm_size</a></p><p style="text-align: justify;"><a title="FAQ eAccelerator" href="http://eaccelerator.net/wiki/Faq" target="_blank">FAQ eAccelerator</a></p> <br /><div><img src="http://shakaran.net/blog/wp-content/plugins/gd-star-rating/gfx.php?value=0.0" /></div><div>Rating: 0.0/<strong>10</strong> (0 votes cast)</div><br />]]></content:encoded> <wfw:commentRss>http://shakaran.net/blog/2011/03/apache-error-500-eaccelerator-shmmax-should-be-at-least-2mb/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Apache checker: un script comprobador de Apache en bash</title><link>http://shakaran.net/blog/2010/02/apache-checker-un-script-comprobador-de-apache-en-bash/</link> <comments>http://shakaran.net/blog/2010/02/apache-checker-un-script-comprobador-de-apache-en-bash/#comments</comments> <pubDate>Fri, 12 Feb 2010 15:13:12 +0000</pubDate> <dc:creator>shakaran</dc:creator> <category><![CDATA[Apache]]></category> <category><![CDATA[Cpanel]]></category> <category><![CDATA[Open Source]]></category> <category><![CDATA[Servidores]]></category> <category><![CDATA[administracion]]></category> <category><![CDATA[bc]]></category> <category><![CDATA[centos]]></category> <category><![CDATA[checker]]></category> <category><![CDATA[consumo]]></category> <category><![CDATA[crontab]]></category> <category><![CDATA[eficiencia]]></category> <category><![CDATA[gestion]]></category> <category><![CDATA[limite]]></category> <category><![CDATA[memoria]]></category> <category><![CDATA[mutt]]></category> <category><![CDATA[optimizar]]></category> <category><![CDATA[quijost]]></category> <category><![CDATA[servidor]]></category><guid isPermaLink="false">http://shakaran.net/blog/?p=867</guid> <description><![CDATA[La gestión de servidores es un tema apasionante, pero exige mucho control sobre los sistemas a administrar. Personalmente en la empresa de hospedaje que administro llamada Quijost necesitamos un riguroso control de los servicios para detectar cualquier mal funcionamiento o sobrecarga y obtener una solución de forma casi inmediata. Uno de los principales problemas es [...]<br /><div><img src="http://shakaran.net/blog/wp-content/plugins/gd-star-rating/gfx.php?value=10.0" /></div><div>Rating: 10.0/<strong>10</strong> (2 votes cast)</div><br />]]></description> <content:encoded><![CDATA[<div class="wpbuzzer_button" style="float: right"><a title="Post on Google Buzz" class="google-buzz-button" href="http://www.google.com/buzz/post" data-button-style="normal-button" data-url="http://shakaran.net/blog/2010/02/apache-checker-un-script-comprobador-de-apache-en-bash/" data-imageurl=""></a><script type="text/javascript" src="http://www.google.com/buzz/api/button.js"></script></div><div class="mceTemp mceIEcenter"><dl id="attachment_868" class="wp-caption aligncenter" style="width: 210px;margin:auto"><dt class="wp-caption-dt"><a href="http://shakaran.net/blog/wp-content/uploads/2010/02/apache-checker-logo.png"><img class="size-full wp-image-868" title="apache-checker-logo" src="http://shakaran.net/blog/wp-content/uploads/2010/02/apache-checker-logo.png" alt="apache-checker-logo" width="200" height="150" /></a></dt></dl></div><p>La<strong> gestión de servidores </strong>es un tema apasionante, pero exige mucho control sobre los sistemas a administrar. Personalmente en la empresa de hospedaje que administro llamada <a title="Quijost: servicio de hospedaje manchego" href="http://www.quijost.com" target="_blank">Quijost</a> necesitamos un <strong>riguroso control</strong> de los servicios para detectar cualquier mal funcionamiento o sobrecarga y obtener una solución de forma casi inmediata.</p><p>Uno de los principales problemas es la gestión de <strong>recursos de memoria</strong> en servidores con Apache y que por lo general suelen usar <a title="Cpanel" href="http://www.cpanel.net" target="_blank">Cpanel</a>.</p><p>Cpanel es un buen sistema de <strong>panel de administración</strong>, pero es muy exigente en recursos y a veces consume demasiada memoria llegando a colapsar sus propios procesos e invocando a daemons encargados de reiniciarlo.</p><p>El problema viene cuando Cpanel además provoca un <strong>mal funcionamiento</strong> de Apache o bien tenemos un exceso de consumo en servidor por algún efecto <a title="Efecto barrapunto" href="http://es.wikipedia.org/wiki/Barrapunto#Efecto_Barrapunto" target="_blank">Barrapunto</a>, <a title="Efecto menéame" href="http://es.wikipedia.org/wiki/Men%C3%A9ame#Efecto_Men.C3.A9ame" target="_blank">Menéame</a>, <a title="Efecto Digg o Slashdot" href="http://en.wikipedia.org/wiki/Slashdot_effect">Digg</a>, etc.</p><p>En esos casos Apache atenderá todas las peticiones posibles dada la memoria de la que dispongamos. Normalmente y como referencia unas <strong>200 peticiones por segundo</strong> con 1 GB de RAM (aunque tened presente que esta cifra puede variar bastante según configuraciones y hardware).</p><p>Cuando el servidor se quede sin memoria, las <strong>peticiones no se atenderán</strong> incluso otros servicios como emails (exim) pueden colapsar. Para evitar estas situaciones, he desarrollado un script que se encarga de <strong>comprobar</strong> periodicamente mediante una tarea cron, los recursos del sistema, la disponibilidad de Apache y la memoria disponible en el servidor, para actuar en consecuencia y reiniciar si es necesario, además de notificar a los administradores y mantener un log.</p><p>El script llamado <em>Apache Checker</em> está escrito en bash y tiene el siguiente aspecto:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left2">Descargar <a href="http://shakaran.net/blog/wp-content/plugins/wp-codebox/wp-codebox.php?p=867&amp;download=apache_checker.sh">apache_checker.sh</a></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p86775"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
</pre></td><td class="code" id="p867code75"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Apache Checker: a script for check resources on apache servers</span>
<span style="color: #666666; font-style: italic;"># Author: Shakaran (http://www.shakaran.net)</span>
<span style="color: #666666; font-style: italic;"># License: GPLv3</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># For CentOs servers require bc and mutt:</span>
<span style="color: #666666; font-style: italic;"># yum install bc</span>
<span style="color: #666666; font-style: italic;"># yum install mutt</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Uses:</span>
<span style="color: #666666; font-style: italic;"># Add this script to a cron's task with crontab -e</span>
<span style="color: #666666; font-style: italic;"># For example: For run the checking every minute</span>
<span style="color: #666666; font-style: italic;"># */1 * * * * /apache_check.sh &amp;&gt; /dev/null </span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Exit immediately if a simple command exits with a non-zero status</span>
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-e</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Number of current apache2 processes.</span>
<span style="color: #007800;">N_CURRENT</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$(ps aux | grep apache2 | wc -l)</span>&quot;</span>
<span style="color: #007800;">N_MIN</span>=<span style="color: #ff0000;">&quot;1&quot;</span>
<span style="color: #007800;">DESTINY_EMAIL</span>=<span style="color: #ff0000;">&quot;your-server-admin-address@domain.com&quot;</span>
<span style="color: #007800;">USER</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">id</span> -un<span style="color: #000000; font-weight: bold;">`</span> <span style="color: #666666; font-style: italic;"># For example: root</span>
<span style="color: #007800;">HOST</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">hostname</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">USERHOST</span>=<span style="color: #007800;">$USER</span><span style="color: #000000; font-weight: bold;">@</span><span style="color: #007800;">$HOST</span>
&nbsp;
<span style="color: #007800;">THRESHOLD</span>=<span style="color: #000000;">90</span> <span style="color: #666666; font-style: italic;"># Max threshold for restart apache</span>
<span style="color: #007800;">TOTAL_MEMORY</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">free</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">&quot;Mem:&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $2}'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">REMAINING_MEMORY</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">free</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">&quot;Mem:&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $4}'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">CURRENT_MEMORY</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;(<span style="color: #007800;">$REMAINING_MEMORY</span>/<span style="color: #007800;">$TOTAL_MEMORY</span>)*100.0&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">bc</span> -l<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #007800;">MAX_NPROCESS_APACHE</span>=<span style="color: #000000;">5</span>
<span style="color: #007800;">NPROCESS_APACHE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">ps</span> fu <span style="color: #007800;">$USERNAME</span>  <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'/processname/ { x++ } END{print x}'</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$N_CURRENT</span>&quot;</span> <span style="color: #660033;">-lt</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$N_MIN</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    apachectl restart
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: The Apache process is not working and it has been restarted.&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: The Apache process is not working and it has been restarted.&quot;</span> \
    <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache_restarter.log
    <span style="color: #007800;">SUBJECT</span>=<span style="color: #ff0000;">&quot;Script Apache checker: start&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: The Apache process is not working and it has been restarted.&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> mutt <span style="color: #660033;">-s</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$SUBJECT</span>&quot;</span> <span style="color: #007800;">$DESTINY_EMAIL</span>
<span style="color: #000000; font-weight: bold;">fi</span> 
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">ps</span> <span style="color: #660033;">-fea</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">&quot;/usr/sbin/apache2&quot;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #007800;">$?</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #000000; font-weight: bold;">then</span>
    apachectl start
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: Apache has stopped and it has been reactivated.&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: Apache has stopped and it has been reactivated.&quot;</span> \
    <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache_restarter.log
    <span style="color: #007800;">SUBJECT</span>=<span style="color: #ff0000;">&quot;Script Apache checker: restart&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: Apache has stopped and it has been reactivated.&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> mutt <span style="color: #007800;">$DESTINY_EMAIL</span>
<span style="color: #660033;">-s</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$SUBJECT</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$CURRENT_MEMORY</span> <span style="color: #660033;">-gt</span> <span style="color: #007800;">$THRESHOLD</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    apachectl restart
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: Restarted apache on <span style="color: #780078;">`date +'%Y-%m-%d %H:%M:%S'`</span>. RAM utilization at
<span style="color: #007800;">${CURRENT_MEMORY}</span>%&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: Restarted apache on <span style="color: #780078;">`date +'%Y-%m-%d %H:%M:%S'`</span>. RAM utilization at
<span style="color: #007800;">${CURRENT_MEMORY}</span>%&quot;</span> \
    <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache_restarter.log
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Restarted apache on <span style="color: #780078;">`date +'%Y-%m-%d %H:%M:%S'`</span>. RAM utilization at
<span style="color: #007800;">${CURRENT_MEMORY}</span>%&quot;</span> \
    <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache_restarter.log
    <span style="color: #007800;">SUBJECT</span>=<span style="color: #ff0000;">&quot;Script Apache checker: restart&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: Restarted apache on <span style="color: #780078;">`date +'%Y-%m-%d %H:%M:%S'`</span>. RAM utilization at
<span style="color: #007800;">${CURRENT_MEMORY}</span>%&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> mutt <span style="color: #007800;">$DESTINY_EMAIL</span> <span style="color: #660033;">-s</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$SUBJECT</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">ps</span> fu <span style="color: #007800;">$USERNAME</span>  <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'/processname/ { x++ } END{print x}'</span><span style="color: #000000; font-weight: bold;">`&gt;</span>
<span style="color: #007800;">$MAX_NPROCESS_APACHE</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: max number of apache process = <span style="color: #007800;">${MAX_NPROCESS_APACHE}</span> <span style="color: #780078;">`date
+'%Y-%m-%d %H:%M:%S'`</span>. RAM utilization at <span style="color: #007800;">${CURRENT_MEMORY}</span>% &quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: max number of apache process = <span style="color: #007800;">${MAX_NPROCESS_APACHE}</span> <span style="color: #780078;">`date
+'%Y-%m-%d %H:%M:%S'`</span>. RAM utilization at <span style="color: #007800;">${CURRENT_MEMORY}</span>% &quot;</span> \
    <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache_restarter.log
    <span style="color: #007800;">SUBJECT</span>=<span style="color: #ff0000;">&quot;Script Apache checker: max number of apache process&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOST</span>: max number of apache process = <span style="color: #007800;">${MAX_NPROCESS_APACHE}</span> <span style="color: #780078;">`date
+'%Y-%m-%d %H:%M:%S'`</span>. RAM utilization at <span style="color: #007800;">${CURRENT_MEMORY}</span>% &quot;</span> <span style="color: #000000; font-weight: bold;">|</span> mutt <span style="color: #007800;">$DESTINY_EMAIL</span>
<span style="color: #660033;">-s</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$SUBJECT</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></td></tr></table></div><p>El script esta basado en bash y ha sido probado en <strong>servidores GNU/Linux CentOs 5.4</strong>, pero debería funcionar en cualquier distribución que soporte bash. Como únicos requisitos necesita tener instalados los programas mutt (para enviar correo) y bc (para calcular datos). En CentOs puedes instalarlos con:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left2">Descargar <a href="http://shakaran.net/blog/wp-content/plugins/wp-codebox/wp-codebox.php?p=867&amp;download=instalar.txt">instalar.txt</a></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p86776"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p867code76"><pre class="shell" style="font-family:monospace;"># yum install bc mutt</pre></td></tr></table></div><p>Además para su instalación necesitas añadir <strong>una tarea cron</strong> que ejecute el script periodicamente, por ejemplo para cada minuto, abre tu editor de cron con:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left2">Descargar <a href="http://shakaran.net/blog/wp-content/plugins/wp-codebox/wp-codebox.php?p=867&amp;download=editar.txt">editar.txt</a></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p86777"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p867code77"><pre class="text" style="font-family:monospace;"># crontab -e</pre></td></tr></table></div><p>Y suponiendo que pones el script en / escribe:</p><div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left2">Descargar <a href="http://shakaran.net/blog/wp-content/plugins/wp-codebox/wp-codebox.php?p=867&amp;download=editar-cron.txt">editar-cron.txt</a></span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p86778"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p867code78"><pre class="text" style="font-family:monospace;">*/1 * * * * /apache_check.sh &amp;&gt; /dev/null</pre></td></tr></table></div><p><span style="text-decoration: underline;"><strong>Nota</strong></span>: se asume que el usuario que ejecuta el script tiene <strong>permisos de ejecución </strong>para Apache y programas bc y mutt que se utilizan (normalmente root), de lo contrario no funcionará correctamente.</p><h2><span style="color: #993300;">¿como funciona?</span></h2><p>El script necesita que configures una <strong>dirección de envío</strong> para los mails de notificación, que puedes cambiar en el valor de la variable DESTINY_EMAIL.</p><p>La primera comprobación que hace el script es para<strong> evitar ataques DDOS</strong> en los que se intentan que Apache haga muchos procesos hijos y sature el servidor (esto puede ser limitado en Apache) pero por si hubiese alguna manera de que el atacante lo incrementara o superase, el script reiniciará apache en caso de que haya muchos procesos y de esta manera se pueda liberar memoria. Para establecer el numero minimo y máximo, se pueden configurar las variables N_MIN y MAX_NPROCESS_APACHE respectivamente.</p><p>La segunda comprobación consiste en comprobar si <strong>apache esta funcionando</strong>, por si hubiese colapsado podamos volverlo a su ejecución normal.</p><p>La tercera comprobación establece un <strong>límite de consumo de memoria</strong> en el servidor, para que en tal caso (suponiendo que es Apache en que la consume) se reinicie apache y se liberen recursos. Por defecto este limite es el 90% de memoria del servidor y puede ser cambiado con la variable THRESHOLD.</p><p>De esta manera se puede conseguir tener un servidor un poco <strong>más optimizado</strong> al uso de memoria y tener constancia de cuando se producen picos debidos a Apache.</p><p>El script lo libero con <strong>licencia GPLv3</strong> para todos aquellos que lo necesiten y quieran hacer uso de él.</p><p>Puedes descargarlo comprimido aquí: <a class="downloadlink" href="http://shakaran.net/blog/downloads/apache_checker.sh.tar.gz" title="Versión1.0 descargado 88 veces" >Apache Checker (88)</a></p><p>Todas la mejoras, sugerencias, fallos y críticas son bien recibidas.</p> <br /><div><img src="http://shakaran.net/blog/wp-content/plugins/gd-star-rating/gfx.php?value=10.0" /></div><div>Rating: 10.0/<strong>10</strong> (2 votes cast)</div><br />]]></content:encoded> <wfw:commentRss>http://shakaran.net/blog/2010/02/apache-checker-un-script-comprobador-de-apache-en-bash/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached
Page Caching using memcached
Database Caching 1/80 queries in 0.044 seconds using memcached
Object Caching 2458/2688 objects using memcached

Served from: shakaran.net @ 2012-05-23 17:16:00 -->
