Looking at Drupal Performance with XProf and XHGui

Perhaps, your Drupal site is so slow that you cannot ignore it any longer and you have decided to look into the affects of the poor performance. In general, the affects of performance may be categorized into three categories each addressing different aspects of application such as Drupal:

  • Code execution looks at the time code executes.
  • Querying database looks at how much time it takes to query database.
  • Load balancing looks at how your site performs based on number of visitors on your site at the same time.

In this post, we cover how to use XProf and XHGUI to look into code execution aspect of the performance. It also helps determine if code execution related to DB querying is significant enough contributor to slow performance that you have to address it as well

Before starting troubleshooting performance, restart the mysql because mysql keeps cache and some bad queries in the cache may have an unwanted effects on your performance analyses

Profile PHP Executions

To to profile php executions, we will use XHprof. There is XHprof part of Drupal Devel module,however. It’s outdated and it was difficult to make it work with Ubuntu 14/Apache 2.4. Instead we will grab the newest XHprof that comes with nice GUI for reports and run it as stand alone solution

But before installing XHprof, lets install MongoDB because the newest of XHprof requires MongoDB to run.

sudo pecl install --nocompress mongo
echo 'extension=mongo.so' > /etc/php5/mods-available/mongo.ini
sudo php5enmod mongo
sudo service apache2 restart
mongo

This installs MongoDB, configures the php driver to be loaded and starts the mongo DB

Installing XHprof and XHGui

Next, lets install the XHprof.:

sudo pecl install --nocompress xhprof-beta
echo 'extension=xhprof.so' > /etc/php5/mods-available/xhprof.ini
service apache2 restart
php -m | grep xhprof

Here, we first install xhprof module. Next we enable it and then restart it to load the module. At last, we verify if the module is loaded by retrieving all php modules loaded and filtering for xhprof module only. If you see the ‘xhprof’ listed, then you have installed XHprof correctly

Lets install the Gui for xhprof(XHGui) as following:

sudo git clone https://github.com/perftools/xhgui.git xhgui
sudo chmod -R 777 xhgui
cd xhgui
sudo composer install
sudo php install.php

Access XHGui Reports

To see the reports, we will configure virtual host that services dir located at /path/to/xhgui/webroot as following:

<VirtualHost *:80>
	DocumentRoot /home/margots/tools/xhgui/webroot
	ServerName xhgui
	<Directory "/home/margots/tools/xhgui/webroot">
		Options Indexes MultiViews FollowSymLinks
		AllowOverride All
	#	Order allow,deny
	#	Allow from all
		Require all granted
	</Directory>
</VirtualHost>

After putting the above virtual host at /path/to/apache2/sites-available/xhgui.conf, we enable and load:

sudo a2ensite xhgui
services apache2 restart

At last, lets point the url – xhgui to our local machine in the local DNS table /etc/hosts:

127.0.0.1     xhgui

Now, if you go to ‘http://xhgui’, you should see the the reports of xhprof. You should see something like “Looks like you haven’t done any profiling” if for the first time. This is because, we haven’t enabled profiling to any o our sites.

Enabling XHProf Profiling for Drupal Site

One way to enable profiling is to do it in php.ini that is going to profile all sites. If you like to profile individual site, then another way to enable profiling is via virtual host for the particular site. To do so, update the virtual host by adding following line:

<VirtualHost *:80>
...
   php_admin_value auto_prepend_file /path/to/xhgui/external/header.php
...
<Directory path/to/root>
....
</Directory>
<VirtualHost>

After restarting apache, your site will be profiled. Make view requests and open reports at http://xhgui

Configure XProf Profiler

  1. Profiler Every Request

    By default, XHprof will only profile 1% of all requests because it is intended light weight to be used in production. Since we are at development and like to improve performance, we enable to profile all requests by updating /path/to/xhprof/config/config.default.php:

    ...
    'profiler.enable' => function() {
    #        return rand(0, 100) === 42;
    	return true;
        },
    

    Here, we uncommented the ‘rand(0,100)===42’ line and added ‘return true;’ to profile all requests

  2. Clear HXProf or XHGUI

    To clear XHProf with XHGui, log into mongo db and clear the collection – results as following:

    mongo
    use results
    db.drop()
    

    The first line log into mongo db console. Next we switch the the database. At last command, it drops database – results that is is going to be recreated by the XHGui on the next request that is profiled

    Some other useful commands:

    show dbs //shows all databases
    use results //switch to this database
    db.results.help() //to find out all commands available for collection results
    
  3. Delete After 5 Days

    To limit disk usage, perhaps, you like to set certain time after which the logs are deleted

    $ mongo
      > use xhprof
      > db.results.ensureIndex( { "meta.request_ts" : 1 }, { expireAfterSeconds : 432000 } )
    

    This will set logs to be deleted after 5 days.

Enable Profiling for Command Line Executions

Drush is common tool for handling Drupal and you may want to profile it as well.
To profile scripts run from command line, all you have to do is import the header.php as following:

<?php
require '/path/to/xhgui/external/header.php';
// Rest of script.

Or use the -d flag:

php -d auto_prepend_file=/path/to/xhgui/external/header.php do_work.php

This will start profiling the particular script run from command line

Troubleshooting

1. could not extract the package.xml file from “/build/buildd/php5-5.5.9+dfsg/pear-build-download/mongo-1.5.5.tgz”

This happened when installing php mongo driver. The solution was installing uncompressed as following:

pecl install --nocompress mongo
2. Fatal error: Class ‘Xhgui_Config’ not found in [path]/xhgui/src/bootstrap.php

This error appears,when you forget to run ‘composer install’ before ‘php install.php’ in the xhgui directory. Basically, the autoloader.php is missing because composer hasn’t created it and you need autoloader to load Xhgui_Config class

3. xhgui – Failed to connect to: 127.0.0.1:27017: Connection refused

This error indicates that the mongodb cannot start. After looking into mongodb logs(/var/log/mongodb/), it was telling that we are out memory. By increasing memory, the mongodb was able to start and the error was gone

References