Primi passi con Tracy

La libreria Tracy è un aiutante quotidiano prezioso per i programmatori PHP. Vi aiuta a:

  • individuare e correggere rapidamente gli errori
  • registrare gli errori
  • fare il dump delle variabili
  • misurare il tempo di esecuzione di script e query
  • vedere il consumo di memoria

PHP è un linguaggio perfetto per creare errori difficili da individuare, perché lascia agli sviluppatori molta libertà. Tanto più prezioso è quindi uno strumento di debug come Tracy. Rappresenta il vertice assoluto tra gli strumenti diagnostici per PHP.

Se oggi incontrate Tracy per la prima volta, credeteci: la vostra vita comincerà a dividersi nel tempo prima di Tracy e nel tempo con lei. Benvenuti nella parte migliore!

Installazione

Il modo migliore di installare Tracy è scaricare l'ultimo pacchetto oppure usare Composer:

composer require tracy/tracy

In alternativa potete scaricare l'intero pacchetto oppure il file tracy.phar.

Uso

Tracy si attiva chiamando il metodo Tracy\Debugger::enable() il prima possibile all'inizio del programma, prima che venga inviato qualsiasi output:

use Tracy\Debugger;

require 'vendor/autoload.php'; // eventualmente tracy.phar

Debugger::enable();

La prima cosa che noterete sulla pagina è la Tracy Bar nell'angolo in basso a destra. Se non la vedete, può voler dire che Tracy gira in modalità produzione. Tracy infatti, per motivi di sicurezza, è visibile solo su localhost. Per verificare se funziona, potete metterla temporaneamente in modalità di sviluppo con il parametro Debugger::enable(Debugger::Development).

Tracy Bar

La Tracy Bar è un pannello flottante mostrato nell'angolo in basso a destra della pagina. Potete spostarlo con il mouse e ricorderà la sua posizione dopo il ricaricamento della pagina.

Alla Tracy Bar potete aggiungere altri pannelli utili. Quelli interessanti li trovate tra i componenti aggiuntivi, oppure potete crearne di vostri.

Se non volete mostrare la Tracy Bar, impostate:

Debugger::$showBar = false;

Visualizzazione di errori ed eccezioni

Sapete di certo come PHP segnala gli errori: stampa nel codice sorgente della pagina qualcosa del genere:

Parse error:  syntax error, unexpected '}' in HomePresenter.php on line 15

oppure un'eccezione non catturata:

Fatal error:  Uncaught Nette\MemberAccessException: Call to undefined method Nette\Application\UI\Form::addTest()? in /sandbox/vendor/nette/utils/src/Utils/ObjectMixin.php:100
Stack trace:
#0 /sandbox/vendor/nette/utils/src/Utils/Object.php(75): Nette\Utils\ObjectMixin::call(Object(Nette\Application\UI\Form), 'addTest', Array)
#1 /sandbox/app/Forms/SignFormFactory.php(32): Nette\Object->__call('addTest', Array)
#2 /sandbox/app/Presentation/Sign/SignPresenter.php(21): App\Forms\SignFormFactory->create()
#3 /sandbox/vendor/nette/component-model/src/ComponentModel/Container.php(181): App\Presentation\Sign\SignPresenter->createComponentSignInForm('signInForm')
#4 /sandbox/vendor/nette/component-model/src/ComponentModel/Container.php(139): Nette\ComponentModel\Container->createComponent('signInForm')
#5 /sandbox/temp/cache/latte/15206b353f351f6bfca2c36cc.php(17): Nette\ComponentModel\Co in /sandbox/vendor/nette/utils/src/Utils/ObjectMixin.php on line 100

Orientarsi in un output del genere non è proprio semplice. Se attivate Tracy, errori ed eccezioni vengono mostrati in una forma completamente diversa:

