Em distribuições Linux com um kernel que suporta eBPF, o utilitário bpftrace pode se conectar diretamente às sondas USDT DTrace do PHP, sem precisar do SystemTap.
Instale o bpftrace usando o gerenciador de pacotes da distribuição. Por exemplo, no Oracle Linux, RHEL ou Fedora:
# dnf install bpftrace
# apt install bpftrace
Os exemplos abaixo assumem que o binário PHP alvo está instalado em /usr/bin/php.
As mesmas sondas USDT também são expostas por outras SAPIs construídas a partir da mesma árvore de fontes, então o
alvo da sonda pode ser, ao invés disso, o módulo do Apache
(libphp.so) ou o binário do FastCGI Process Manager
(php-fpm); substitua o caminho
apropriado ou conecte-se pelo PID com -p conforme necessário.
Certifique-se de que o binário alvo foi construído com o DTrace e que a variável de ambiente está configurado corretamente. Veja Configurando o PHP para Sondas Estáticas DTrace para detalhes.
As sondas estáticas do PHP podem ser listadas usando bpftrace:
# bpftrace -l 'usdt:/usr/bin/php:php:*'
A saída é:
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
Exemplo #1 all_probes.bt para instrumentação de todas as Sondas Estáticas do PHP com 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));
}
O script acima irá instrumentar todos os pontos de sondas estáticas do núcleo do PHP durante toda a duração de um script PHP em execução. O bpftrace requer privilégios de root:
# USE_ZEND_DTRACE=1 bpftrace -c '/usr/bin/php test.php' all_probes.bt
Para instrumentar um processo PHP já em execução (por exemplo, um worker do php-fpm ou um processo Apache carregando libphp.so), conecte-se pelo PID:
# bpftrace -p $PID all_probes.bt
usdt: no script deve corresponder ao binário do
processo em execução; ajuste usdt:/usr/bin/php para o
binário do php-fpm ou para libphp.so conforme apropriado.