1
0
mirror of https://github.com/php/doc-es.git synced 2026-03-23 23:12:09 +01:00
Files
archived-doc-es/features/dtrace.xml
2025-10-24 14:40:15 -05:00

563 lines
20 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: d35d7d811ccf7662eefe4f23ff1cabc727a917ca Maintainer: PhilDaiguille Status: ready -->
<!-- Reviewed: yes Maintainer: Marqitos -->
<chapter xml:id="features.dtrace" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Rastreo dinámico de DTrace</title>
<sect1 xml:id="features.dtrace.introduction">
<title>Introducción a PHP y DTrace</title>
<para>
DTrace es un framework de rastreo siempre disponible, a bajo costo,
disponible en varias plataformas, incluyendo Solaris, macOS,
Oracle Linux y BSD. DTrace puede rastrear el comportamiento del sistema operativo
y la ejecución de programas de usuario. Puede mostrar los valores de los argumentos y ser
utilizado para deducir estadísticas de rendimiento. Las sondas son controladas por scripts
creados por el usuario y escritos en el lenguaje de script DTrace D. Esto
permite un análisis eficiente de los puntos de datos.
</para>
<para>
Las sondas PHP que no son activamente monitoreadas por el script DTrace
D del usuario no contienen código instrumentado, por lo que
no hay degradación del rendimiento durante la ejecución normal de la aplicación.
Las sondas que son monitoreadas tienen un costo de funcionamiento bastante bajo para
generalmente permitir la supervisión de DTrace en sistemas de producción.
</para>
<para>
PHP incorpora sondas de "Rastreo Estático Definido por el Usuario" (USDT)
que se disparan en el momento de la ejecución. Por ejemplo, cuando un script D
monitorea la sonda <literal>function-entry</literal> de PHP, entonces,
cada vez que se llama a una función del script PHP, esta sonda se dispara y
el código de acción del script D asociado se ejecuta. Este código de acción
podría, por ejemplo, imprimir los argumentos de la sonda como la ubicación del fichero
fuente de la función PHP. La acción también puede agrupar datos
como el número de veces que se llama a cada función.
</para>
<para>
Solo se describen aquí las sondas PHP USDT. Consulte la documentación externa
general y específica del sistema operativo para ver cómo
DTrace puede ser utilizado para trazar funciones arbitrarias, y cómo puede ser utilizado
para trazar el comportamiento del sistema operativo. Tenga en cuenta que no todas las funcionalidades
de DTrace están disponibles en todas las implementaciones de DTrace.
</para>
<para>
Las sondas DTrace estáticas en PHP pueden alternativamente ser utilizadas con la función
SystemTap en ciertas distribuciones Linux.
</para>
</sect1>
<sect1 xml:id="features.dtrace.dtrace">
<title>Usar PHP y DTrace</title>
<para>
PHP puede ser configurado con las sondas estáticas DTrace en las plataformas
que soportan el rastreo dinámico DTrace.
</para>
<sect2 xml:id="features.dtrace.install">
<title>Configurar PHP para las sondas estáticas de DTrace</title>
<para>
Consulte la documentación específica de la plataforma externa para habilitar
el soporte de DTrace del sistema operativo. Por ejemplo, en Oracle Linux
inicie un núcleo UEK3 y haga:
<informalexample>
<programlisting role="php">
<![CDATA[
# modprobe fasttrap
# chmod 666 /dev/dtrace/helper
]]>
</programlisting>
</informalexample>
</para>
<para>
En lugar de usar <literal>chmod</literal>, puede usar una regla de paquetado
ACL para limitar el acceso al dispositivo a un usuario específico.
</para>
<para>
Construir PHP con el parámetro de configuración <literal>--enable-dtrace</literal>:
<informalexample>
<programlisting role="php">
<![CDATA[
# ./configure --enable-dtrace ...
# make
# make install
]]>
</programlisting>
</informalexample>
</para>
<para>
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>
<para>
Para habilitar las sondas, definir la variable de entorno <option>USE_ZEND_DTRACE=1</option> a los procesos PHP objetivo.
</para>
</sect2>
<sect2 xml:id="features.dtrace.static-probes">
<title>Sondas estáticas DTrace en el núcleo de PHP</title>
<table>
<title>Las siguientes sondas estáticas están disponibles en PHP</title>
<tgroup cols="2">
<thead>
<row>
<entry>Nombre de la sonda</entry>
<entry>Descripción de la sonda</entry>
<entry>Argumentos de la sonda</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>request-startup</literal></entry>
<entry>Se dispara cuando una petición comienza.</entry>
<entry>char *<varname>file</varname>, char *<varname>request_uri</varname>, char *<varname>request_method</varname></entry>
</row>
<row>
<entry><literal>request-shutdown</literal></entry>
<entry>Se dispara cuando una petición se detiene.</entry>
<entry>char *<varname>file</varname>, char *<varname>request_uri</varname>, char *<varname>request_method</varname></entry>
</row>
<row>
<entry><literal>compile-file-entry</literal></entry>
<entry>Se dispara cuando comienza la compilación de un script.</entry>
<entry>char *<varname>compile_file</varname>, char *<varname>compile_file_translated</varname></entry>
</row>
<row>
<entry><literal>compile-file-return</literal></entry>
<entry>Se dispara cuando termina la compilación de un script.</entry>
<entry>char *<varname>compile_file</varname>, char *<varname>compile_file_translated</varname></entry>
</row>
<row>
<entry><literal>execute-entry</literal></entry>
<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.</entry>
<entry>char *<varname>request_file</varname>, int <varname>lineno</varname></entry>
</row>
<row>
<entry><literal>execute-return</literal></entry>
<entry>Se dispara después de la ejecución de un array de opcodes.</entry>
<entry>char *<varname>request_file</varname>, int <varname>lineno</varname></entry>
</row>
<row>
<entry><literal>function-entry</literal></entry>
<entry>Se dispara cuando el motor de PHP entra en una función PHP o una llamada de método.</entry>
<entry>char *<varname>function_name</varname>, char *<varname>request_file</varname>, int <varname>lineno</varname>, char *<varname>classname</varname>, char *<varname>scope</varname></entry>
</row>
<row>
<entry><literal>function-return</literal></entry>
<entry>Se dispara cuando el motor PHP regresa de una función PHP o una llamada de método.</entry>
<entry>char *<varname>function_name</varname>, char *<varname>request_file</varname>, int <varname>lineno</varname>, char *<varname>classname</varname>, char *<varname>scope</varname></entry>
</row>
<row>
<entry><literal>exception-thrown</literal></entry>
<entry>Se dispara cuando se lanza una excepción.</entry>
<entry>char *<varname>classname</varname></entry>
</row>
<row>
<entry><literal>exception-caught</literal></entry>
<entry>Se dispara cuando se captura una excepción.</entry>
<entry>char *<varname>classname</varname></entry>
</row>
<row>
<entry><literal>error</literal></entry>
<entry>Se dispara cuando ocurre un error, independientemente del nivel de <link linkend="ini.error-reporting">error_reporting</link>.</entry>
<entry>char *<varname>errormsg</varname>, char *<varname>request_file</varname>, int <varname>lineno</varname></entry>
</row>
</tbody>
</tgroup>
</table>
<para>
Las extensiones PHP también pueden disponer de sondas estáticas adicionales.
</para>
</sect2>
<sect2 xml:id="features.dtrace.list-probes">
<title>Lista de sondas estáticas DTrace de PHP</title>
<para>
Para listar las sondas disponibles, inicie un proceso PHP y luego ejecute:
<informalexample>
<programlisting>
<![CDATA[
# dtrace -l
]]>
</programlisting>
</informalexample>
</para>
<para>
El resultado será similar al siguiente:
<informalexample>
<programlisting>
<![CDATA[
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
]]>
</programlisting>
</informalexample>
</para>
<para>
Los valores de la columna Provider son <literal>php</literal> y
el identificador del proceso PHP en ejecución.
</para>
<para>
Si el servidor web Apache está en ejecución, el nombre del módulo podría ser,
por ejemplo, <filename>libphp5.so</filename>, y habría
varios bloques de listas, uno por cada proceso Apache en ejecución.
</para>
<para>
La columna Función hace referencia a la implementación interna en C
de PHP, donde se encuentra cada proveedor.
</para>
<para>
Si no hay un proceso PHP en ejecución, no se mostrará ninguna sonda PHP.
</para>
</sect2>
<sect2 xml:id="features.dtrace.examples">
<title>DTrace con un ejemplo PHP</title>
<para>
Este ejemplo muestra los fundamentos del lenguaje de script DTrace D.
<example>
<title><filename>all_probes.d</filename> para trazar todas las sondas estáticas PHP con DTrace</title>
<programlisting>
<![CDATA[
#!/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));
}
]]>
</programlisting>
</example>
</para>
<para>
Este script utiliza la opción <literal>-Z</literal> de
<filename>dtrace</filename>, 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.
</para>
<para>
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:
<informalexample>
<programlisting>
<![CDATA[
# ./all_probes.d
]]>
</programlisting>
</informalexample>
</para>
<para>
Ejecute un script o una aplicación PHP. El script D de monitoreo
mostrará los argumentos de cada sonda a medida que se dispare.
</para>
<para>
Cuando el monitoreo haya terminado, el script D puede ser interrumpido con un
<keycombo action='simul'><keycap>CTRL</keycap><keycap>C</keycap></keycombo>
</para>
<para>
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 :
<informalexample>
<programlisting>
<![CDATA[
php*:::function-entry
{
printf("%lld: PHP function-entry ", walltimestamp);
[ . . .]
}
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="features.dtrace.references">
&reftitle.seealso;
<simplelist>
<member><link linkend="oci8.dtrace">OCI8 y el rastreo dinámico DTrace</link></member>
</simplelist>
</sect2>
</sect1>
<sect1 xml:id="features.dtrace.systemtap">
<title>Usar SystemTap con las sondas estáticas DTrace de PHP</title>
<para>
En ciertas distribuciones Linux, la utilidad de rastreo SystemTap puede
ser utilizada para trazar las sondas estáticas DTrace de PHP. Esto está disponible con
PHP 5.4.20 y PHP 5.5.
</para>
<sect2 xml:id="features.dtrace.systemtap-install">
<title>Instalar PHP con SystemTap</title>
<para>
Instale el paquete de desarrollo SDT de SystemTap:
<informalexample>
<programlisting role="shell">
<![CDATA[
# yum install systemtap-sdt-devel
]]>
</programlisting>
</informalexample>
</para>
<para>
Instalar PHP con las sondas DTrace habilitadas:
<informalexample>
<programlisting role="shell">
<![CDATA[
# ./configure --enable-dtrace ...
# make
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="features.dtrace.systemtap-list-probes">
<title>Lista de sondas estáticas con SystemTap</title>
<para>
Las sondas estáticas en PHP pueden ser listadas utilizando <filename>stap</filename>:
<informalexample>
<programlisting>
<![CDATA[
# stap -l 'process.provider("php").mark("*")' -c 'sapi/cli/php -i'
]]>
</programlisting>
</informalexample>
</para>
<para>
Esto produce:
<informalexample>
<programlisting>
<![CDATA[
process("sapi/cli/php").provider("php").mark("compile__file__entry")
process("sapi/cli/php").provider("php").mark("compile__file__return")
process("sapi/cli/php").provider("php").mark("error")
process("sapi/cli/php").provider("php").mark("exception__caught")
process("sapi/cli/php").provider("php").mark("exception__thrown")
process("sapi/cli/php").provider("php").mark("execute__entry")
process("sapi/cli/php").provider("php").mark("execute__return")
process("sapi/cli/php").provider("php").mark("function__entry")
process("sapi/cli/php").provider("php").mark("function__return")
process("sapi/cli/php").provider("php").mark("request__shutdown")
process("sapi/cli/php").provider("php").mark("request__startup")
]]>
</programlisting>
</informalexample>
</para>
</sect2>
<sect2 xml:id="features.dtrace.systemtap-examples">
<title>SystemTap con un Ejemplo PHP</title>
<para>
<example>
<title><filename>all_probes.stp</filename> para trazar todas las sondas estáticas PHP con SystemTap</title>
<programlisting role="shell">
<![CDATA[
probe process("sapi/cli/php").provider("php").mark("compile__file__entry") {
printf("Probe compile__file__entry\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("compile__file__return") {
printf("Probe compile__file__return\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("error") {
printf("Probe error\n");
printf(" errormsg %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
}
probe process("sapi/cli/php").provider("php").mark("exception__caught") {
printf("Probe exception__caught\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("exception__thrown") {
printf("Probe exception__thrown\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("execute__entry") {
printf("Probe execute__entry\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("execute__return") {
printf("Probe execute__return\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("function__entry") {
printf("Probe function__entry\n");
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("function__return") {
printf("Probe function__return: %s\n", user_string($arg1));
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("request__shutdown") {
printf("Probe request__shutdown\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
probe process("sapi/cli/php").provider("php").mark("request__startup") {
printf("Probe request__startup\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
]]>
</programlisting>
</example>
</para>
<para>
El script anterior trazará todos los puntos de sondeo estáticos de PHP
durante toda la duración de la ejecución de un script PHP:
<informalexample>
<programlisting>
<![CDATA[
# stap -c 'sapi/cli/php test.php' all_probes.stp
]]>
</programlisting>
</informalexample>
</para>
</sect2>
</sect1>
</chapter>
<!-- Keep this comment at the end of the file
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->