Pierwsze kroki z Tracy
Biblioteka Tracy to przydatny codzienny pomocnik programisty PHP. Pomaga Ci:
- szybko wykrywać i poprawiać błędy
- logować błędy
- dumpować zmienne
- mierzyć czas wykonywania skryptów/zapytań
- widzieć zużycie pamięci
PHP to język idealnie nadający się do tworzenia trudnych do wykrycia błędów, bo daje programistom sporą swobodę. Tym cenniejsze jest narzędzie debugujące takie jak Tracy. Reprezentuje absolutny szczyt wśród narzędzi diagnostycznych dla PHP.
Jeśli spotykasz się z Tracy dziś po raz pierwszy, uwierz, że Twoje życie zacznie dzielić się na czas przed Tracy i czas z nią. Witaj w tej lepszej części!
Instalacja
Najlepszym sposobem instalacji Tracy jest pobranie najnowszego pakietu albo użycie Composera:
composer require tracy/tracy
Alternatywnie możesz pobrać cały pakiet albo plik tracy.phar.
Użycie
Tracy aktywuje się wywołaniem metody Tracy\Debugger::enable() możliwie jak najwcześniej na początku programu,
przed wysłaniem jakiegokolwiek wyjścia:
use Tracy\Debugger;
require 'vendor/autoload.php'; // ewentualnie tracy.phar
Debugger::enable();
Pierwszą rzeczą, którą zauważysz na stronie, jest Tracy Bar w prawym dolnym rogu. Jeśli go nie widzisz, może to
oznaczać, że Tracy działa w trybie produkcyjnym. Tracy jest bowiem ze względów bezpieczeństwa widoczna tylko na
localhoście. Żeby sprawdzić, czy działa, możesz tymczasowo przełączyć ją w tryb deweloperski parametrem
Debugger::enable(Debugger::Development).
Tracy Bar
Tracy Bar to pływający panel wyświetlany w prawym dolnym rogu strony. Możesz go przesuwać myszą, a po przeładowaniu strony zapamięta swoją pozycję.

Do Tracy Bara możesz dodawać kolejne przydatne panele. Ciekawe znajdziesz w dodatkach albo możesz utworzyć własne.
Jeśli nie chcesz wyświetlać Tracy Bara, ustaw:
Debugger::$showBar = false;
Wizualizacja błędów i wyjątków
Na pewno wiesz, jak PHP zgłasza błędy: wypisuje do kodu źródłowego strony coś takiego:
Parse error: syntax error, unexpected '}' in HomePresenter.php on line 15
albo nieprzechwycony wyjątek:
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
Poruszanie się po takim wyjściu nie jest łatwe. Jeśli włączysz Tracy, błędy i wyjątki wyświetlają się w zupełnie innej postaci:

Komunikat o błędzie dosłownie krzyczy. Widzisz fragment kodu źródłowego z podświetloną linią, w której doszło do błędu. Komunikat Call to undefined method Nette\Http\User::isLogedIn() jasno wyjaśnia błąd. Cała strona jest interaktywna, możesz doklikać się do szczegółów. Wypróbuj.
I wiesz co? Błędy krytyczne są przechwytywane i wyświetlane w ten sam sposób. Bez potrzeby instalowania jakichkolwiek rozszerzeń.

Błędy takie jak literówka w nazwie zmiennej albo próba otwarcia nieistniejącego pliku generują zgłoszenia na poziomie E_NOTICE albo E_WARNING. Łatwo je przeoczyć w graficznym layoucie strony, a nawet mogą być całkowicie niewidoczne (chyba że zajrzysz do kodu źródłowego). Pozwól, żeby zajęła się nimi Tracy:

Albo mogą wyświetlać się jak błędy:
Debugger::$strictMode = true; // wyświetla wszystkie błędy
Debugger::$strictMode = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED; // wszystkie błędy oprócz notic o przestarzałości

