В дистрибутивах Linux, в которых ядро поддерживает технологию eBPF, трассировщик bpftrace умеет подключаться к зондам PHP DTrace USDT без посредничества инструмента SystemTap.
Установите bpftrace через менеджер пакетов дистрибутива. Например, в Oracle Linux, RHEL или Fedora:
# dnf install bpftrace
# apt install bpftrace
Следующие примеры предполагают, что целевой исполняемый файл PHP установлен по пути /usr/bin/php.
Те же зонды USDT предоставляют и другие SAPI, которые собрали из того же дерева исходного кода,
поэтому целью зондов вместо этого выступает либо модуль Apache
(libphp.so), либо исполняемый файл диспетчера процессов FastCGI
(php-fpm); подставьте правильный
путь или подключитесь по PID-идентификатору через ключ -p при необходимости.
Убедитесь, что собрали целевой исполняемый файл с поддержкой фреймворка DTrace и что правильно настроили переменные окружения. Подробности описывает раздел Конфигурирование PHP со статическими зондами DTrace.
Статические зонды PHP выводит команда bpftrace:
# bpftrace -l 'usdt:/usr/bin/php:php:*'
Команда выводит:
usdt:/usr/bin/php:php:compile__file__entry usdt:/usr/bin/php:php:compile__file__return usdt:/usr/bin/php:php:error usdt:/usr/bin/php:php:exception__caught usdt:/usr/bin/php:php:exception__thrown usdt:/usr/bin/php:php:execute__entry usdt:/usr/bin/php:php:execute__return usdt:/usr/bin/php:php:function__entry usdt:/usr/bin/php:php:function__return usdt:/usr/bin/php:php:request__shutdown usdt:/usr/bin/php:php:request__startup
Пример #1 Скрипт all_probes.bt — трассировка всех статических PHP-зондов через bpftrace
#!/usr/bin/env bpftrace
usdt:/usr/bin/php:php:compile__file__entry
{
printf("Probe compile__file__entry\n");
printf(" compile_file %s\n", str(arg0));
printf(" compile_file_translated %s\n", str(arg1));
}
usdt:/usr/bin/php:php:compile__file__return
{
printf("Probe compile__file__return\n");
printf(" compile_file %s\n", str(arg0));
printf(" compile_file_translated %s\n", str(arg1));
}
usdt:/usr/bin/php:php:error
{
printf("Probe error\n");
printf(" errormsg %s\n", str(arg0));
printf(" request_file %s\n", str(arg1));
printf(" lineno %d\n", (int32)arg2);
}
usdt:/usr/bin/php:php:exception__caught
{
printf("Probe exception__caught\n");
printf(" classname %s\n", str(arg0));
}
usdt:/usr/bin/php:php:exception__thrown
{
printf("Probe exception__thrown\n");
printf(" classname %s\n", str(arg0));
}
usdt:/usr/bin/php:php:execute__entry
{
printf("Probe execute__entry\n");
printf(" request_file %s\n", str(arg0));
printf(" lineno %d\n", (int32)arg1);
}
usdt:/usr/bin/php:php:execute__return
{
printf("Probe execute__return\n");
printf(" request_file %s\n", str(arg0));
printf(" lineno %d\n", (int32)arg1);
}
usdt:/usr/bin/php:php:function__entry
{
printf("Probe function__entry\n");
printf(" function_name %s\n", str(arg0));
printf(" request_file %s\n", str(arg1));
printf(" lineno %d\n", (int32)arg2);
printf(" classname %s\n", str(arg3));
printf(" scope %s\n", str(arg4));
}
usdt:/usr/bin/php:php:function__return
{
printf("Probe function__return\n");
printf(" function_name %s\n", str(arg0));
printf(" request_file %s\n", str(arg1));
printf(" lineno %d\n", (int32)arg2);
printf(" classname %s\n", str(arg3));
printf(" scope %s\n", str(arg4));
}
usdt:/usr/bin/php:php:request__shutdown
{
printf("Probe request__shutdown\n");
printf(" file %s\n", str(arg0));
printf(" request_uri %s\n", str(arg1));
printf(" request_method %s\n", str(arg2));
}
usdt:/usr/bin/php:php:request__startup
{
printf("Probe request__startup\n");
printf(" file %s\n", str(arg0));
printf(" request_uri %s\n", str(arg1));
printf(" request_method %s\n", str(arg2));
}
Приведённый скрипт трассирует все статические зонды ядра PHP на всём протяжении работы PHP-скрипта. Трассировщику bpftrace требуются привилегии суперпользователя:
# USE_ZEND_DTRACE=1 bpftrace -c '/usr/bin/php test.php' all_probes.bt
Для трассировки уже запущенного PHP-процесса, например, рабочего процесса php-fpm или процесса Apache, который загрузил библиотеку libphp.so, подключитесь по PID:
# bpftrace -p $PID all_probes.bt
usdt: потребуется указать цель — путь до исполняемого файла
запущенного процесса: usdt:/usr/bin/php;
замените путь в строке спецификации зонда на путь до исполняемого файла php-fpm
или библиотеки libphp.so, если потребуется.