PHP конфигурируется со статическими зондами DTrace на платформах, которые поддерживают динамическую трассировку DTrace.
Обратитесь к документации платформы, чтобы включить поддержку DTrace в операционной системе. Например, в Oracle Linux требуется загрузить ядро UEK3 и сделать следующее:
# modprobe fasttrap
# chmod 666 /dev/dtrace/helper
Вместо chmod
доступен
пакет правил ACL для ограничения доступа для конкретного
пользователя.
Сборка PHP с ключом --enable-dtrace
:
# ./configure --enable-dtrace ...
# make
# make install
Это делает статические зонды доступными в ядре PHP. Любой модуль PHP, который предоставляет свои зонды, потребуется собрать отдельно как разделяемый модуль.
Установите переменную среды USE_ZEND_DTRACE=1 для целевых PHP-процессов, чтобы включить зонды.
Название зонда | Описание зонда | Аргументы зонда |
---|---|---|
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 |
Срабатывает, когда запускается массив байт-кода. К примеру, когда вызываются функции, возобновляется работа генератора или происходит include. | char *request_file, int lineno |
execute-return |
Срабатывает, после отработки массива байт-кода. | char *request_file, int lineno |
function-entry |
Срабатывает, когда движок PHP начинает запуск функции или метода. | char *function_name, char *request_file, int lineno, char *classname, char *scope |
function-return |
Срабатывает, когда движок 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 -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
и PID-идентификатор текущего запущенного PHP-процесса.
При работе веб-сервера Apache название модуля выводится как, например, libphp5.so, и выводятся серия блоков списка, по одному на каждый процесс Apache.
Колонка Function ссылается на название внутренней С-функции PHP, которая реализует соответствующий зонд.
Список не будет содержать зонды, которые связаны с PHP, если PHP не запустили.
Пример показывает базовые возможности скриптового языка DTrace D.
Пример #1 Скрипт all_probes.d — трассировка статических PHP-зондов через DTrace
#!/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)); }
Скрипт указывает опцию -Z
для команды dtrace, разрешая работать даже
если ни однин PHP-процесс не запущен. Без этой опции
скрипт сразу же завершит выполнение, поскольку
не увидит ни одного зонда, который требуется отслеживать.
Скрипт отслеживает каждый статический PHP-зонд на всём протяжении работы PHP-скрипта. Запускаем D-скрипт:
# ./all_probes.d
Запустите скрипт или PHP-приложение. Отслеживающий D-скрипт будет выводить аргументы каждого сработавшего зонда.
После получения информации работу скрипта прерывают комбинацией CTRL+C.
На многопроцессорных машинах порядок зондов непоследователен и зависит от процессоров, на которых работают зонды и как мигрируют потоки между процессорами. Отображение временных меток помогает избегать конфузов. К примеру:
php*:::function-entry { printf("%lld: PHP function-entry ", walltimestamp); [ . . .] }