Crear extensiones para Tracy
Tracy es una gran herramienta para depurar su aplicación. A veces, sin embargo, puede querer tener a mano información adicional. Le mostraremos cómo escribir sus propias extensiones para la Tracy Bar y hacer el desarrollo aún más agradable.
- Crear su propio panel para la Tracy Bar
- Crear su propia extensión para la Bluescreen
Encontrará un repositorio de extensiones ya hechas para Tracy en Componette.
Extensiones de la Tracy Bar
Crear una nueva extensión para la Tracy Bar es sencillo. Cree un objeto que implemente la interfaz
Tracy\IBarPanel, que tiene dos métodos: getTab() y getPanel(). Estos métodos deben
devolver el código HTML de la pestaña (una pequeña etiqueta que se muestra directamente en la Bar) y del panel (una ventana
emergente que se muestra al pulsar la pestaña). Si getPanel() no devuelve nada, se muestra solo la pestaña. Si
getTab() no devuelve nada, no se muestra nada en absoluto y getPanel() no se llama.
class ExamplePanel implements Tracy\IBarPanel
{
public function getTab()
{
return /* ... */;
}
public function getPanel()
{
return /* ... */;
}
}
Registro
El registro se hace llamando a Tracy\Debugger::getBar()->addPanel():
Tracy\Debugger::getBar()->addPanel(new ExamplePanel);
Alternativamente puede registrar el panel directamente en la configuración de la aplicación:
tracy:
bar:
- ExamplePanel
Código HTML de la pestaña
Debería tener más o menos este aspecto:
<span title="Explanatory tooltip">
<svg>...</svg>
<span class="tracy-label">Title</span>
</span>
La imagen debería estar en formato SVG. Si no hace falta un tooltip explicativo, se puede omitir el <span>
exterior.
Código HTML del panel
Debería tener más o menos este aspecto:
<h1>Title</h1>
<div class="tracy-inner">
<div class="tracy-inner-container">
... content ...
</div>
</div>
El título debería ser el mismo que el de la pestaña o contener información adicional.
Tenga presente que una misma extensión se puede registrar varias veces, quizá con ajustes distintos. Por eso, para los
estilos no puede usar IDs de CSS, solo clases, preferiblemente con el formato
tracy-addons-<NombreDeClase>[-<opcional>]. Añada esa clase al div junto con la clase
tracy-inner. Al escribir CSS conviene anteponer a los selectores #tracy-debug .su-clase, porque eso le
da a la regla mayor especificidad que a los estilos del reset.
Estilos predeterminados
En el panel, los elementos <a>, <table>, <pre> y
<code> tienen estilos predefinidos. Si quiere crear un enlace que oculte y muestre otro elemento, conéctelos
con los atributos href e id y la clase tracy-toggle:
<a href="#tracy-addons-ClassName-{$counter}" class="tracy-toggle">Details</a>
<div id="tracy-addons-ClassName-{$counter}">...</div>
Si el estado predeterminado es colapsado, añada la clase tracy-collapsed a ambos elementos.
Use un contador estático para evitar IDs duplicados en una misma página.
Recursos propios
Si su panel necesita su propia hoja de estilos o su propio script, puede hacer que Tracy cargue archivos adicionales junto con los suyos:
Tracy\Debugger::$customCssFiles[] = __DIR__ . '/panel.css';
Tracy\Debugger::$customJsFiles[] = __DIR__ . '/panel.js';
Soporte para agentes de IA
Cuando un agente de IA maneja el navegador, Tracy envía a la consola de JS un resumen en markdown de la Tracy Bar. Los paneles
propios pueden aportar su propio markdown añadiendo un método getAgentInfo(): ?string a su implementación de
IBarPanel:
class DatabasePanel implements Tracy\IBarPanel
{
public function getTab(): string { /* ... */ }
public function getPanel(): string { /* ... */ }
public function getAgentInfo(): ?string
{
return "## Database\n\n- Queries: {$this->count}\n- Total time: {$this->time} ms\n";
}
}
El markdown devuelto se incluye en el resumen en markdown de la barra. Cuando el método falta o devuelve null,
el panel se omite del resumen.
Véase la integración de Tracy con los agentes de IA para el panorama completo.
Extensiones de la Bluescreen
De esta manera puede añadir visualizaciones propias de las excepciones o paneles que aparecerán en la bluescreen.
Una extensión se crea así:
Tracy\Debugger::getBlueScreen()->addPanel(function (?Throwable $e) { // excepción capturada
return [
'tab' => '...Title...',
'panel' => '...HTML panel content...',
];
});
La función se llama dos veces. Primero se pasa la propia excepción en el parámetro $e (si se produjo alguna) y
el panel devuelto se renderiza al principio de la página. Si devuelve null o un array vacío, el panel no se
renderiza. Después se llama con $e = null y el panel devuelto se renderiza debajo de la pila de llamadas. Si la
función devuelve 'bottom' => true en el array, el panel se renderiza al final del todo.
Además de paneles, con addAction() puede añadir también acciones: enlaces o botones pulsables que
aparecen en la cabecera de la página de error junto a los integrados (como search):
Tracy\Debugger::getBlueScreen()->addAction(function (Throwable $e): ?array {
if ($e instanceof MyException) {
return [
'link' => 'https://example.com/help?code=' . $e->getCode(),
'label' => 'view help',
];
}
return null;
});
El callback recibe la excepción capturada y devuelve un array con las claves link y label, o
null si no quiere añadir ninguna acción para esa excepción.
Acción „create file“
Cuando en la página de error pulsa un archivo que todavía no existe, Tracy ofrece crearlo (la acción create file). Puede controlar el contenido inicial de ese archivo registrando un generador:
Tracy\Debugger::getBlueScreen()->addFileGenerator(function (string $file, ?string $class): ?string {
if (str_ends_with($file, 'Test.php')) {
return "<?php\n\nclass $class extends Tester\\TestCase\n{\n\t\$END\$\n}\n";
}
return null;
});
El callback recibe la ruta del archivo de destino y, cuando se conoce, el nombre de la clase que debería definirse en él.
Devuelve el contenido inicial (el token $END$ marca dónde se colocará el cursor y se elimina de la salida), o
null para dejar la decisión a otro generador. Los generadores se prueban empezando por el registrado más
recientemente; el generador integrado produce un esqueleto de PHP simple.
Fibers y generadores
Si se lanza una excepción mientras un fiber o un generador está suspendido, su pila no forma parte de la pila de llamadas habitual. Tracy muestra automáticamente la pila de los fibers y generadores accesibles desde la excepción, pero uno que se ejecute de forma independiente se quedaría fuera. Puede añadirlo a la BlueScreen a mano:
Tracy\Debugger::getBlueScreen()->addFiber($fiber);