プロファイラ(xhprof)を簡単に安全に導入できる手順を用意してみた

# 課題

1. プロファイラ導入ってお金や手順がかかる
2. 今調査したい、、けど、環境構築にある程度時間がかかる
3. リクエストごとに全部プロファイリングされるのは膨大なログがたまり、HDD を圧迫するのは辛い

# 前提

- apache2.x 環境で、 php-module として WEB を稼働している
- php5.x 以上、 php7 以上の環境である
- 該当サーバで sudo もしくは他の方法で root 権限のいるコマンドが実行できる

# 準備 (インストール)

まずは yum (apt) で xhprof のパッケージ存在確認

```
$ yum search xhprof
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
remi-safe/primary_db                                                                                                     
                                                        | 1.6 MB  00:00:02     
243 packages excluded due to repository priority protections
========================================================================================= N/S matched: xhprof ======================================================================================================================================================================
php-pecl-xhprof.x86_64 : PHP extension for XHProf, a Hierarchical Profiler
php54-php-pecl-xhprof.x86_64 : PHP extension for XHProf, a Hierarchical Profiler
php55-php-pecl-xhprof.x86_64 : PHP extension for XHProf, a Hierarchical Profiler
php56-php-pecl-xhprof.x86_64 : PHP extension for XHProf, a Hierarchical Profiler
php70-php-pecl-xhprof.x86_64 : PHP extension for XHProf, a Hierarchical Profiler
php71-php-pecl-xhprof.x86_64 : PHP extension for XHProf, a Hierarchical Profiler
php72-php-pecl-xhprof.x86_64 : PHP extension for XHProf, a Hierarchical Profiler
php73-php-pecl-xhprof.x86_64 : PHP extension for XHProf, a Hierarchical Profiler
php74-php-pecl-xhprof.x86_64 : PHP extension for XHProf, a Hierarchical Profiler
php54-xhprof.noarch : A Hierarchical Profiler for PHP - Web interface
php55-xhprof.noarch : A Hierarchical Profiler for PHP - Web interface
php56-xhprof.noarch : A Hierarchical Profiler for PHP - Web interface
php70-xhprof.noarch : A Hierarchical Profiler for PHP - Web interface
php71-xhprof.noarch : A Hierarchical Profiler for PHP - Web interface
php72-xhprof.noarch : A Hierarchical Profiler for PHP - Web interface
php73-xhprof.noarch : A Hierarchical Profiler for PHP - Web interface
php74-xhprof.noarch : A Hierarchical Profiler for PHP - Web interface
xhprof.noarch : A Hierarchical Profiler for PHP - Web interface

  Name and summary matches only, use "search all" for everything.
```

あったのでインストール

```
$ yum install php-pecl-xhprof
```

※yum パッケージ、apt にない方は、以下の方法でインストール

```
# php 7 以上の環境
$ git clone https://github.com/longxinH/xhprof.git ./xhprof
$ cd xhprof/extension/
$ phpize
$ ./configure
$ make && sudo make install

# php 7 未満の環境
$ sudo pecl install channel://pecl.php.net/xhprof-2.1.4
```

# 設定変更

`vi /etc/php.ini ` で ini ファイルの末尾に以下を追加

```
[xhprof]
extension = xhprof.so
xhprof.output_dir = /var/log/xhprof
```

さらに以下の設定を進める

```
# xhprof ログ置き場
$ sudo mkdir -vp /var/log/xhprof
$ sudo chmod 777 /var/log/xhprof

# ３１日経過したファイルを削除する cron
$ echo '0 0 * * * root find /var/log/xhprof -mtime +30 -delete' |sudo tee /etc/cron.d/xhprof-log-remove
$ sudo chown root:root /etc/cron.d/xhprof-log-remove

# xhprof ファイル置き場
$ sudo mkdir -vp /opt/xhprof
$ cd /opt/xhprof
$ sudo git clone https://github.com/longxinH/xhprof.git
```

`vi main.php` で以下のように記述

※ `ほげほげ.hapitas.jp` と書いているところは適宜自分の環境に書き換えてください

```
<?php

if (isset($_GET['use_profiler'])) {
    if (function_exists('xhprof_enable') && function_exists('xhprof_disable')) {
        include_once __DIR__.'/xhprof/xhprof_lib/utils/xhprof_lib.php';
        include_once __DIR__.'/xhprof/xhprof_lib/utils/xhprof_runs.php';

        xhprof_enable(XHPROF_FLAGS_NO_BUILTINS|XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY);
        register_shutdown_function('xhprof_shutdown');
    }
}

function xhprof_shutdown()
{
    $data = xhprof_disable();
    $runs = new XHProfRuns_Default();

    $appName = date('Y-m-d_H-i-s').(int)microtime(true);
    $runId = $runs->save_run($data, $appName);
    printf('<a href="https://ほげほげ.hapitas.jp/xhprof/index.php?run=%s&amp;source=%s">profiler check</a>%s', rawurlencode($runId), rawurlencode($appName), PHP_EOL);
}
```

`vi /etc/httpd/conf.d/xhprof.conf` で以下のように記述

こうすることで、 web から index.php やらを呼ばれる前に、先程作った main.php が実行され、 /xhprof のURLにアクセスすると xhprof の解析用のURLに遷移できる

```
php_value auto_prepend_file /opt/xhprof/main.php
Alias /xhprof /opt/xhprof/xhprof/xhprof_html
```

最後に `service httpd restart` して準備完了

----

1. URL に ?use_profile=1 をいれます、下の方に 「profile check」という文字がでてくるので、クリックすると

<img width="541" alt="スクリーンショット 2019-12-26 9.48.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/855d908b-9cef-73c2-047e-37c341cd9e29.png">


2. こうなります。あとはCPU時間、メモリ使用量がどれぐらいになっているか解析をお楽しみください！

<img width="1206" alt="スクリーンショット 2019-12-26 9.53.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218682/52544433-04ca-b427-c57b-931de4a0cfc8.png">