PHP puede ser configurado con las sondas estáticas DTrace en las plataformas que soportan el traçado dinámico DTrace.
Consulte la documentación específica de la plataforma externa para habilitar el soporte de DTrace del sistema operativo DTrace. Por ejemplo, en Oracle Linux inicie un núcleo UEK3 y haga :
# modprobe fasttrap
# chmod 666 /dev/dtrace/helper
En lugar de usar chmod
, puede usar una regla de paquetado
ACL para limitar el acceso al dispositivo a un usuario específico.
Construir PHP con el parámetro de configuración --enable-dtrace
:
# ./configure --enable-dtrace ...
# make
# make install
Esto hace que las sondas estáticas estén disponibles en el núcleo de PHP. Todas las extensiones PHP que proporcionen sus propias sondas deben ser construidas por separado como extensiones compartidas.
Para habilitar las sondas, definir la variable de entorno USE_ZEND_DTRACE=1 a los procesos PHP objetivo.
Nombre de la sonde | Descripción de la sonde | Argumentos de la sonde |
---|---|---|
request-startup |
Se dispara cuando una petición comienza. | char *file, char *request_uri, char *request_method |
request-shutdown |
Se dispara cuando una petición se detiene. | char *file, char *request_uri, char *request_method |
compile-file-entry |
Se dispara cuando comienza la compilación de un script. | char *compile_file, char *compile_file_translated |
compile-file-return |
Se dispara cuando termina la compilación de un script. | char *compile_file, char *compile_file_translated |
execute-entry |
Se dispara cuando un array de opcodes debe ser ejecutado. Por ejemplo, se dispara en llamadas de función, inclusiones y reanudaciones de generador. | char *request_file, int lineno |
execute-return |
Se dispara después de la ejecución de un array de opcodes. | char *request_file, int lineno |
function-entry |
Se dispara cuando el motor de PHP entra en una función PHP o una llamada de método. | char *function_name, char *request_file, int lineno, char *classname, char *scope |
function-return |
Se dispara cuando el motor PHP regresa de una función PHP o una llamada de método. | char *function_name, char *request_file, int lineno, char *classname, char *scope |
exception-thrown |
Se dispara cuando se lanza una excepción. | char *classname |
exception-caught |
Se dispara cuando se captura una excepción. | char *classname |
error |
Se dispara cuando ocurre un error, independientemente del nivel de error_reporting. | char *errormsg, char *request_file, int lineno |
Las extensiones PHP también pueden disponer de sondas estáticas adicionales.
Para listar las sondas disponibles, inicie un proceso PHP y luego ejecute :
# dtrace -l
El resultado será similar al siguiente :
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
Los valores de la columna Provider son php
y
el identificador del proceso PHP en ejecución.
Si el servidor web Apache está en ejecución, el nombre del módulo podría ser, por ejemplo, libphp5.so, y habría varios bloques de listas, uno por cada proceso Apache en ejecución.
La columna Función hace referencia a la implementación interna en C de PHP, donde se encuentra cada proveedor.
Si no hay un proceso PHP en ejecución, no se mostrará ninguna sonde PHP.
Este ejemplo muestra los fundamentos del lenguaje de script DTrace D.
Ejemplo #1 all_probes.d para trazar todas las sondas estáticas PHP con 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 utiliza la opción -Z
de
dtrace, lo que le permite ejecutarse cuando no hay
ningún proceso PHP en ejecución. Si se omitiera esta opción, el script
terminaría inmediatamente porque sabe que ninguna de las sondas a
monitorear existe.
El script traza todos los puntos de sondeo estáticos de PHP durante la duración de un script PHP en ejecución. Ejecute el script D :
# ./all_probes.d
Ejecute un script o una aplicación PHP. El script D de monitoreo mostrará los argumentos de cada sonde a medida que se dispare.
Cuando el monitoreo haya terminado, el script D puede ser interrumpido con un comando CTRL+C
En máquinas multi-CPU, el orden de las sondas puede no ser secuencial. Esto depende del CPU que ha procesado las sondas, y de cómo los hilos migran de un CPU a otro. La visualización de los timestamps de las sondas permite reducir la confusión, por ejemplo :
php*:::function-entry { printf("%lld: PHP function-entry ", walltimestamp); [ . . .] }