GUI для xdebug trace файлов
Приходилось ли вам разбираться в запутанном коде без внятной документации? Например, что происходит при создании страницы в какой-нибудь CMS, или почему и откуда именно чужой код посылает email, или делает что-то еще? Есть множество приемов для погружения в чужой код. Можно использовать var_dump (), для чего вам придется запускать один и тот же сценарий множество раз. Можно настроить отладчик, но тогда вам придется заходить (Step Into) во множество функций которые не относятся к тому что вы ищете, а если вы пропустите (Step Over) какой-то важный вызов, вам придется начинать все сначала. Современные IDE предоствляют хорошие средства статического анализа кода, но и с их поддержкой бывает сложно понять, что происходит во время выполнения.
Долгое время меня привлекали возможности трассировки xdebug, но вручную отследить что-либо в многомегабайтном логе совершенно не реально, а какого-нибудь внятного GUI для *.xt файлов я так и не нашел. Поэтому решил написать свой визуализатор, о котором и хочу рассказать.
Возможно я плохо искал и зря потратил время на собственный велосипед. Если вы знаете хороший GUI для трейсов xdebug, то дальше можете не читать, только не забудьте оставить ссылку в комментариях. Свой GUI я написал на php в виде веб-проекта. В идеале это должен быть плагин для PHPStorm, Eclipse или другой IDE, но я бы такое не осилил. Сразу поделюсь ссылкой на исходники: github.com/vtk13/xdebug-trace-viewer. GUI довольно требовательная к ресурсам, поэтому никакого онлайн демо не предусмотрено. Вам придется установить её на свой сервер, если захотите попробовать в живую.
Тут я расскажу, что можно узнать из трейса на примере Joomla. Предположим, что вы уже знаете, что такое xdebug и чем в xdebug страссировка отличается от профилирования. Иначе зачем вам подобный GUI? Вот рекоммендуемые значения ini параметров:
xdebug.auto_trace=»0» — думаю стоит отключить трассировку всех подряд скриптов, чтобы не захламлять сильно папку с trace файлами. xdebug.trace_enable_trigger=»1» — с этой опцией вы сможете делать страссировку только интересующих вас запросов с помощью GET параметра XDEBUG_TRACE=1 xdebug.trace_output_dir=»…» — по вашему желанию xdebug.collect_assignments=»0» — в случае »1» у xdebug случается segmetation fault. xdebug.trace_format=»1» — это едиственный параметр, который обязательно должен быть установлен, чтобы xdebug создавал trace файлы в CSV формате. xdebug.collect_params=»3» — для большей информативности советую писать в лог значения параметров. Если GUI не справится с trace файлом, стоит сначала уменьшить xdebug.var_display_max_data, xdebug.var_display_max_depth, xdebug.var_display_max_children, а если это не поможет, то тогда уже ставить xdebug.collect_params=»0». По моему опыту GUI вполне справлятся с trace файлами в несколько мегабайт. Итак, допустим вы пишете свое расширение для Joomla, которое должно создавать новые статьи и хотите узнать как создание статей устроено в Joomla. Для начала получим trace файл. В админке joomla допишем &XDEBUG_TRACE=1 в action формы создания статьи:
После создания статьи в xdebug.trace_output_dir вы должны получить *.xt файл, который так же должен отобразиться на главной странице GUI:
Раз мы анализируем создание статьи, но наверное стоит начать исследование с mysql функций. Выбираем нужный trace файл и ищем «mysql» по именам исполнявшихся функций:
В нашем примере, в результатах встрачаются два места с вызовом функции mysqli_query (): mysqli.php:123 и mysqli.php:382. Каждый из вызовов может исполняться множество раз во время исполнения скрипта, но в данном случае отображенны только информация о исполнявшихся строках. Сразу скажу, что один из вызовов (в файле mysqli.php строке 123) исполняется только единожды при подключении и не представляет интереса. А вот второй результат поиска — «mysqli.php:382 mysqli_query ()» — более интересен.
По ссылке «mysqli.php:382» в результатах поиска можно перейти к отображению исходного кода:
В исходном коде подсвечены строки которые выполнялись. Стоит сказать что подсвечиваются не абсолютно все исполненые строки. Xdebug записывает в trace только вызовы функций, поэтому строки, например, с присвоением переменных отсутствуют в trace файле, и следовательно не они не подсвечиваются в GUI.
К каждой выполненной строки прикреплено небольшое меню доступное по клику на номере строки:
В нашем примере меня интересуют все вызовы mysqli_query () функции, для чего нужно перейти по ссылке «View all calls» в меню 382-ой строки. В списке всех вызовов функции mysqli_query можно найти 2 вызова с INSERT запросом:
Всего два INSERT для создания статьи выглядит не плохо — в худшем случае ваш плагин сможет создать статью напряму в базе, если не получится найти никакого внутреннего API для этого. Но пока рано отчаиваться. По ссылке #11191 в строке с INSERT можно открыть stacktrace для данного вызова (цифры в ссылке особого интереса не преставляют, это id вызова функции из *.tx файла):
В полученом stacktrace фигурирует вызов ContentModelArticle→save (). Получится ли использовать этот класс в своем расширении — это уже совсем другая история. Тем не менее, это уже хорошая зацепка.