Ubuntu+nginxの環境にxhprofを導入する

PHPのパフォーマンス測定用ツールxhprofをubuntu+nginxの環境で使うやり方をまとめています。やりたい事自体はubuntu以外のOSやapache等でも応用できるはずです。

インストール方法は本家含めて色々なとこで記述されているかと思うのですが、実際に恒常的に使うとなるまでに関しての資料があまり見つからず、またそのまま使うには少々不便な所がある（タグを入れたり等）ので、今回まとめました。

#検証した環境
ubuntu 14.04.5
nginx 1.10.1
PHP 5.5.9

#xhprofのインストール

サーバ上で必要ファイルのインストール。rootもしくはsudoで実行。

```
apt-get install graphviz
apt-get install libgv-php5
pecl install xhprof-0.9.4
```

xhprofを有効にする。xhprof.output_dirにはxhprofのプロファイルデータ保存先。
データを残しておきたい場合は/tmp以外を指定してください。

```
echo "extension=xhprof.so" > /etc/php5/mods-available/xhprof.ini
echo "xhprof.output_dir=/tmp" >> /etc/php5/mods-available/xhprof.ini
php5enmod xhprof
```

確認、0.9.2がインストールされているが特に利用に支障はないので気にせず進める

```
php -i|grep xhprof
/etc/php5/cli/conf.d/20-xhprof.ini
xhprof
xhprof => 0.9.2
```

#プロファイル画面の設置

```
cd /var/www
git clone https://github.com/phacility/xhprof.git
```

#nginxの設定

http://<ドメイン or IP>/xhprof/で見れるように設定。
/var/www/html/xhprofに必要ファイル一式をおいても良いのだが、今回はhtml以下を汚さない方針で以下の様に設置

```nginx設定（抜粋）
server {
  listen 80;
  server_name <<your domain>>;
  root   /var/www/html;

(略)
  #PHP実行設定
  location ~ \.php$ {
    fastcgi_pass    unix:/var/run/php5-fpm.sock;
    fastcgi_index   index.php;
    fastcgi_param   SCRIPT_FILENAME $document_root/$fastcgi_script_name;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;
    include         fastcgi_params;
  }

  #xhprof/以下でxhpforを見るための設定
  location ^~ /xhprof {
    alias /var/www/xhprof/xhprof_html;

    index index.php index.html index.htm;

    location ~ \.php$ {
      fastcgi_pass    unix:/var/run/php5-fpm.sock;
      fastcgi_split_path_info ^(/xhprof)(/.*)$;
      fastcgi_index   index.php;
      fastcgi_param   SCRIPT_FILENAME $request_filename;
      fastcgi_buffers 16 16k;
      fastcgi_buffer_size 32k;
      include         fastcgi_params;
    }
  }
}
```

nginx,php5-fpmをリロード

```
nginx -s reload
service php5-fpm restart
```

xhprof/以下で画面表示した際に画面ではパスがルート直下になっており、css,js等がでないのとリンクが全て死ぬ。
設定する所が見つからなかったので、以下の様に対応。（やり方として恐らく間違っているので、正しいやり方があればご指摘ください。。。）

```/var/www/xhprof/xhprof_lib/display/xhprof.php
45行目付近
/**
* Our coding convention disallows relative paths in hrefs.
* Get the base URL path from the SCRIPT_NAME.
*/
// $base_path = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
// ↓
$base_path = "/xhprof".rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
```

```/var/www/xhprof/xhprof_lib/display/xhprof.php
59行目付近
if (empty($ui_dir_url_path)) {
  //$ui_dir_url_path = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
  // ↓
  $ui_dir_url_path ='/xhprof'. rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
}
```

#プロファイル実行用スクリプト設置


##スクリプト作成
基本的にやることはxhprofのプロファイル開始と終了だが、
プロファイルするしないを自由に制御できる様にパラメーターとcookieで実行を制御する。

```/var/www/xhprof/xhprof_profile_start.php
<?php
$isExecuteXhprof=false;
if(isset($_COOKIE['is_execute_xhprof']) && $_COOKIE['is_execute_xhprof']==1){
    $isExecuteXhprof=true;
}
if(isset($_REQUEST['xhprof'])){
    if($_REQUEST['xhprof']=='1'){
        $isExecuteXhprof=true;
        setcookie('is_execute_xhprof',1);
    } elseif($_REQUEST['xhprof']=='0'){
        $isExecuteXhprof=false;
        setcookie('is_execute_xhprof',0);
    }
}
if($isExecuteXhprof){
    xhprof_enable();
}
```

```/var/www/xhprof/xhprof_profile_finish.php
<?php
if($isExecuteXhprof){
    //プロファイル終了
    $xhprof_data = xhprof_disable();

    //データ保存
    $XHPROF_ROOT = "/var/www/xhprof/";
    include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
    include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php";

    $xhprof_runs = new XHProfRuns_Default();
    $run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo");

    //表示、ログ出力、etc
    echo '<br /><a id="xhprof_result_link" href="http://'.$_SERVER['HTTP_HOST'].'/xhprof/index.php?run='.$run_id.'&source=xhprof_foo" target="_blank">xhprof</a>';
}
```

##スクリプト設置

以下どちらかの方で開始と終了の設定を読み込む。

###nginxの設定で読み込む

nginxに以下の様にfastcgi_paramにPHP_VALUEを設定すれば、ページ実行時に強制的に入れてくれる。

```
  #PHP実行設定
  location ~ \.php$ {
    (略)
    fastcgi_param   SCRIPT_FILENAME $document_root/$fastcgi_script_name;
    #以下を追加
    fastcgi_param  PHP_VALUE   "auto_prepend_file=/var/www/xhprof/xhprof_profile_start.php \n auto_append_file=/var/www/xhprof/xhprof_profile_finish.php";
    (略)
  }
```

```
nginx -s reload
```

###プログラム上でincludeする
```
//プロファイル開始のところに入れる
include('/var/www/xhprof/xhprof_profile_start.php');

（計測したい処理）

//プロファイル終了のところに入れる
include('/var/www/xhprof/xhprof_profile_finish.php');
```

#動作確認
正常に設定されて入れば、パラメータにxhprof=1をつけて、ページの最下部にリンクが表示されるはずです。
一度パラメータをつけるとプロファイルし続け、xhprof=0とするとプロファイルをしなくなります。

遷移先でもプロファイル結果が正しく表示され、リンク等も問題なく遷移できれば正常にインストールされています。ページによっては表示の設定等で最下部が見れない場合もあるので、以下の様なブックマークレットを使うと便利です。

##プロファイルページを出す用のブックマークレット

```
javascript:(function(){var%20d=window.document;if(d.getElementById("xhprof_result_link")){window.open(d.getElementById("xhprof_result_link").href);}else{alert("xhprofのリンクが取得できませんでした。xhprofが実行されていないか、処理が中断されていないか等確認ください。");}
})();void(0);
```