PHP 및 DTrace 사용
PHP는 DTrace 동적 추적을 지원하는 플랫폼에서 DTrace 정적 프로브로 구성할 수 있습니다.
DTrace 정적 프로브를 위한 PHP 구성
운영 체제 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 정적 프로브
다음 정적 프로브는 PHP에서 사용할 수 있습니다.
Probe Name | Probe Description | Probe Arguments |
---|---|---|
request-startup |
Fires when a request starts. | char *file, char *request_uri, char *request_method |
request-shutdown |
Fires when a request shutdown. | char *file, char *request_uri, char *request_method |
compile-file-entry |
Fires when the compilation of a script starts. | char *compile_file, char *compile_file_translated |
compile-file-return |
Fires when the compilation of a script finishes. | char *compile_file, char *compile_file_translated |
execute-entry |
Fires when an opcode array is to be executed. For example, it fires on function calls, includes, and generator resumes. | char *request_file, int lineno |
execute-return |
Fires after execution of an opcode array. | char *request_file, int lineno |
function-entry |
Fires when the PHP engine enters a PHP function or method call. | char *function_name, char *request_file, int lineno, char *classname, char *scope |
function-return |
Fires when the PHP engine returns from a PHP function or method call. | char *function_name, char *request_file, int lineno, char *classname, char *scope |
exception-thrown |
Fires when an exception is thrown. | char *classname |
exception-caught |
Fires when an exception is caught. | char *classname |
error |
Fires when an error occurs, regardless of the error_reporting level. | 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 웹 서버가 실행 중인 경우 모듈 이름은 예를 들어 libphp5.so일 수 있으며 실행 중인 Apache 프로세스당 하나씩 여러 블록의 목록이 있을 수 있습니다.
함수 열은 각 공급자가 위치한 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); [ . . .] }