XHGui on VM, Storage on Host

I'm doing some performance tuning on a project at the moment and my favourite tool is still XHGui - but it's designed to run on the same machine as its victim and since this is a vagrant VM, the chances of me destroying the machine and therefore the data are pretty high! Instead, I set it up to store the data onto the host and I thought I'd share how I did that.

All these instructions for Ubuntu on both host and guest, and I've tried not to be specific about the vagrant elements in order to focus on how the pieces fit together rather than what you should type.

XHGui Moving Parts

For this to make sense, we need to understand the ingredients of this excellent tool. They are:

  • An extension with the ability to capture the performance data from inside PHP - either XHProf or uprofiler will work fine (uprofiler plays slightly more nicely with newer versions of PHP)
  • The XHGui capture functionality - we include this with each request and it prompts the extension to start to capture and tells it where to store the data
  • Mongodb for XHGui to use as a datastore
  • The XHGui frontend that presents the data nicely and allows you to compare runs

Set up the Guest

First I set up the vagrant machine. Since we intend to be able to destroy and recreate these machines, you'll probably want to translate these instructions so that they make sense to your provisioner of choice!

First I added the PHP extensions I would need: mongo and xhprof are both available from pecl (xhprof is beta so the package is xhprof-beta). Don't forget to enable the extensions and restart apache (guess why I have this in my notes?). Note that you'll also need mcrypt if you don't have it already.

The grab the XHGui code itself, either by cloning the project into your VM, or if it's easier you can grab a download from the GitHub site and use that - I did this and just got the provisioner to copy it into the right place. Then you will need to install XHGui by running its install script:

php install.php

This will let you know if any dependencies are missing, prompt you if the permissions aren't correct on the cache directory (it's probably fine to open up the permissions completely on a VM) and will also install all the composer dependencies that XHGui relies on.

We also need to configure XHGui at this point. Copy config/config.default.php to config/config.php and look inside it. We need to change at least one thing here - the location of the mongodb. Your settings should look something like this (you need to know the IP that your guest machine can use to reach your host machine, for me that's 10.0.2.2):

'db.host' => 'mongodb://10.0.2.2:27017',

The other thing I usually change in this config file is to set XHGui to profile every request - this tool is designed to be safe for a live platform so will only profile 1% of requests by default but in development it makes more sense to see all of them. To do this, set the anonymous function for profiler.enable to return true every time.

(Note: What I actually do here is take a correct version of the config file and get the provisioner to copy it into place - so I do the above the first time, then automate it once it's all working)

Almost there on the guest - the final step is to configure the virtualhost to get the XHGui files included with every request. This is done by adding a PHP auto_prepend_file directive to the vhost configuration:

php_admin_value auto_prepend_file "/path/to/xhgui/external/header.php"

At this point, you should be able to request your project and see data arriving in mongodb on the host.

Viewing the Data on the Host

Since we've got the data storage on the host machine, it makes sense to view the results there as well, so we install XHGui there as well. Clone the project from github and then run the install script:

php install.php

Again, this will check for system dependencies and pull in PHP dependencies. The dependencies are the mongo and mcrypt extensions. Once you're all set and the install script completes in a happy manner, you should be able to get the web interface running.

I use the PHP webserver for this, so in the webroot/ folder I run:

php -S localhost:8888

At this point, the web interface should exist at http://localhost:8888 and hopefully show some data!

XHGui is a really useful performance tool, allowing you to inspect which parts of your application are taking all the time/CPU/memory. It also allows you to compare multiple requests to the same endpoint - so when you are focussing on performance, get some benchmarks from XHGui before you begin, and then you'll be able to see which things make a big difference and which aren't worth the effort. On a development platform without load the numbers are different to what you'd see from having this on a live platform and keeping an eye on any pages that have suddenly got slower, but I find this a very handy tool when I do need to optimise for something in particular.

Having the data on my host means I am less likely to lose it when rebuilding my dev environment, and that I can compare runs even after deliberately upgrading the VM. I haven't set up this tool this way before and wanted to write down what I had done - if it's useful (or not!) or you have something to share, please leave a comment.

2 thoughts on “XHGui on VM, Storage on Host

  1. Pingback: Lorna Mitchell: XHGui on VM, Storage on Host - Reader

  2. Thanks for the article! My first thought was to use the 'file' output mode of XHGui and then pull those over (first thoughts are not always very smart thoughts...), but this is much easier. I am interested about what you said about uprofiler vs XHProf, did you experience issues personally with XHProf or are these issues documented somewhere?

Mentions