Il messaggio di errore letteralmente urla. Vedete la parte di codice sorgente con la riga evidenziata in cui si è verificato l'errore. Il messaggio Call to undefined method Nette\Http\User::isLogedIn() spiega chiaramente l'errore. Tutta la pagina è interattiva, potete cliccare per avere altri dettagli. Provate.

E indovinate un po'? Anche gli errori fatali vengono catturati e mostrati allo stesso modo. Senza dover installare alcuna estensione.

Errori come un refuso nel nome di una variabile o il tentativo di aprire un file inesistente generano segnalazioni di livello E_NOTICE o E_WARNING. Nel layout grafico della pagina si possono facilmente trascurare, o addirittura essere del tutto invisibili (a meno che non guardiate il codice sorgente). Lasciate che se ne occupi Tracy:

Oppure si possono mostrare come errori:

Debugger::$strictMode = true; // mostra tutti gli errori
Debugger::$strictMode = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED; // tutti gli errori tranne le notice deprecated

Nota: Tracy, quando viene attivata, cambia il livello di error reporting a E_ALL. Se volete modificarlo, fatelo dopo la chiamata a enable().

Modalità di sviluppo e modalità produzione

Come vedete, Tracy è piuttosto loquace, il che si apprezza nell'ambiente di sviluppo, mentre sul server di produzione sarebbe un disastro. Là infatti non va mostrata alcuna informazione di debug. Tracy ha perciò il rilevamento automatico dell'ambiente. Se l'esempio gira su un server pubblico, l'errore verrà registrato invece che mostrato e il visitatore vedrà solo un messaggio comprensibile:

La modalità produzione sopprime la visualizzazione di tutte le informazioni di debug inviate con dump() e naturalmente anche di tutti i messaggi di errore generati da PHP. Se quindi vi siete dimenticati nel codice qualche dump($obj), non dovete preoccuparvi: sul server di produzione non verrà mostrato nulla.

Come funziona il rilevamento automatico della modalità? La modalità è di sviluppo se l'applicazione gira su localhost (cioè con indirizzo IP 127.0.0.1 oppure ::1) e non c'è un proxy (cioè manca il suo header HTTP). Altrimenti gira in modalità produzione.

Se volete attivare la modalità di sviluppo anche in altri casi, per esempio per gli sviluppatori che accedono da un indirizzo IP determinato, potete indicarlo come parametro del metodo enable():

Debugger::enable('23.75.345.200'); // si può indicare anche un array di indirizzi IP

Consigliamo senz'altro di combinare l'indirizzo IP con un cookie. Salvate nel cookie tracy-debug un token segreto, per esempio secret1234, e in questo modo attivate la modalità di sviluppo solo per gli sviluppatori che accedono da un determinato indirizzo IP e hanno nel cookie il token indicato:

Debugger::enable('secret1234@23.75.345.200');

Potete anche impostare direttamente la modalità di sviluppo o produzione usando le costanti Debugger::Development o Debugger::Production come parametro del metodo enable().

Se usate il Nette Framework, date un'occhiata a come impostare la modalità per esso: verrà poi usata anche per Tracy.

Logging degli errori

In modalità produzione Tracy registra automaticamente tutti gli errori e le eccezioni catturate in un log di testo. Perché il logging funzioni, dovete impostare nella variabile $logDirectory il percorso assoluto della directory dei log, oppure passarlo come secondo parametro al metodo enable():

Debugger::$logDirectory = __DIR__ . '/log';

Il logging degli errori è estremamente utile. Immaginate che tutti gli utenti della vostra applicazione siano in realtà dei beta tester che svolgono un lavoro di prim'ordine nel trovare errori gratuitamente, e che sareste sciocchi a buttare le loro preziose segnalazioni nel cestino senza accorgervene.

Se avete bisogno di registrare messaggi vostri o eccezioni catturate, usate il metodo log():

Debugger::log('Errore imprevisto'); // messaggio di testo

try {
	criticalOperation();
} catch (Exception $e) {
	Debugger::log($e); // registra l'eccezione
	// oppure
	Debugger::log($e, Debugger::ERROR); // invia anche una notifica per email
}

