Usando PHP e DTrace
O PHP pode ser configuracom com sensores estáticos do DTrace em plataformas que suportam a Instrumentação Dinâmica do DTrace.
Configurando o PHP para Sensores Estáticos DTrace
Refira-se à documentação externa específica da plataforma para habilitar o suporte do DTrace no sistema operacional. Por exemplo, no Oracle Linux inicialize um kernel UEK3 e rode os seguintes comandos:
# modprobe fasttrap
# chmod 666 /dev/dtrace/helper
Ao invés de usar chmod
, pode-se alternativamente usar uma
regra de pacote ACL para limitar o acesso a um dispositivo para um usuário específico.
Construa o PHP com o parâmetro de configuração --enable-dtrace
:
# ./configure --enable-dtrace ...
# make
# make install
Isto habilita sensores estáticos no núcleo do PHP. Quaisquer extensões PHP que fornecem seus próprios sensores devem ser construídas separadamente como extensões compartilhadas.
Sensores Estáticos DTrace no Núcleo do PHP
Nome do Sensor | Descrição do Sensor | Argumentos do Sensor |
---|---|---|
request-startup |
Dispara quando uma requisição inicia. | char *file, char *request_uri, char *request_method |
request-shutdown |
Dispara quando uma requisição termina. | char *file, char *request_uri, char *request_method |
compile-file-entry |
Dispara quando a compilação de um script inicia. | char *compile_file, char *compile_file_translated |
compile-file-return |
Dispara quando a compilação de um script termina. | char *compile_file, char *compile_file_translated |
execute-entry |
Dispara quando um array de opcode está para ser executado. Por exemplo, ele dispara em chamadas de função, de includes e em continuação de geradores. | char *request_file, int lineno |
execute-return |
Dispara depois da execução de um array de opcode. | char *request_file, int lineno |
function-entry |
Dispara quando o motor do PHP entra em uma chamada de função ou método. | char *function_name, char *request_file, int lineno, char *classname, char *scope |
function-return |
Dispara quando o motor do PHP retorna de uma chamada de função ou método. | char *function_name, char *request_file, int lineno, char *classname, char *scope |
exception-thrown |
Dispara quando uma exceção é disparada. | char *classname |
exception-caught |
Dispara quando uma exceção é capturada. | char *classname |
error |
Dispara quando um erro ocorre, independente do nível de error_reporting. | char *errormsg, char *request_file, int lineno |
Extensões de PHP podem também conter sensores estáticos adicionais.
Listando os Sensores Estáticos DTrace no PHP
Para listar os sensores disponíveis, inicie um processo PHP e então execute:
# dtrace -l
A saída será similar a:
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
Os valores da coluna Provider consistem de php
mais o id
do processo PHP sendo executado.
Se o servidor web Apache estiver rodando, o módulo poderia ser, por exemplo, libphp5.so, e haveria múltiplos blocos de listagens, um para cada processo Apache em execução.
A coluna Function refere-se aos nomes das funções da implementação interna do PHP, em C, onde cada fornecedor está localizado.
Se um processo PHP não estiver em execução, então nenhum sensor PHP será mostrado.
Exemplo de DTrace com PHP
Este exemplo mostra o básico da linguagem D de scripts DTrace.
Example #1 Arquivo all_probes.d para instrumentar todos os Sensores Estáticos PHP com 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)); }
Este script usa a opção -Z
para a aplicação
dtrace, permitindo que ela seja executada quando não
há processo PHP em execução. Se esta opção fosse omitida, o script
iria terminar imediatamente porque ele saberia que nenhum dos sensores
a serem monitorados existiriam.
O script instrumenta todos os pontos de sensores estáticos do núcleo do PHP durante toda a duração de um script PHP em execução. Execute o script D:
# ./all_probes.d
Executa um script PHP ou aplicação. O script D de monitoramento terá como saída os argumentos de cada um dos sensores quando for disparado.
Quando o monitoramento estiver completo, o script D pode ser terminado com CTRL+C.
Em máquinas com múltiplas CPUs, pode parecer que os sensor estão em ordem não sequencial. Isto depende de qual CPU está processando os sensores, e como as threads migram atráves dos CPUs. Mostrar os timestamps dos sensores irá ajudar a reduzir a confusão, por exemplo:
php*:::function-entry { printf("%lld: PHP function-entry ", walltimestamp); [ . . .] }