Créer des extensions pour Tracy
Tracy est un excellent outil pour déboguer votre application. Vous voudrez cependant parfois avoir d'autres informations sous la main. Nous allons montrer comment écrire vos propres extensions pour la Tracy Bar afin de rendre le développement encore plus agréable.
- Créer votre propre panneau de la Tracy Bar
- Créer votre propre extension du BlueScreen
Vous trouverez un dépôt d'extensions toutes prêtes pour Tracy sur Componette.
Extensions de la Tracy Bar
Créer une nouvelle extension pour la Tracy Bar est simple. Créez un objet qui implémente l'interface
Tracy\IBarPanel, laquelle comporte deux méthodes : getTab() et getPanel(). Ces méthodes
doivent renvoyer le code HTML de l'onglet (une petite étiquette affichée directement sur la Bar) et du panneau (une fenêtre qui
apparaît après un clic sur l'onglet). Si getPanel() ne renvoie rien, seul l'onglet lui-même est affiché. Si
getTab() ne renvoie rien, rien n'est affiché du tout et getPanel() n'est pas appelée.
class ExamplePanel implements Tracy\IBarPanel
{
public function getTab()
{
return /* ... */;
}
public function getPanel()
{
return /* ... */;
}
}
Enregistrement
L'enregistrement se fait en appelant Tracy\Debugger::getBar()->addPanel() :
Tracy\Debugger::getBar()->addPanel(new ExamplePanel);
Vous pouvez sinon enregistrer le panneau directement dans la configuration de l'application :
tracy:
bar:
- ExamplePanel
Code HTML de l'onglet
Il devrait ressembler à ceci :
<span title="Infobulle explicative">
<svg>...</svg>
<span class="tracy-label">Titre</span>
</span>
L'image devrait être au format SVG. Si une infobulle explicative n'est pas nécessaire, le <span>
extérieur peut être omis.
Code HTML du panneau
Il devrait ressembler à ceci :
<h1>Titre</h1>
<div class="tracy-inner">
<div class="tracy-inner-container">
... contenu ...
</div>
</div>
Le titre devrait être soit identique à celui de l'onglet, soit contenir des informations supplémentaires.
Gardez à l'esprit qu'une même extension peut être enregistrée plusieurs fois, éventuellement avec des réglages
différents. Pour la mise en forme, vous ne pouvez donc pas utiliser d'identifiants CSS, seulement des classes, de préférence
sous la forme tracy-addons-<NomDeClasse>[-<facultatif>]. Ajoutez cette classe au div à côté de la
classe tracy-inner. Lors de l'écriture du CSS, il est utile de préfixer les sélecteurs par
#tracy-debug .votre-classe, car cela donne à la règle une spécificité plus élevée que les styles de reset.
Styles par défaut
Dans le panneau, les éléments <a>, <table>, <pre> et
<code> ont des styles prédéfinis. Si vous voulez créer un lien qui masque et affiche un autre élément,
reliez-les par les attributs href et id et la classe tracy-toggle :
<a href="#tracy-addons-ClassName-{$counter}" class="tracy-toggle">Détails</a>
<div id="tracy-addons-ClassName-{$counter}">...</div>
Si l'état par défaut est replié, ajoutez la classe tracy-collapsed aux deux éléments.
Utilisez un compteur statique pour éviter les identifiants en double sur une même page.
Assets personnalisés
Si votre panneau a besoin de sa propre feuille de style ou de son propre script, vous pouvez faire charger à Tracy des fichiers supplémentaires à côté des siens :
Tracy\Debugger::$customCssFiles[] = __DIR__ . '/panel.css';
Tracy\Debugger::$customJsFiles[] = __DIR__ . '/panel.js';
Prise en charge des agents IA
Lorsqu'un agent IA pilote le navigateur, Tracy envoie dans la console JS un résumé en markdown de la Tracy Bar. Les panneaux
personnalisés peuvent fournir leur propre markdown en ajoutant une méthode getAgentInfo(): ?string à leur
implémentation d'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";
}
}
Le markdown renvoyé est inclus dans le résumé markdown de la barre. Quand la méthode manque ou renvoie null,
le panneau est omis du résumé.
Voir l'intégration des agents IA à Tracy pour la vue d'ensemble.
Extensions du BlueScreen
Vous pouvez ainsi ajouter des visualisations d'exceptions ou des panneaux personnalisés qui apparaîtront sur l'écran bleu.
Une extension se crée ainsi :
Tracy\Debugger::getBlueScreen()->addPanel(function (?Throwable $e) { // exception attrapée
return [
'tab' => '...Titre...',
'panel' => '...contenu HTML du panneau...',
];
});
La fonction est appelée deux fois. D'abord, l'exception elle-même est passée dans le paramètre $e (si une
exception est survenue) et le panneau renvoyé est rendu au début de la page. S'il renvoie null ou un tableau vide,
le panneau n'est pas rendu. Elle est ensuite appelée avec $e = null et le panneau renvoyé est rendu sous la pile
d'appels. Si la fonction renvoie 'bottom' => true dans le tableau, le panneau est rendu tout en bas.
Outre des panneaux, vous pouvez aussi ajouter des actions à l'aide d'addAction() : des liens ou des
boutons cliquables qui apparaissent dans l'en-tête de la page d'erreur, à côté de ceux intégrés (comme search) :
Tracy\Debugger::getBlueScreen()->addAction(function (Throwable $e): ?array {
if ($e instanceof MyException) {
return [
'link' => 'https://example.com/help?code=' . $e->getCode(),
'label' => 'voir l\'aide',
];
}
return null;
});
Le callback reçoit l'exception attrapée et renvoie un tableau avec les clés link et label, ou
null s'il ne veut pas ajouter d'action pour l'exception donnée.
Action create file
Lorsque vous cliquez, sur la page d'erreur, sur un fichier qui n'existe pas encore, Tracy propose de le créer (l'action create file). Vous pouvez déterminer le contenu initial d'un tel fichier en enregistrant un générateur :
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;
});
Le callback reçoit le chemin du fichier cible et, quand il est connu, le nom de la classe qui doit y être définie. Il
renvoie le contenu initial (le jeton $END$ marque l'endroit où le curseur sera placé et est retiré de la sortie),
ou null pour laisser la décision à un autre générateur. Les générateurs sont essayés en commençant par le
dernier enregistré ; le générateur intégré produit un simple squelette PHP.
Fibers et générateurs
Si une exception est levée pendant qu'une fiber ou un générateur est suspendu, sa pile ne fait pas partie de la pile d'appels ordinaire. Tracy affiche automatiquement la pile des fibers et générateurs accessibles depuis l'exception, mais l'une d'elles tournant indépendamment échapperait à cette détection. Vous pouvez l'ajouter manuellement au BlueScreen :
Tracy\Debugger::getBlueScreen()->addFiber($fiber);