Se volete che Tracy registri gli errori PHP come E_NOTICE o E_WARNING con informazioni dettagliate (report HTML), impostate Debugger::$logSeverity:

Debugger::$logSeverity = E_NOTICE | E_WARNING;

Per un vero professionista il log degli errori è una fonte di informazioni fondamentale e vuole essere informato subito di ogni nuovo errore. Tracy va incontro a questa esigenza: sa inviare notifiche per email sulle nuove voci del log. La variabile $email determina dove inviare queste email:

Debugger::$email = 'admin@example.com';

Se usate tutto il Nette Framework, potete impostare questo e altro nel file di configurazione.

Per proteggere la vostra casella di posta da un diluvio di messaggi, Tracy invia un solo messaggio e crea il file email-sent. Quando lo sviluppatore riceve la notifica per email, controlla il log, corregge l'applicazione e cancella il file di controllo email-sent. Questo riattiva l'invio delle email.

Report in markdown

Accanto a ogni log/exception-*.html Tracy scrive un file gemello .md con lo stesso contenuto in markdown: il messaggio, lo stack trace e gli estratti del codice sorgente. Questi file vengono creati sempre, indipendentemente dal fatto che con l'applicazione stia lavorando un agente AI.

Il loro scopo è l'elaborazione in blocco. Invece di cliccare uno per uno centinaia di report HTML, potete consegnare a un agente AI l'intera directory dei log e lasciare che confronti ogni report con lo stato attuale del codice e proponga delle correzioni.

Supporto per gli agenti AI

Quando un agente AI comanda la vostra applicazione tramite un browser (Chrome DevTools MCP, Playwright, Puppeteer), Tracy lo rileva grazie alla proprietà JavaScript navigator.webdriver e invia nella console del browser, accanto alla consueta interfaccia, una versione markdown delle diagnostiche principali:

  • BlueScreen – eccezione, stack trace e valori delle variabili inviati a console.error() accanto alla schermata rossa, sia per il rendering sincrono sia per gli errori AJAX.
  • Tracy Bar – riassunto markdown dei pannelli principali (SQL, Errors, Dumps) inviato a console.log().
  • Debugger::dump() – una variante in testo semplice accanto al consueto output HTML, così i dump non si perdono nella pagina.
  • Pagina 500 di produzione – console.error() informa l'agente che si è verificato un errore e che i dettagli sono stati registrati sul server.

Il rilevamento imposta il cookie tracy-webdriver=1; potete impostarlo a mano nei DevTools per attivare l'output markdown da un browser normale. L'attivazione dell'agente non influisce sui file gemelli .md scritti accanto a ogni log/exception-*.html: quelli vengono prodotti sempre e sono la base per l'elaborazione in blocco dei log di produzione.

I pannelli personalizzati della Tracy Bar possono fornire il proprio markdown implementando getAgentInfo(). Per chi usa Claude Code, il plugin Nette comprende la skill tracy-debugging, che insegna all'agente come leggere l'output di Tracy da list_console_messages().

Aprire i file nell'editor

Quando viene mostrata la pagina di errore, potete cliccare sui nomi dei file e si apriranno nel vostro editor con il cursore sulla riga corrispondente. Si possono anche creare file (azione create file) oppure correggervi errori (azione fix it). Perché funzioni bisogna configurare il browser e il sistema.

Versioni di PHP supportate

Tracy Compatibile con PHP
Tracy 2.10 – 3.0 PHP 8.0 – 8.4
Tracy 2.9 PHP 7.2 – 8.2
Tracy 2.8 PHP 7.2 – 8.1
Tracy 2.6 – 2.7 PHP 7.1 – 8.0
Tracy 2.5 PHP 5.4 – 7.4
Tracy 2.4 PHP 5.4 – 7.2

Vale per le ultime versioni patch.

Port

Questo è l'elenco dei port non ufficiali verso altri framework e CMS: