laradock で プロファイラ(性能解析)ツール xhprof を入れて動かす


php を使っている環境で、プロファイラツールというと xhprof が有名なようですが、laradock 環境で簡単に使えないかな? と思って調べて記録です。

tideways/xhprofの公式レポジトリ: https://github.com/tideways/php-xhprof-extension
可視化のためのツール: https://github.com/sters/xhprof-html

どうも調べてみるとlaradockのgithubレポジトリに xhprof.ini ファイルがあることがわかりました。
https://github.com/laradock/laradock/blob/master/php-fpm/xhprof.ini

インストール方法

laradock/.env
PHP_FPM_INSTALL_XHPROF=true

これを有効にして、再度ビルド。

$ docker-compose build php-fpm

コードでの利用法


tideways_enable();

your_code();         

file_put_contents(
    '/tmp/offer_search.xhprof',
     json_encode(tideways_disable())
);

※公式で書いてあるメソッド名(tideways_xhprof_enable())と違うこれで動く
情報提供のブログ(中国語) https://translate.google.com/translate?hl=ja&sl=zh-CN&u=https://blog.mango.im/2018/05/php-xhprof-extension-01/&prev=search

これは、laradockでインストールしている tideways のバージョンが 4.1.7 であるのに対して、
tideways の最新のバージョンが5系になっているからだった。
laradockファイル該当箇所: https://github.com/laradock/laradock/blob/04c6aaf3389ebd30e2874788b90437f229effb0b/php-fpm/Dockerfile#L275

追記: 修正PRを出したので最新版のLaradockだと動くはず https://github.com/laradock/laradock/pull/2342

見る

おまけです。色々なみるためのソリューションがあるのですが、私が試した方法だけ記録しておきます。

直接ファイルみる

php-fpm のコンテナに入って、 /tmp/ディレクトリにいくと該当ファイルがあるので、ダウンロードするなりコピーするなりして中身見れます。
json なので jq で見るなり http://jsonviewer.stack.hu/ こういうので見るなりできます。

xhprof-htmlでみる

こちらを使います。https://github.com/sters/xhprof-html
使い方は公式に書いてある通り単純です。

ただし、いくつかハマりどころがあったので記録しておきます。
ツールのclone先をプロジェクト直下の /public/ 下とすると、laradockのphp-fpmコンテナの中では /var/www/public/xhprof-html/ になります。ここに結果出力先を output を作っておくとして ($ mkdir output) 出力結果の出し方は以下のようになります


tideways_xhprof_enable();

my_application();

$data = tideways_xhprof_disable();
// ★出力先に注意
$filename = '/var/www/public/xhprof-html/output/' . intval(microtime(true)) . mt_rand(1,10000) . '.xhprof';
// ★serialize していることに注意。
file_put_contents($filename, serialize($data));

ファイルを直接みるときには serialize いらないのですが、このツールを使うときには必要です。

で、クローンしたツールのレポジトリのディレクトリ内でphp -Sでサーバ起動します。このPHPはMacのPC内のphpコマンドを用います。

上記のコードでアウトプット先を決めたところをURLのクエリパラメタで追加してリクエストします。
http://localhost:8000/?dir=/Users/MyUserName/PathToProject/public/xhprof-html/output

ここまではドキュメントに書いてある通りなのですが、最後にハマりどころがありました。出力ファイル名でそのまま読んでくれないで
/Users/MyUserName/PathToProject/public/xhprof-html/output/15733478965982.xhprof.xhprof のように拡張子が二つついているような状態のファイルを期待したコードになっていました
今の所、こういうコードになっている詳細未調査。$type と $suffix がそれぞれ対応しており、$type になんでか xhprof が入ってくる(グローバル変数登録をどこかでしている?)。
それはそうと、とりあえず以下のように直せば治りました。(こちらも時間見つけてコミットしたい・・・)

--- a/xhprof_lib/utils/xhprof_runs.php
+++ b/xhprof_lib/utils/xhprof_runs.php
@@ -76,7 +76,8 @@ class XHProfRuns_Default implements iXHProfRuns {

   private function file_name($run_id, $type) {

-    $file = "$run_id.$type." . $this->suffix;
+    $file = "$run_id." . $this->suffix;

     if (!empty($this->dir)) {
       $file = $this->dir . "/" . $file;

というわけで最終的にブラウザアクセスすると

こういう感じとか(アクセスごとに結果がみれる)

こういう感じで(詳細のメソッドを追っていくと、それがどれくらい呼ばれてて、実時間Wall Timeでどれくらいかかっているかわかります。)
※プロジェクトに多少関係があるところはモザイク入れてあります。