PHP および DTrace の使用
DTrace 動的トレーシングをサポートするプラットフォームでは、 DTrace 静的プローブ付きで PHP を構成できます。
DTrace 静的プローブのために PHP を構成
OS の DTrace サポートを有効にするには、 プラットフォーム固有の外部のドキュメントを参照してください。 例えば、Oracle Linux では UEK3 を起動して下記を行います。
# modprobe fasttrap# chmod 666 /dev/dtrace/helper
chmod
を使用する代わりに、
デバイスのアクセスを特定のユーザーに制限するために
ACL パッケージ・ルールを使用できるでしょう。
--enable-dtrace
構成パラメータとともに PHP をビルドします。
# ./configure --enable-dtrace ...# make# make install
これは、 コア PHP で静的プローブを有効にします。 それら自身のプローブを提供するどの PHP 拡張モジュールも、 共用拡張モジュールとして別々にビルドするべきです。
コア PHP の DTrace 静的プローブ
プローブ名 | プローブの説明 | プローブの引数 |
---|---|---|
request-startup
|
リクエスト開始時に発射されます。 | char *file , char *request_uri , char *request_method
|
request-shutdown
|
リクエスト・シャットダウン時に発射されます。 | char *file , char *request_uri , char *request_method
|
compile-file-entry
|
スクリプトのコンパイル開始時に発射されます。 | char *compile_file , char *compile_file_translated
|
compile-file-return
|
スクリプトのコンパイル終了時に発射されます。 | char *compile_file , char *compile_file_translated
|
execute-entry
|
op コードの配列が実行される際に発射されます。
例えば、関数の呼び出し、インクルードおよびジェネレータ続行時に発射されます。 |
char *request_file , int lineno
|
execute-return
|
op コードの配列の実行後に発射されます。 | char *request_file , int lineno
|
function-entry
|
PHP エンジンが、PHP の関数またはメソッドの呼び出しに入り込む際に発射されます。 | char *function_name , char *request_file , int lineno , char *classname , char *scope
|
function-return
|
PHP エンジンが、PHP の関数またはメソッドの呼び出しから戻る際に発射されます。 | char *function_name , char *request_file , int lineno , char *classname , char *scope
|
exception-thrown
|
例外がスローされる際に発射されます。 | char *classname
|
exception-caught
|
例外が捕捉される際に発射されます。 | char *classname
|
error
|
error_reporting レベルにかかわらず、
エラー発生時に発射されます。 |
char *errormsg , char *request_file , int lineno
|
PHP 拡張モジュールには、追加の静的プローブもあるかもしれません。
PHP の DTrace 静的プローブ一覧
使用できるプローブを一覧表示するには、 PHP プロセスを開始して以下のように実行します。
# dtrace -l
出力は以下のようになります。
ID PROVIDER MODULE FUNCTION NAME [ . . . ] 4 php15271 php dtrace_compile_file compile-file-entry 5 php15271 php dtrace_compile_file compile-file-return 6 php15271 php zend_error error 7 php15271 php ZEND_CATCH_SPEC_CONST_CV_HANDLER exception-caught 8 php15271 php zend_throw_exception_internal exception-thrown 9 php15271 php dtrace_execute_ex execute-entry 10 php15271 php dtrace_execute_internal execute-entry 11 php15271 php dtrace_execute_ex execute-return 12 php15271 php dtrace_execute_internal execute-return 13 php15271 php dtrace_execute_ex function-entry 14 php15271 php dtrace_execute_ex function-return 15 php15271 php php_request_shutdown request-shutdown 16 php15271 php php_request_startup request-startup
PROVIDER 列の値は、php
および
現在実行中の PHP プロセスのプロセス ID から構成されます。
Apache Web サーバーが実行中の場合、モジュール名は、例えば
libphp5.so
かもしれません。
そして、実行中の Apache プロセスごとに 1 つ、
一覧表の複数のブロックが存在するかもしれません。
FUNCTION 列は、各プロバイダが配置された PHP 内部の C 実装関数名を参照します。
PHP プロセスが実行されていない場合、PHP プローブは表示されません。
PHP についての DTrace の例
この例では、DTrace の D スクリプト言語の基本を示します。
例1
DTrace を使用してすべての PHP 静的プローブをトレースするためのall_probes.d
#!/usr/sbin/dtrace -Zs #pragma D option quiet php*:::compile-file-entry { printf("PHP compile-file-entry\n"); printf(" compile_file %s\n", copyinstr(arg0)); printf(" compile_file_translated %s\n", copyinstr(arg1)); } php*:::compile-file-return { printf("PHP compile-file-return\n"); printf(" compile_file %s\n", copyinstr(arg0)); printf(" compile_file_translated %s\n", copyinstr(arg1)); } php*:::error { printf("PHP error\n"); printf(" errormsg %s\n", copyinstr(arg0)); printf(" request_file %s\n", copyinstr(arg1)); printf(" lineno %d\n", (int)arg2); } php*:::exception-caught { printf("PHP exception-caught\n"); printf(" classname %s\n", copyinstr(arg0)); } php*:::exception-thrown { printf("PHP exception-thrown\n"); printf(" classname %s\n", copyinstr(arg0)); } php*:::execute-entry { printf("PHP execute-entry\n"); printf(" request_file %s\n", copyinstr(arg0)); printf(" lineno %d\n", (int)arg1); } php*:::execute-return { printf("PHP execute-return\n"); printf(" request_file %s\n", copyinstr(arg0)); printf(" lineno %d\n", (int)arg1); } php*:::function-entry { printf("PHP function-entry\n"); printf(" function_name %s\n", copyinstr(arg0)); printf(" request_file %s\n", copyinstr(arg1)); printf(" lineno %d\n", (int)arg2); printf(" classname %s\n", copyinstr(arg3)); printf(" scope %s\n", copyinstr(arg4)); } php*:::function-return { printf("PHP function-return\n"); printf(" function_name %s\n", copyinstr(arg0)); printf(" request_file %s\n", copyinstr(arg1)); printf(" lineno %d\n", (int)arg2); printf(" classname %s\n", copyinstr(arg3)); printf(" scope %s\n", copyinstr(arg4)); } php*:::request-shutdown { printf("PHP request-shutdown\n"); printf(" file %s\n", copyinstr(arg0)); printf(" request_uri %s\n", copyinstr(arg1)); printf(" request_method %s\n", copyinstr(arg2)); } php*:::request-startup { printf("PHP request-startup\n"); printf(" file %s\n", copyinstr(arg0)); printf(" request_uri %s\n", copyinstr(arg1)); printf(" request_method %s\n", copyinstr(arg2)); }
このスクリプトは、dtrace
に対して
-Z
オプションを使用します。
それにより、実行中の PHP プロセスがない場合に実行できるようになります。
もしこのオプションが書き落とされた場合、
モニターされているプローブがどれも存在しないことがわかっているので、
スクリプトは即座に終了します。
スクリプトは、PHP スクリプト実行中の期間全体にわたって、 すべてのコア PHP 静的プローブ・ポイントをトレースします。 D スクリプトを実行します。
# ./all_probes.d
PHP スクリプトまたはアプリケーションを実行します。 モニタリングの D スクリプトは、各プローブが発射されるたびに その引数を出力します。
モニタリングが完了した際には、^C
を使用して
D スクリプトを終わらせることができます。
マルチ CPU マシンでは、プローブの順序は規則的に連続して表示されないことがあります。 これは、どの CPU がプローブを処理し、 CPU の間をスレッドがどのように移動したかに依存します。 プローブのタイムスタンプを表示すると、 混乱を減らすことができます。 その例です。
php*:::function-entry { printf("%lld: PHP function-entry ", walltimestamp); [ . . .] }