Xdebug en PHP (KCachegrind y Webgrind)

Cuando queremos que nuestros scripts php sean más rápidos y sin atascos tenemos varias opciones, cachear, acelerar código, depurar... todas ellas complementarias y elementales para aplicaciones de alto rendimiento.

Hoy hablaremos de la depuración y localización de cuellos de botella. Para ello tenemos varias herramientas indispensables en PHP que pueden facilitar mucho la vida del programador. Entre ellas se encuentran Xdebug y APD. En este artículo trataremos la instalación y configuración de la primera, así como varias herramientas de análisis y representación gráfica de informes.

Xdebug con PEAR

La instalación de Xdebug puede llevarse a cabo de varias formas distintas, aquí se abordarán las dos más frecuentes, a través de PEAR o compilándolo como extensión Zend. Empecemos por la primera.

Para instalar Xdebug en Debian/Ubuntu lo haremos a través de PEAR (pecl):

# apt-get install php-pear

Intentamos la instalación de Xdebug, pero nos dará un error:

# pecl install xdebug
downloading xdebug-2.0.3.tgz ...
Starting to download xdebug-2.0.3.tgz (286,325 bytes).........done: 286,325 bytes
66 source files, building
running: phpize
sh: phpize: not found
ERROR: `phpize' failed

Necesitamos phpize, una herramienta que viene disponible en el paquete de desarrollo de php, lo instalamos:

# apt-get install php5-dev

Y repetimos:

# pecl install xdebug
[...]
Build process completed successfully
Installing '/usr/lib/php5/20060613+lfs/xdebug.so'
install ok: channel://pecl.php.net/xdebug-2.0.3
configuration option "php_ini" is not set to php.ini location
You should add "extension=xdebug.so" to php.ini

Agregamos la extensión y configuramos para que el profiler se active de forma automática y guarde los logs en el directorio /var/log/xdebug:

extension = xdebug.so
xdebug.profiler_enable = 1
xdebug.profiler_output_dir = "/var/log/xdebug"
xdebug.profiler_output_name = "-%H%R-%u.webgrind"

xdebug.auto_trace = On
xdebug.trace_output_dir = "/var/log/xdebug"
xdebug.trace_output_name = "trace-%H%R-%u"

Ojo: El directorio /var/log/xdebug debe tener permisos para el usuario www-data, que es el que escribirá el informe.

Como paso final creamos un típico phpinfo.php y reiniciamos el servidor para ver si -con la nueva configuración- genera el informe cuando visitemos http://localhost/phpinfo.php:

# echo "<?php phpinfo(); ?>" >> /var/www/phpinfo.php
# /etc/init.d/apache2 restart
Xdebug en phpinfo()
Xdebug en phpinfo()

La visualización de ésta página generará un informe /var/log/xdebug/cachegrind.out.3159, que podremos analizar bien por Webgrind o por Kcachegrind.

Xdebug como extensión Zend

Antes de nada veremos si tenemos instalado php5-dev o no. Si no es así lo instalamos:

# dpkg -l | grep php5-dev
# apt-get install php5-dev

Una vez instalado bajamos Xdebug a una carpeta temporal, descomprimimos, preparamos la extensión para compilarla, compilamos e instalamos:

# wget http://xdebug.org/link.php?url=xdebug203
# tar xfvvz xdebug-2.0.3.tgz
# cd xdebug-2.0.3
# phpize
Configuring for:
PHP Api Version:         20041225
Zend Module Api No:      20060613
Zend Extension Api No:   220060519
# ./configure --enable-xdebug
# make
# make install
Installing shared extensions:     /usr/lib/php5/20060613+lfs/

Para la configuración posterior tenemos que usar el archivo php.ini que esté cargado, con lo que abrimos ese archivo (/etc/php5/apache2/php.ini) y agregamos las siguientes lineas antes de ;End:

zend_extension=/usr/lib/php5/20060613+lfs/xdebug.so
xdebug.profiler_enable=1
xdebug.remote_enable=1
xdebug.profiler_output_dir=/var/www/webgrind/log/

Debemos cerciorarnos de que el directorio de log tiene los permisos adecuados para que el usuario de apache (www-data en este caso) pueda escribir ahí sus informes. El último paso será reiniciar Apache:

# /etc/init.d/apache2 restart

Si todo ha salido correctamente veremos en phpinfo() algo parecido a lo siguiente:

This program makes use of the Zend Scripting Language Engine:
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans
Xdebug en phpinfo
Xdebug en phpinfo()

KCacheGrind

Es una herramienta en QT (KDE) que analiza y representa el informe creado por Xdebug, tan solo hay que abrir el archivo cachegrind.out correspondiente y echar un vistazo. Para instalar es tan sencillo como hacer un:

# apt-get install kcachegrind

Varios pantallazos de ejemplo:

KCacheGrind Ejemplo 1
Ejemplo de KCacheGrind con phpinfo()
KCacheGrind Ejemplo 2
Ejemplo de KCacheGrind con Kohana
KCacheGrind Ejemplo 3
Ejemplo de KCacheGrind con Code Igniter

Webgrind

Llega el turno para Webgrind, un frontend web para analizar los logs generados por Xdebug. Instalarlo es tan sencillo como bajarse el fuente y descomprimirlo en un documentroot accesible:

# cd /var/www/webgrind/
# wget http://webgrind.googlecode.com/files/webgrind-release-0.81.zip
# unzip webgrind-release-0.81.zip

Una vez lo tenemos descomprimido y listo solamente hemos de configurar el directorio de donde ha de leer los cachegrind.out generados por el profiler de Xdebug. Eso se hace en el config.php:

/**
   * Writable dir for information storage.
   * If empty, will use system tmp folder or xdebug tmp
   */
   static $storageDir = &#39;/var/www/webgrind/log/';

Ahora nos vamos al interfaz web (http://localhost/webgrind/ por ejemplo) y seleccionamos en el combo superior el archivo grind a pintar:

Webgrind
Webgrind en acción

El informe detallado de profiling será algo similar a lo siguiente:

Webgrind
Informe detallado en Webgrind

Referencias

About the author

Óscar
has doubledaddy super powers, father of Hugo and Nico, husband of Marta, *nix user, Djangonaut and open source passionate.