Создание расширений Tracy
Tracy – отличный инструмент для отладки вашего приложения. Однако иногда вам может понадобиться, чтобы под рукой была и другая информация. Мы покажем, как написать собственные расширения для Tracy Bar, чтобы разработка стала ещё приятнее.
- Создание собственной панели Tracy Bar
- Создание собственного расширения для красного экрана
Хранилище готовых расширений для Tracy вы найдёте на Componette.
Расширения Tracy Bar
Создать новое расширение для Tracy Bar просто. Создайте объект,
реализующий интерфейс Tracy\IBarPanel, у которого есть два метода:
getTab() и getPanel(). Эти методы должны вернуть HTML-код вкладки
(небольшой ярлык, отображаемый прямо на панели Bar) и панели (всплывающее
окно, отображаемое после щелчка по вкладке). Если getPanel() ничего
не вернёт, отобразится только сама вкладка. Если ничего не вернёт
getTab(), не отобразится ничего вообще, и getPanel() вызван
не будет.
class ExamplePanel implements Tracy\IBarPanel
{
public function getTab()
{
return /* ... */;
}
public function getPanel()
{
return /* ... */;
}
}
Регистрация
Регистрация выполняется вызовом Tracy\Debugger::getBar()->addPanel():
Tracy\Debugger::getBar()->addPanel(new ExamplePanel);
Как вариант, панель можно зарегистрировать прямо в конфигурации приложения:
tracy:
bar:
- ExamplePanel
HTML-код вкладки
Должен выглядеть примерно так:
<span title="Поясняющая подсказка">
<svg>...</svg>
<span class="tracy-label">Заголовок</span>
</span>
Изображение должно быть в формате SVG. Если поясняющая подсказка не
нужна, внешний <span> можно опустить.
HTML-код панели
Должен выглядеть примерно так:
<h1>Заголовок</h1>
<div class="tracy-inner">
<div class="tracy-inner-container">
... содержимое ...
</div>
</div>
Заголовок должен либо совпадать с заголовком вкладки, либо содержать дополнительные сведения.
Помните, что одно расширение может быть зарегистрировано несколько
раз, возможно с разными настройками. Поэтому для оформления нельзя
использовать CSS-идентификаторы, только классы, желательно в формате
tracy-addons-<ИмяКласса>[-<необязательное>]. Добавьте этот класс
к div вместе с классом tracy-inner. При написании CSS полезно предварять
селекторы #tracy-debug .ваш-класс, потому что так правило получает
более высокую специфичность, чем сбрасывающие стили.
Стили по умолчанию
В панели у элементов <a>, <table>, <pre> и
<code> есть заранее заданные стили. Если вы хотите сделать
ссылку, скрывающую и показывающую другой элемент, свяжите их
атрибутами href и id и классом tracy-toggle:
<a href="#tracy-addons-ClassName-{$counter}" class="tracy-toggle">Подробности</a>
<div id="tracy-addons-ClassName-{$counter}">...</div>
Если состояние по умолчанию – свёрнутое, добавьте обоим элементам
класс tracy-collapsed.
Используйте статический счётчик, чтобы на одной странице не появились одинаковые идентификаторы.
Собственные ресурсы
Если вашей панели нужны собственные стили или скрипт, вы можете попросить Tracy загрузить дополнительные файлы вместе с её собственными ресурсами:
Tracy\Debugger::$customCssFiles[] = __DIR__ . '/panel.css';
Tracy\Debugger::$customJsFiles[] = __DIR__ . '/panel.js';
Поддержка AI-агентов
Когда браузером управляет AI-агент, Tracy отправляет в JS-консоль
markdown-сводку панели Tracy Bar. Собственные панели могут предоставить свой
markdown, добавив в свою реализацию IBarPanel метод
getAgentInfo(): ?string:
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";
}
}
Возвращённый markdown включается в markdown-сводку панели. Если метода нет
или он возвращает null, панель в сводку не попадает.
Полную картину смотрите в разделе Интеграция Tracy с AI-агентами.
Расширения красного экрана
Таким образом вы можете добавить собственные способы отображения исключений или панели, которые появятся на красном экране.
Расширение создаётся так:
Tracy\Debugger::getBlueScreen()->addPanel(function (?Throwable $e) { // перехваченное исключение
return [
'tab' => '...Заголовок...',
'panel' => '...HTML-содержимое панели...',
];
});
Функция вызывается дважды. Сначала в параметре $e передаётся
само исключение (если оно произошло), и возвращённая панель
отрисовывается в начале страницы. Если она вернёт null или пустой
массив, панель не отрисовывается. Затем функция вызывается с
$e = null, и возвращённая панель отрисовывается под стеком вызовов.
Если функция вернёт в массиве 'bottom' => true, панель отрисуется в
самом низу.
Кроме панелей, через addAction() можно добавить и действия –
кликабельные ссылки или кнопки, которые появятся в шапке страницы с
ошибкой рядом со встроенными (например, search):
Tracy\Debugger::getBlueScreen()->addAction(function (Throwable $e): ?array {
if ($e instanceof MyException) {
return [
'link' => 'https://example.com/help?code=' . $e->getCode(),
'label' => 'посмотреть справку',
];
}
return null;
});
Callback получает перехваченное исключение и возвращает массив с
ключами link и label либо null, если для данного
исключения не хочет добавлять действие.
Действие create file
Когда вы на странице с ошибкой щёлкнете по файлу, которого ещё нет, Tracy предложит его создать (действие create file). Начальное содержимое такого файла можно задать, зарегистрировав генератор:
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;
});
Callback получает путь к целевому файлу и, если оно известно, имя класса,
который в нём должен быть определён. Он возвращает начальное
содержимое (маркер $END$ обозначает место, куда встанет курсор, и
из вывода удаляется) либо null, чтобы оставить решение другому
генератору. Генераторы пробуются начиная с зарегистрированного
последним; встроенный генератор порождает простой каркас PHP.
Файберы и генераторы
Если исключение выброшено в момент, когда файбер или генератор приостановлен, его стек не входит в обычный стек вызовов. Tracy автоматически показывает стек файберов и генераторов, достижимых из исключения, но тот, который работает независимо, остался бы без внимания. Вы можете добавить его в BlueScreen вручную:
Tracy\Debugger::getBlueScreen()->addFiber($fiber);