phpwordpressprofilingxhprof

xhprof-html won't show Run Report (No XHProf runs specified in the URL)


How do I show the Run Report for a given xhprof run using xhprof-html?

I installed tideways-xhprof.

apt-get install php-dev
git clone "https://github.com/tideways/php-xhprof-extension.git"
cd php-xhprof-extension
phpize
./configure
make
make install

I enabled it in my php.ini

extension=/usr/lib/php/20190902/tideways_xhprof.so

I configured wordpress to write-out xhprof runs in my wp-config.php file

# PHP profiling with tideways-xhprof 
#  * https://pressjitsu.com/blog/profiling-wordpress-performance/
if ( isset( $_GET['profile'] ) && $_GET['profile'] === 'secret-string' ) {
    tideways_xhprof_enable( TIDEWAYS_FLAGS_MEMORY + TIDEWAYS_FLAGS_CPU );
    register_shutdown_function( function() {
        $results = tideways_xhprof_disable();
        file_put_contents( '/path/to/my/xhprof/dir/' .date('Y-m-d\TH:i:s\Z', time() - date('Z')). '.xhprof' , serialize( $results ) );
    });
}

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

And I was successfully able to dump-out xhprof files by visiting https://example.com/index.php?profile=secret-string

root@host:/path/to/my/xhprof/dir/# du -sh *
1,6M    2022-05-25T18:15:45Z.xhprof
1,6M    2022-05-25T18:18:38Z.xhprof
root@host:/path/to/my/xhprof/dir/#

I also created a website with xhprof-html. And I configured it to find the above .xhprof files

root@host:/var/www/xhprof/xhprof-html# diff index.orig.php index.php 
83c83
< $xhprof_runs_impl = new XHProfRuns_Default();
---
> $xhprof_runs_impl = new XHProfRuns_Default( '/path/to/my/xhprof/dir' );
root@host:/var/www/xhprof/xhprof-html#

Now I can load access the xhprof-html/index.php file and it successfully displays my two .xhprof files at https://xhprof.example.com/xhprof-html/index.php

No XHProf runs specified in the URL.

Existing runs:

    2022-05-25T18:18:38Z.xhprof 2022-05-25 18:18:38
    2022-05-25T18:15:45Z.xhprof 2022-05-25 18:15:45

And if I click on either one, I'm redirected (as expected) to either of these pages:

However, I would expect the above pages to render the actual Run Report. But they do not. Instead, I just see

No XHProf runs specified in the URL.

Existing runs:

    2022-05-25T18:18:38Z.xhprof 2022-05-25 18:18:38
    2022-05-25T18:15:45Z.xhprof 2022-05-25 18:15:45

Hello? The XHProf run is clearly specified in the URL.

How do I get xhprof-html to display the actual Run Report?


Solution

  • The Run Report is not shown because it can't read the file.

    Problem

    You are generating the file using the tideways xhprof and writing a serialized output to a file

    $results = tideways_xhprof_disable();
    file_put_contents( '/path/to/my/xhprof/dir/' .date('Y-m-d\TH:i:s\Z', time() - date('Z')). '.xhprof' , serialize( $results ) );
    

    (source)

    But then, you switch to hosting an older (no longer maintained) fork of xhprof to serve xhprof_html in your web server's document root

    Note: Of course you have to do this, and even the tideways docs link you to the phacility repo. The tideways repo itself curiously does not include the xhprof_html directory, possibly because tideways is a business that sells xhprof visualization SaaS -- so they stripped the "poor man's" xhprof_html from the fork of xhprof that they maintain

    If you want to read the file using XHProfRuns_Default() then you should write the file using XHProfRuns_Default().

    Solution

    Change the block in your wp-config.php to the following

    # PHP profiling with tideways-xhprof 
    #  * https://pressjitsu.com/blog/profiling-wordpress-performance/
    if ( isset( $_GET['profile'] ) && $_GET['profile'] === 'secret-string' ) {
       tideways_xhprof_enable( TIDEWAYS_FLAGS_MEMORY + TIDEWAYS_FLAGS_CPU );
       register_shutdown_function( function() {
          $results = tideways_xhprof_disable();
          include_once( '/var/www/xhprof/xhprof_lib/utils/xhprof_runs.php' );
          $XHProfRuns = new XHProfRuns_Default( '/path/to/my/xhprof/dir' );
          $XHProfRuns->save_run( $results, date('Y-m-d\TH:i:s\Z', time() - date('Z')) );
       });
    }
    

    Then generate a new profile

    You'll now see a new item named something like 62906fb2c49b4.2022-05-27T06:29:06Z.xhprof

    No XHProf runs specified in the URL.
    
    Existing runs:
    
        62906fb2c49b4.2022-05-27T06:29:06Z.xhprof 2022-05-27 06:29:06
        2022-05-25T18:18:38Z.xhprof 2022-05-25 18:18:38
        2022-05-25T18:15:45Z.xhprof 2022-05-25 18:15:45
    
    

    Click this new item, and you'll acctually see the Run Report now that it can read the xhprof file format.

    For more info on this issue, see: