localdisk

PHP とか Java とか Web とか好きなことを書きます。

Laravel で xhprof を手軽につかう

f:id:localdisk:20140911161541p:plain


「推測するな。計測せよ」

と偉い人が言っていました。先人に倣って僕も頑張ろうと思います。…というのも自分が今作ってるアプリが特定の条件で極端に遅くなるという現象に遭遇したからですが。

というわけで Facebook 謹製*1 の xhprof を使ってみることにします。後継と言われている uprofiler はまだ HomeBrew ではインストールできなかったので。

PHP と xhprof のインストール

brew install php55 php55-mcrypt php55-xhprof

簡単ですね。mcrypt 入れてるのは Laravel で必要だからです。

xhprof_html/xhprof_lib を任意の場所にコピーする

mkdir $HOME/.xhprof
cp /usr/local/Cellar/php55-xhprof/{なんかユニークな文字列が入る}/xhprof_html $HOME/.xhprof/xhprof_html
cp /usr/local/Cellar/php55-xhprof/{なんかユニークな文字列が入る}/xhprof_lib $HOME/.xhprof/xhprof_lib

Laravel のコードに xhprof を仕込む

アプリケーションイベントを使うのが簡単でよいです。

<?php
// app/start/global.php
App::before(function()
{
    // xhprof を有効にする
    xhprof_enable(XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY);
});
// shutdown
App::shutdown(function()
{
    // 計測する
    $xhprof_data = xhprof_disable();
    $XHPROF_ROOT = '/Users/localdisk/.xhprof';
    $APP_NAME = 'app_name';
    require_once $XHPROF_ROOT . '/xhprof_lib/utils/xhprof_lib.php';
    require_once $XHPROF_ROOT . '/xhprof_lib/utils/xhprof_runs.php';
    $xhprof_runs = new XHProfRuns_Default();
    $run_id = $xhprof_runs->save_run($xhprof_data, $APP_NAME);
    // ログに xhprof 用の URL が出力されます
    Log::debug("http://localhost:8001/index.php?run={$run_id}&source={$APP_NAME}");
});

今回はタイトルにあるように手軽さを重視していますが、Laravel 的には Middleware を作って ServiceProvider に登録するのがよいと思います。設定も思いのままですし、アプリケーションのコードを修正する必要がなくなります。

あとは $HOME/.xhprof/xhprof_html をルートにしてPHPのビルトインサーバーを起動させておき、app/storage/logs/laravel.log に出力された URL にアクセスすればOKです。

最後に宣伝

明日 InnoCafe 開発コミュニティサミット in 福岡 - イノベーター・ジャパン | Doorkeeper という集まりがあります。東京と福岡のコミュニティについて面白い話が聞けるのでよかったら遊びに来てください。
翌日である 9/13 は ヌーラボさんのオフィスをお借りしてもくもく会をします。こちらもきっと楽しいと思いますのでよかったらどうぞ。

*1:だと思ってたけど違う人がメンテしてる?