Uwaga: Tracy po aktywacji zmienia poziom raportowania błędów na E_ALL. Jeśli chcesz to zmienić, zrób to po wywołaniu
enable().
Tryb deweloperski a produkcyjny
Jak widzisz, Tracy jest dość rozmowna, co można docenić w środowisku deweloperskim, podczas gdy na serwerze produkcyjnym spowodowałoby to katastrofę. Nie powinny się tam bowiem wyświetlać żadne informacje debugujące. Tracy ma dlatego autodetekcję środowiska. Jeśli przykład zostanie uruchomiony na serwerze produkcyjnym, błąd zostanie zalogowany zamiast wyświetlony, a odwiedzający zobaczy tylko przyjazny komunikat:

Tryb produkcyjny wyłącza wyświetlanie wszystkich informacji debugujących wysyłanych przez dump(), a oczywiście także wszystkich komunikatów o błędach generowanych przez
PHP. Jeśli więc zapomniałeś w kodzie jakiegoś dump($obj), nie musisz się martwić, na serwerze produkcyjnym nic
się nie wyświetli.
Jak działa autodetekcja trybu? Tryb jest deweloperski, jeśli aplikacja działa na localhoście (czyli pod adresem IP
127.0.0.1 albo ::1) i nie ma proxy (czyli jego nagłówek HTTP nie jest obecny). W przeciwnym razie
działa w trybie produkcyjnym.
Jeśli chcesz włączyć tryb deweloperski także w innych przypadkach, na przykład dla programistów łączących się
z konkretnego adresu IP, możesz podać go jako parametr metody enable():
Debugger::enable('23.75.345.200'); // możesz podać też tablicę adresów IP
Zdecydowanie zalecamy łączenie adresu IP z cookie. Zapisz do cookie tracy-debug tajny token, np.
secret1234, i w ten sposób aktywuj tryb deweloperski tylko dla programistów łączących się z konkretnego
adresu IP, którzy mają wspomniany token w cookie:
Debugger::enable('secret1234@23.75.345.200');
Tryb deweloperski/produkcyjny możesz też ustawić bezpośrednio, używając stałych Debugger::Development albo
Debugger::Production jako parametru metody enable().
Jeśli używasz Nette Framework, zobacz, jak ustawić tryb dla niego, a zostanie on użyty również dla Tracy.
Logowanie błędów
W trybie produkcyjnym Tracy automatycznie loguje wszystkie błędy i przechwycone wyjątki do logu tekstowego. Żeby logowanie
działało, musisz ustawić absolutną ścieżkę do katalogu logów w zmiennej $logDirectory albo przekazać ją
jako drugi parametr metody enable():
Debugger::$logDirectory = __DIR__ . '/log';
Logowanie błędów jest niezwykle przydatne. Wyobraź sobie, że wszyscy użytkownicy Twojej aplikacji to w rzeczywistości beta testerzy, którzy za darmo wykonują pierwszorzędną pracę przy znajdowaniu błędów, a Ty byłbyś głupi, wyrzucając ich cenne zgłoszenia niezauważone do kosza.
Jeśli potrzebujesz logować własne komunikaty albo przechwycone wyjątki, użyj metody log():
Debugger::log('Unexpected error'); // komunikat tekstowy
try {
criticalOperation();
} catch (Exception $e) {
Debugger::log($e); // logowanie wyjątku
// albo
Debugger::log($e, Debugger::ERROR); // wysyła też powiadomienie e-mailem
}
Jeśli chcesz, żeby Tracy logowała błędy PHP jak E_NOTICE czy E_WARNING ze szczegółowymi
informacjami (raport HTML), ustaw Debugger::$logSeverity:
Debugger::$logSeverity = E_NOTICE | E_WARNING;
Dla prawdziwego profesjonalisty log błędów jest kluczowym źródłem informacji i chce być natychmiast informowany
o każdym nowym błędzie. Tracy wychodzi temu naprzeciw, potrafiąc wysyłać powiadomienia e-mailem o nowych wpisach w logu.
Zmienna $email określa, gdzie te e-maile wysyłać:
Debugger::$email = 'admin@example.com';
Jeśli używasz całego Nette Framework, możesz ustawić to i inne rzeczy w pliku konfiguracyjnym.
Żeby chronić Twoją skrzynkę przed zalaniem, Tracy wysyła tylko jedną wiadomość i tworzy plik
email-sent. Gdy programista otrzyma powiadomienie e-mailem, sprawdza log, poprawia aplikację i usuwa plik
monitorujący email-sent. Reaktywuje to wysyłanie e-maili.
Raporty w markdownie
Obok każdego log/exception-*.html Tracy zapisuje bliźniaczy plik .md z tą samą treścią w
markdownie: komunikat, stos wywołań i wycinki kodu źródłowego. Pliki te powstają bezwarunkowo, niezależnie od tego, czy
z aplikacją pracuje agent AI.
Ich celem jest przetwarzanie wsadowe. Zamiast przeklikiwać się przez setki raportów HTML po kolei, możesz przekazać agentowi AI cały katalog logów i pozwolić mu porównać każdy raport z bieżącym stanem kodu oraz zaproponować poprawki.
Wsparcie dla agentów AI
Gdy agent AI steruje Twoją aplikacją przez przeglądarkę (Chrome DevTools MCP, Playwright, Puppeteer), Tracy wykrywa go
przez JavaScriptową właściwość navigator.webdriver i wysyła do konsoli przeglądarki markdownową wersję
kluczowej diagnostyki obok standardowego UI:
- BlueScreen – wyjątek, stos wywołań i wartości zmiennych wysyłane do
console.error()obok czerwonego ekranu, zarówno przy renderowaniu synchronicznym, jak i przy błędach AJAX. - Tracy Bar – markdownowe podsumowanie głównych paneli (SQL, Errors, Dumps) wysyłane do
console.log(). Debugger::dump()– wariant zwykłym tekstem obok zwykłego wyjścia HTML, żeby dumpy nie ginęły w stronie.- Produkcyjna strona 500 –
console.error()informuje agenta, że doszło do błędu i że szczegóły zostały zalogowane na serwerze.
Wykrycie ustawia cookie tracy-webdriver=1; możesz ustawić je ręcznie w DevTools, żeby włączyć wyjście
markdownowe ze zwykłej przeglądarki. Aktywacja agenta nie wpływa na bliźniacze pliki .md zapisywane obok każdego
log/exception-*.html – te powstają bezwarunkowo i stanowią podstawę wsadowego przetwarzania logów
produkcyjnych.
Własne panele Tracy Bara mogą dostarczyć swój markdown, implementując getAgentInfo(). Dla użytkowników
Claude Code plugin Nette zawiera skill tracy-debugging, który uczy
agenta, jak czytać wyjście Tracy z list_console_messages().
Otwieranie plików w edytorze
Gdy wyświetli się strona błędu, możesz kliknąć w nazwy plików, a otworzą się w Twoim edytorze z kursorem na
odpowiedniej linii. Pliki można też tworzyć (akcja create file) albo naprawiać w nich błędy (akcja
fix it). Żeby to działało, trzeba skonfigurować
przeglądarkę i system.
Wspierane wersje PHP
| Tracy | Kompatybilna z 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 |
Dotyczy najnowszych wersji patch.
Porty
Oto lista nieoficjalnych portów do innych frameworków i CMS-ów:
- Drupal 7
- Laravel framework: recca0120/laravel-tracy, whipsterCZ/laravel-tracy
- OpenCart
- ProcessWire CMS/CMF
- Slim Framework
- Symfony framework: kutny/tracy-bundle, VasekPurchart/Tracy-Blue-Screen-Bundle
- WordPress