## Usando PHP y DTrace

PHP puede ser configurado con sondas estáticas DTrace en plataformas que soportan Rastreo Dinámico DTrace.

### Configurando PHP para Sondas Estáticas DTrace

Refierase a la documentación externa específica par su plataforma para habilitar el soporte para rastreo DTrace en el sistema operativo. Por ejemplo, en Oracle Linux arranque con un kernel UEK3 y haga:

`# modprobe fasttrap
# chmod 666 /dev/dtrace/helper`

En lugar de utilizar `chmod`, usted podria utilizar una regla de paquete ACL para limitar acceso a los dispositivos a ciertos usuarios.

Compile PHP con el parámetro de configuración `--enable-dtrace`:

`# ./configure --enable-dtrace ...
# make
# make install`

Esto habilita las sondas estáticas en el núcleo de PHP. Cualquiera de las extensiones que ofrezcan sus propios sondeos deberán ser compiladas de forma separada como extensiones compartidas.

### Sondeos Estáticos DTrace en el núcleo de PHP

Los siguientes sondeos estáticos están disponibles en PHP
Nombre del Sondeo | Descripción del Sondeo | Argumentos del Sondeo
--- | --- | ---
`request-startup` | Se dispara cuando comienza una petición. | char *file, char *request_uri, char *request_method
`request-shutdown` | Se dispara cuando se termina una petición. | char *file, char *request_uri, char *request_method
`compile-file-entry` | Se dispara cuando la compilación de un script comienza. | char *compile_file, char *compile_file_translated
`compile-file-return` | Se dispara cuando la compilación de un script termina. | char *compile_file, char *compile_file_translated
`execute-entry` | Se dispara cuando un código de operación array está por ser ejecutado. Por ejemplo, se dispara en llamadas a funciones, includes, y continuaciones de resumes. | char *request_file, int lineno
`execute-return` | Se dispara después de la ejecución de un código de operación array. | char *request_file, int lineno
`function-entry` | Se dispara cuando el motor de PHP entra a la llamada de una función o método. | char *function_name, char *request_file, int lineno, char *classname, char *scope
`function-return` | Se dispara cuando el motor de PHP regresa de la llamada a una función o método. | char *function_name, char *request_file, int lineno, char *classname, char *scope
`exception-thrown` | Se dispara cuando una excepción es lanzada. | char *classname
`exception-caught` | Se dispara cuando una excepción es capturada. | char *classname
`error` | Se dispara cuando ocurre un error, sin importar el nivel de error_reporting. | char *errormsg, char *request_file, int lineno

Otras extensiones PHP pueden también tener otras sondas estáticas adicionales.

### Listando Sondas Estáticas DTrace en PHP

Para listar todas las sondas disponibles, inicie un proceso PHP y ejecute:

    # dtrace -l

La salida 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

La columna Proveedor consiste en `php` y el id del proceso del proceso PHP que está ejecutandose.

Si el servidor web Apache está corriendo, el nombre del módulo será, por ejemplo, libphp5.so, y habría múltiples bloques de listado, uno por cada proceso Apache ejecutandose.

La columna Función se refiere los nombres internos de función de su implementación en C, donde cada proveedor está ubicado.

Si un proceso PHP no está ejecutandose, entonces ningún sondeo será mostrado.

### DTrace con un ejemplo PHP

Este ejemplo muestra los conceptos básicos del lenguaje de scripting DTrace D.

Ejemplo #1 all_probes.d para monitorizar todos los Śondeos Estáticos en 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` en dtrace, permitiendo que se ejecute aún cuando no hay procesos PHP ejecutandose. Si esta opción se hubiese omitido el script hubiese terminado inmediatamente porque no sabría que los sondeos a ser monitorizados realmente son válidos.

Este script rastrea todas las sondas estáticas del núcleo de PHP y puntos de muestreo a lo largo de la duración de un script PHP que esté corriendo:

    # ./all_probes.d

Ejecuta un script o aplicación PHP. El script D de monitorización mostrará los argumentos de cada sondeo según vayan sucediendo.

Cuando la monitorización está completada, el script D puede ser terminado con `^C`.

En máquinas con múltiples-CPU el orden de los sondeos podría no aparecer secuencialmente. Esto depende de en que CPU fue procesado, y como los hilos se mueven a través de las CPUs. Mostrar la fecha y hora del sondeo ayudará a reducir la confusión, por ejemplo:

    php*:::function-entry
    {
          printf("%lld: PHP function-entry ", walltimestamp);
          [ . . .]
    }

### Vea también

- OCI8 y Rastreo Dinámico DTrace