Contents

XHProf

The original XHProf project is no longer supported with PHP7, but several alternative tools are freely available and generate compatible profiling information.
The most widely used of these is Tideways, which Moodle supports.

Tideways is a large, paid-for service, which helps to identify a range of issues with production servers.
Whilst the service itself is a paid-for service, the instrumentation tooling is both Open Source, and free.

There are two variants of the plugin. You will almost certainly want the tideways_xhprof plugin.

tideways - the original tool, which includes both xhprof instrumentation, and support for the Tideways service. This version is compatible with:

Moodle 3.0.6

Moodle 3.1.2

Moodle 3.2 onwards

tideways_xhprof - a rewritten implementation of the original which only includes the xhprof instrumentation. Compatible with:

Export Xhprof data to plugins

Starting at 3.6, Moodle allows for a plugin to handle the Xhprof data and not insert the traces into the database as implemented in (MDL-63031)[1]

To disable Moodle from writing traces to the database, add: "$CFG->disableprofilingtodatabase = False;" into config.php

Plugins will need to provide a _store_profiling_data function to handle the data.

Xdebug

Xdebug is a powerful PHP debugging tool. The first release of Xdebug was in 2002, since that it keeps growing and remains popular among PHP developers. Among its major features are stack and function tracing, code coverage analysis, remote debugging and scripts profiling. As the page topic suggests, we will focus on its profiling feature, which provides developer with detailed information about the script performance, helps identifying which parts of the code are slow. Collected information is being stored in cachegrind compatible file and can be analysed using one of external tools, such as KCachegrind, WinCacheGrind, xdebugtoolkit or web-based analyser Webgrind. Xdebug is simple to install and operate, it does not require code changes.

Installing Xdebug extension

The first step that has to be done is installing Xdebug extension. This procedure depends on the OS you are using, but general idea is to obtain Xdebug php extension and specify full path to it using zend_extension setting in php.inf file. Official Xdebug installation documentation explains its installation on Windows, installing through PEAR/PECL and compiling from source.
Xdebug has been packaged for many Linux distributions, so it can be installed using corresponding package management tool. On Debian or Ubuntu, for example one would need to execute:

# apt-get install php5-xdebug

This will put xdebug.so in default php modules directory and create /etc/php5/conf.d/xdebug.ini file with single line:

zend_extension=/usr/lib/php5/20090626/xdebug.so

Note that this is equal to specifying the same line in php.inf, example above just reflects split php configuration.

Once the Xdebug extension is installed and specified in php configuration, one may restart the webserver and information about Xdebug should appear in phpinfo() function output. If not, make sure that zend_extension line is not commented out, extension file exists in specified location and refer to webserver logs for more details.

Configuring Xdebug Profiler

When Xdebug extension is installed, it is time to configure profiling functionality. (If you are running apache2 as your web server and are using split configuration files such as the default apt-get install mentioned above, these settings should be added to "/etc/php5/apache2/conf.d/xdebug.ini".) There are number of parameters related to profiling, all of them start with xdebug.profiler_ prefix. First of all, profiler should be enabled. There are two ways of doing it. One way is keeping it always enabled, so profiling information will be generated on every page request:

xdebug.profiler_enable=1

Another way is making Xdebug writing profiling information on demand by triggering it with GET/POST or COOKIE variable named XDEBUG_PROFILE:

xdebug.profiler_enable_trigger = 1

This option is preferable for several reasons: profiling data files are relatively large especially on complex scripts and you may run out of disk-space pretty quick, it allows generating profiling information only when you need it, thus it is easier to find the generated file in output directory, finally, on demand profiling can be done on production servers, though it is not recommended. If you have enabled xdebug.profiler_enable_trigger option, make sure that xdebug.profiler_enable is disabled, otherwise this will lead to dump file being generated on each request.

Whatever method of profiling enabling you have chosen, profiling data files will be generated on each request (or request with a trigger parameter) in directory specified with xdebug.profiler_output_dir directive. By default is it set to /tmp, but you may change it to any more suitable location.

xdebug.profiler_output_dir=/tmp

Generated file will be named in accordance with xdebug.profiler_output_name setting. This setting can handle some specifiers and use them in the file name. Default name pattern is cachegrind.out.%p; in the actual file name %p will be replaced with process ID value. The fill list of specifier can be found here. More intuitive naming is recommended, so that it is easier to find the file you have just generated in the bunch of others:

xdebug.profiler_output_name=cachegrind.out.%R.%t

With this naming pattern, timestamp and script name will be reflected in the file name.

When you are done with configuration, it is time to test it. First of all, the webserver has to be restarted, so that the new config will come into effect. Depending on your operating system and web server, you should be able to restart it with a command similar to:

sudo service apache2 restart

(This should work for apache2 on several flavours of Linux.)

Profiling a page

Now assuming that Xdebug was configured to use a trigger for script profiling, open any php page on your server in your browser having added XDEBUG_PROFILE parameter to URL string:

http://servername/moodle2/index.php?XDEBUG_PROFILE

or if it already has some parameters, just add our trigger to the URL end:

http://servername/moodle2/mod/forum/view.php?id=5&XDEBUG_PROFILE

As a result, the new file should be generated in directory you specified with xdebug.profiler_output_dir directive:

Triggering profiling with POST requests or AJAX queries is also possible without code changes. Easy Xdebug plugin for FireFox has profiling toggle button that inserts XDEBUG_PROFILE variable into cookie data, thus making profiling enabled for as long as you wish for all requests. Similar plugins exist for Chrome and Safari browsers.

Analyzing Xdebug profiling files

As it was pointed out earlier, profiling data is recoded in cachegrind format, so it can be analysed using one of external tools, such as KCachegrind, WinCacheGrind, xdebugtoolkit or web-based analyser Webgrind. Using these tools is pretty simple. I prefer KCachegrind which has a feature to show the matching code if web-server is run on the same box. Xdebug profiler documentation page has a section about KCachegrind that worth reading for everyone who starts using KCachegrind.