Профилирование php. XHProf и xDebug - профилирование (profiling) кода PHP. Открытие лога профилирования

Профилирование приложения - это сбор данных о скорости выполнения различных участков программы (файлов и функций). Существует множество инструментов профилирования PHP, но не все инструменты подходят для проведения анализа прямо на рабочем сайте.

XHProf и его форк Tideways - удобный и простой профайлер, который способен эффективно собирать статистику о работе приложения почти без снижения скорости работы вашего приложения (или вашего сайта).

Зачем профилировать код?

Если приложение начинает работать медленно (читай «сайт начал тормозить»), профилирование позволит узнать, какая именно часть наиболее медленная. Результат профилирования обычно представляет собой список выполненных функций вместе со временем их выполнения.

Процедура профилирования кода должна идти первой в процессе оптимизации приложения. Любые другие действия будут догадками и, скорее всего, неправильными. Нужно знать, что именно вызывает проблемы и «тормоза».

Профилирование - это процедура сбора и организации статистики о времени выполнения кода. Это не процесс оптимизации либо изменения программ. Результатом этого процесса обычно является расширенный отчёт о компонентах программы, статистика выполнения функций.

Именно для этого и было разработано решение XHProf. Оно предназначено для работы на реальных сайтах. Основная идея этого профайлера - создавать минимум нагрузки на приложение, при этом собирать все необходимые данные о скорости работы. Решение разработано специалистами из Facebook.

Как подключить php-профайлер в автоматическом режиме?

Наши специалисты потрудились и сделали данный процесс абсолютно автоматизированным.
Вам достаточно авторизоваться в , во вкладке «Домены» выбрать нужный домен, кликнуть по иконке «PHP.INI + PHP Профайлер» и включить чекбокс «Профайлер для домена».

На включение данной функции может потребоваться некоторое время, обычно не более 10 минут.

Для php версий 5.2, 5.3, 5.4, 5.5, 5.6, 7.0 мы используем профайлер XHProf , для php версии 7.1 и выше мы используем профайлер Tideways .

После включения на каждой странице вашего сайта, обрабатываемой php, в нижнюю её часть будет встроен специальный блок со ссылками на файл отчёта (ссылка будет выглядеть примерно так:

Domain-name.com/xhprof-master/xhprof_html/index.php?run=XXXXXXXXXXXX&source=someapp)

А вот как будет выглядеть файл отчета:

Таблица содержит список функций, которые были выполнены в рамках одной страницы с дополнительной информацией:

  • Calls - количество и процентное соотношение вызовов функции
  • Incl. Wall Time - время выполнения функции с вложенными функциями
  • Excl. Wall Time - время выполнения функции без вложенных функций
  • Incl. CPU - процессорное время с вложенными функциями
  • Excl. CPU - процессорное время без вложенных функций
  • Incl. MemUse - потребление памяти с вложенными функциями
  • Excl. MemUse - потребление памяти без вложенных функций
  • Incl. PeakMemUse - максимальное потребление памяти с вложенными функциями
  • Excl. PeakMemUse - максимальное потребление памяти без вложенных функций

Нужно заметить, что отчет, построенный с помощью tideways, может немного визуально отличаться от этого отчета, но суть от этого не меняется.

Графические отчеты


Ресурсоёмкие участки кода выделены желтым (средние) и красным (самые тяжёлые). Это те участки кода, которые используют множество ресурсов относительно всей остальной программы. Это может быть одна медленная функция или большое количество вызовов быстрой функции. В нашем примере мы видим, что функция mysqli_multi_query() помечена красным из-за того, что выполняется медленнее всего.

Агрегатные отчеты

Интерфейс XHProf также позволяет просматривать агрегатную информацию сразу с нескольких отчетов. Для этого run_id передаются через запятую:

Domain-name.com/xhprof-master/xhprof_html/index.php?run=XXXXXXXXXXXX,YYYYYYYYYYY&source=someapp

Технические особенности

    Автоматическое включение профайлера реализовано с помощью директив auto_append_file и auto_prepend_file , которые подключают два исполняемых php файла:

    — auto_append_file выполняет инициализацию объекта сбора статистики и запускает его работу;

    — auto_prepend_file завершает сбор статистики и генерирует файл-отчет со статистикой (в формате JSON);

    Если в процессе выполнения вашего скрипта будет вызвана функция exit() или die(), то auto_prepend_file не будет выполнен, файл статистики не будет сгенерирован и в нижнюю часть страницы не будет включен блок, со ссылками на файл отчета.

  1. Таким образом обращение к любой странице, обрабатываемой php, будет инициировать создание нового файла отчета, поэтому мы рекомендуем отключить профайлер после сбора статистики (обычно для этого хватает нескольких часов), во избежание переполнения дисковой квоты, которая может исчерпаться после генерации большого количества отчетов!
  2. Важно: профайлер будет работать только если сайт прикреплен к серверу по стандартному пути, автоматическими средствами (то есть, с помощью панели управления хостингом), в противном случае для настройки профайлера вам нужно обратиться в техническую поддержку Hostland.
  3. В автоматическом режиме профайлер подключается только к основному доменному имени, к поддоменам автоматического подключение профайлера не предусмотрено.
  4. В автоматическом режиме профайлер собирает статистику только скриптов с расширением.php и.php5
  5. Не возможно гарантировать бесперебойную работу сайта после подключения php-профайлера, поэтому, в случае некорректной работы сайта во время включенного профайлера его следует отключить и продолжить профилирование другими средствами.

Подведём итоги

Мы будем надеяться, что данный инструмент поможет вам сделать ваши сайты еще более быстрыми на хостинге Hostland.

В статье частично использованы материалы пользователя Den Golotyuk размещенные на сайте

Профилирование PHP-кода

Рано или поздно каждый из нас сталкивается с унаследованным кодом и его оптимизацией. Дебаггер и профилировшик в такой ситуации - лучшие помощники программиста. У тех кто работает с PHP, благодаря Дерику Ретансу (Derick Rethans) есть хороший инструмент - xDebug. Информации касательно xDebug много даже в рунете, поэтому речь в этой статье пойдет не о нем.

Наткнувшись на упоминание о профилировщике для PHP я сразу подумал об xDebug (о проприетарных инструментах от Zend я давно уже успел позабыть), но на этот раз ошибся - речь пойдет об XHProf.
XHProf

Этот профилировшик был разработан специально для Facebook, а исходный код его был открыт в марте 2009 года.

Установка прошла достаточно быстро и гладко.
wget pecl.php.net/get/xhprof-0.9.2.tgz
tar xvf xhprof-0.9.2.tgz
cd xhprof-0.9.2/extension/
phpize
./configure && make && make install
cd /usr/local/etc/php.d/
vim xhprof.ini
cd /usr/local/
vim header.php
vim footer.php
vim etc/php.ini
/etc/init.d/php-fpm restart
cp vhost.conf.template prof.my.conf
sed -i s/site/prof/ prof.my.conf
vim prof.my.conf
/etc/init.d/nginx restart

Разберем упомянутые конфиги

Xhprof.ini
extension=/usr/local/lib/php/extensions/no-debug-non-zts-20090626/xhprof.so
xhprof.output_dir="/home/max/www/profile/"

Prof.my.conf - конфиг нгинкса - самый стандартный.

Server {
listen 80;
server_name prof.my;
charset utf8;

Root /usr/local/src/xhprof-0.9.2/xhprof_html ;
location / {
index index.php;
}

Location ~ \.php$ {
fastcgi_pass 127.0.0.1:12000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/src/xhprof-0.9.2/xhprof_html/$fastcgi_script_name;
include fastcgi_params;

В /usr/local/src/xhprof-0.9.2/xhprof_html лежат PHP-исходники, создающие неплохой WEBGUI к профайлеру.

Итак о двух главных файлах:

Header.php


include_once "/usr/local/src/xhprof-0.9.2/xhprof_lib/utils/xhprof_lib.php";
include_once "/usr/local/src/xhprof-0.9.2/xhprof_lib/utils/xhprof_runs.php";
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
}
}

Footer.php
if(isset($_COOKIE["xhprof"])){
if (extension_loaded("xhprof")) {
$profiler_namespace = "myapp"; // namespace for your application
$xhprof_data = xhprof_disable();
$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, $profiler_namespace);

// url to the XHProf UI libraries (change the host name and path)
$profiler_url = sprintf("http://prof.my/index.php?run=%s&source=%s", $run_id, $profiler_namespace);
echo << Profiler output
OUT;
}
}

Теперь запускаем любой PHP-скрипт через веб и видим в левом верхнем углу ссылку на вывод профилировщика - именно для этого и был создан хост prof.my

Обратите внимание - я использую проверку на COOKIE! При такой проверке можно безопасно использовать профилировщик на production-сервере - на реальных данных и реальной загрузке.

Веб-интерфейс профилировщика выводит таблички с информацией о каждой функции и сообщает следующую информацию:

  • Число вызовов каждой функции
  • Wall-time, время затраченное на выполнение функций (включая ожидание ответов от сокетов, файловой системы и т.д.).
  • CPU-time, время затраченное на выполнение функций (исключая ожидание ответов от сокетов, файловой системы и т.д.).
  • Использование памяти
  • Пиковое использование памяти

Есть возможность сортировки таблицы по любому из параметров

Информация по каждой функции делится еще на два вида Inclusive и Exclusive. Inclusive включает цифры использованные дочерними вызовами, а Exclusive не включает их. Так же есть возможность, кликнув на название функции увидеть информацию только по ней и функциям из которых она вызывалась и которые вызывались ей.

Если в системе установлен GraphViz, профилировщик нарисует вам граф вызовов.

P.S. Не нарушая традиций: это мой первый пост на хабре.

UPD: перепостил в PHP.

FirePHP - это расширение для firebug, которое в связке со своим маленьким php-классом, позволяет транслировать в консоль firebug"а данные от php, например всякие var_dump и прочую отладочную информацию. Главный плюс этого расширения в том, что вся трансляция отладочной информации происходит через заголовки и не замусоривает страницы и вообще никак не ломает логику работы приложения. Официальный сайт: http://firephp.org/ .

Основная идея.

Общий алгоритм профилирования заключается в следующем:
  1. В начале страницы включаем профайлинг с помощью xhprof_enable()
  2. В конце страницы выключаем профайлинг с помощью xhprof_disable() и сохраняем собранные данные с помощью save_run()
  3. Далее с помощью php-класса firephp передаем ссылку на данные профайлинга на клиентскую часть
  4. В консоли firebug"а открываем нужную нам информацию
  5. Радуемся:)
Еще хочется сказать, что, конечно, ручное добавление этих функций в свои php-скрипты - это здорово. Но хочется, чтобы эта информация всегда была под рукой во время разработки, и при этом не попадала на боевые сервера. Мы решаем эту задачу следующим образом:

В наших проектах почти во всех скриптах в начале подключается рабочий файлик с загрузчиком классов, подключением функций и прочими нужными штуками. Поэтому включение профайлинга мы вынесли в этот файл. А для того, чтобы иметь возможность включать/выключать отладочный режим по своему желанию добавили проверку на конфигурационную константу, плюс обернули эти проверки в некие мета-тэги, которые автоматически удаляются при сборке проекта. Тоже самое относится и к выключению профайлинга и записывании информации в заголовки с помощью firephp - эти задачи решает одна функция, которая вызывается в конце каждого php-скрипта и так же обернута в мета-тэги. Выглядит это примерно так:

// В конфиг-файле приложения прописаны вот такие константы

/** Режим работы среды окружения * */
define("APPLICATION_ENV" , "dev" ); // dev - отладка | pro - продакшин
/** Путь до профайлера */
define("XHPROF_ROOT" , __DIR__ . "/ExtProcs/debug/xhprof-0.9.2" );

/***************************************************************************************
* Далее в файлике, который подгружается в начале каждого скрипта запускаем профайлинг
* DEV_START и DEV_END - это наши мета-тэги, все что между ними вырезается при сборке
***************************************************************************************/

//-- DEV_START
//-- в режиме отладки подключаем debug библиотеки

// Подгружаем firephp
require_once(__DIR__ . "/includes/ExtProcs/debug/firephp/FirePHP.class.php" );
//-- подгружаем профайлер
"/xhprof_lib/utils/xhprof_lib.php" );
require_once (XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php" );
// Инициализируем профайлинг с нужными флагами. Подробное описание флагов
// можно найти на php.net/manual/ru/xhprof.constants.php
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
}
//-- DEV_END

// Ну и вот такая функция вызывается в конце каждого скрипта
// Ее вызов так же обернут в DEV_START и DEV_END

/**
* Создаем ссылку на результат профайлинга и выводим это в консоль
*/
function dev_boot_Down() {
if (APPLICATION_ENV === "dev" ) {
// Инициализируем экземпляр firephp
$firephp = FirePHP::getInstance(true );
// Выключаем профайлинг и сохраняем данные
$xhprof_data = xhprof_disable();
$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_testing" );
// Формируем ссылку на данные профайлинга и записываем ее в консоль
$link = "http://" . $_SERVER["HTTP_HOST" ] . "/includes/ExtProcs/debug/xhprof-0.9.2/xhprof_html/index.php?run={$run_id}&source=xhprof_testing\n" ;
$firephp->info($link, "profiling data" );
}
}


* This source code was highlighted with Source Code Highlighter .

Не буду вдаваться в подробности установки данных расширений, ибо тут все просто. Скажу только про некоторые моменты настройки. В xhproof предусмотрена всего одна конфигурационная переменная - xhprof.output_dir, которая указывает на папку, куда будут сохраняться данные профайлинга. Поэтому убедитесь, что в указанную директорию у пользователя, из-под которого выполняются php-скрипты есть права на запись. Так что пропишите в свой php.ini что-то вроде этого:


extension=xhprof.so
xhprof.output_dir="/var/tmp/xhprof"

Так же не плохо поставить что-то типа dot или Graphviz для рисования графов вызовов. У меня под MacOS X стоит Graphviz.

Проделав вышеописанные процедуры мы получили возможность в любой момент прямо в браузере открыть и посмотреть на профайлинг любого нашего скрипта.

С помощью систем для профилирования можно собрать информацию о том, какие функции в php-коде потребляют больше процессорного времени и оперативной памяти, то есть выявить наиболее медленные и требовательные к памяти места в программе на php.

xhprof

XHProf - PHP profiler разработанный в Facebook.

Установка:

Aptitude install php-pear pecl install xhprof-0.9.4 echo "extension=xhprof.so" > /etc/php5/mods-available/xhprof.ini ln -s /etc/php5/mods-available/xhprof.ini /etc/php5/conf.d/xhprof.ini apachectl restart

Необходимые для работы файлы расположены в директории /usr/share/php . Однако не все, а только c php-кодом. Для нормального отображения отчетов требуется jquery и css. Их можно заполучить из репозитория на github:

Git clone https://github.com/facebook/xhprof.git

После этого в код php-скрипта в месте, откуда должен начаться сбор данных добавляем строку:

Xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

В скобках указаны параметры для сбора данных. В данном случае будет осуществляться сбор данных по нагрузке на процессор и по использованию оперативной памяти. Возможен еще один параметр XHPROF_FLAGS_NO_BUILTINS при использовании которого данные по встроенным функциям не собираются.

$xhprof_data = xhprof_disable(); include_once "xhprof_lib/utils/xhprof_lib.php"; include_once "xhprof_lib/utils/xhprof_runs.php"; $xhprof_runs = new XHProfRuns_Default(); $run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_test"); echo "Report: http://domain.tld/xhprof_html/index.php?run=$run_id&source=xhprof_test"; echo "\n";

В строке $run_id в кавычках указано название профиля, которое можно задать произвольно.

Результат в обработанном виде выглядит следующим образом:

Если указать параметр XHPROF_FLAGS_NO_BUILTINS , то видно, что количество вызовов функций значительно снижается:

В таблице представлена следующая информация:

Calls - количество вызовов функции,
Wall Time - общее время работы функции вклчая время ожидания ответа от внешних ресурсов,
CPU - сколько времени было затарчено на обработку функций,
MemUse - сколько оперативной памяти было задействовано,
PeakMemUse - пиковое потребление памяти.

В качестве модификаторов выступают:

Incl - inclusive - с учетом вызовов других функций из этой функции,
Excl - exclusive - без учета вызовов функций.

Кроме того, над таблицей представлена информация о суммарных времени обработки, использованной памяти и количестве вызовов функций.

Также XHProf позволяет строить разностные отчеты между двумя запусками, которые обозначаются красным и зеленым цветами. С помощью таких отчетов можно получить ясную картину улучшений после каждого изменения кода.

Для получения подобного отчета нужно воспользоваться ссылкой вида:

http://domain.tld/xhprof_html/index.php?run1=run_id1&run2=run_id2&source=xhprof_test

где run_id1 и run_id2 - идентификаторы запусков.

Если установить Graphviz :

Aptitude install graphviz

Также для php profiler xhprof существуют сторонние веб-интерфейсы использующие базы данных:

xDebug

xDebug - дебаггер PHP-кода с возможностью профилирования (profiling), написанный Дериком Ретансом (Derick Rethans).

Установка:

Yum install php5-xdebug

Затем редактируем конфиг:

Nano /etc/php5/mods-available/xdebug.ini

добавляя в него строки:

Xdebug.profiler_enable = 1 xdebug.profiler_aggregate = On xdebug.profiler_output_dir = /tmp

Здесь включаем PHP профайлер и указываем директорию в которую складывать профили. Профили создаются с именами вида cachegrind.out.*

Существует веб-клиент webgrind: https://github.com/jokkedk/webgrind . Работает он не слишком быстро, но позволяет оперативно просмотреть небольшие профили. Фактически это код на PHP, который нужно склонировать с github:

Git clone https://github.com/jokkedk/webgrind.git

создастся директория webgrind , которую нужно скопировать в директорию любого сайта и обратиться к ней из браузера. Далее, чтобы в Debian заработало построение графиков в конфигурационном файле config.php нужно поправить путь до исполняемого файла graphviz . Должно получиться так:

Static $dotExecutable = "/usr/bin/dot";

Кроме того, можно подправить часовой пояс:

Static $defaultTimezone = "Europe/Moscow";

В заголовке можно выбрать профиль и поставить галочку учитывать ли встроенные функции. В самой таблице видны функции, количество вызовов, время работы самой функции и время с учетом ожидания. Чтобы углубиться в функции достаточно щелкнуть по треугольной стрелочке. В моем случае при достаточно объемных профилях (от нескольких мегабайт), ожидание результата было излишне большим. Вероятно, для достаточно крупных профилей лучше использовать локальные программы просмора.

График может выглядеть следующим образом:

Обратите внимание, что webgrind не стоит использовать на производственных серверах, так как какая-либо авторизация не предусмотрена, но при этом есть доступ к коду файлов на php. В случае необходимости используйте хотя бы базовую авторизацию Apache.

Также существуют программы для анализа профилей как под Linux:

О профилировании

Данные профиля могут помочь вам улучшить ваше приложение, то есть достичь определенных целей, к примеру, понизить потребление памяти, уменьшить время генерации страницы и так далее.

Информация в профиле является стартовой точкой в оптимизации: сообщается сколько времени генерируется результат, сколько памяти используется и сколько вызовов функций происходит. С помощью более подробных данных вы можете улучшить эти показатели.

К примеру, если вы используете фреймворк, то использование некоторых функций фреймворка может вести к вызову нескольких базовых функций. Если вы читаете некоторые данные несколько раз, то, возможно, стоит сохранить результат в переменную.

Также профайлер может помочь понять где стоит использовать кэширование PHP-кода, к примеру, с помощью APCu или memcached .

Прежде всего, стоит оптимизировать функции, который требуют больше всего времени на исполнение. После того, как все оптимизировано и кажется, что улучшать больше нечего, стоит отсортировать функции по количеству вызовов и поработать над его понижением. Даже если PHP работает быстро, то стоит подумать, нужно ли вызывать функции так часто?

При обнаружении следующих ситуаций стоит подумать о кэшировании:

  • Неизменяемые функции вызываются внутри цикла,
  • Некое содержимое генерируется дважды,
  • Содержимое, которое не изменяется генерируется каждый раз,
  • Содержимое генерируется, даже если не используется.

Не стоит кэшировать все подряд, так как память тоже ценный ресурс. Кэшируйте те данные, к которым обращаетесь постоянно. Также кэширование имеет мало смысла в случае если кэширование тратит больше ресурсов, чем экономит.

Кроме кэширования в коде не стоит забывать о кэшировании с помощью веб-сервера (), а также на стороне клиента. Если использовать правильные заголовки, то многие запросы могут быть разрешены еще до поступления на сервер.

Со временем любой PHP-программист сталкивается с проблемой низкой производительности своего приложения. Это может быть медленная загрузка конкретной страницы или слишком долгий ответ от API. И порой достаточно сложно понять, в чем причина тормозов? Порой случаются более сложные ситуации: на боевом сервере api сильно тормозит, но на стенде, где происходит разработка, - все хорошо. И пойди разберись, что идет не так. Производить отладку на рабочем сервере - это крайняя степень безысходности, до которой, конечно, лучше не доводить.

Именно для таких ситуаций и были придуманы специальные инструменты, называемые профилировщиками приложений. В мире PHP эту роль выполняют xDebug, а также xhprof. xhprof является более легковесным, простым и гибким инструментом, поэтому его использование более предпочтительно. Что интересно, xhprof был разработан в facebook еще в 2009 году, однако до сих пор от них нет официальной поддержки php7 и больше не будет, поскольку facebook перешел на HHVM. Однако, благодаря обширному сообществу php-разработчиков, появился форк , поддерживающий php7, установка которого не вызывает каких-либо сложностей.

Установка

Для начала нужно, собственно, установить xhprof:

Git clone https://github.com/longxinH/xhprof xhprof cd xhprof/extension phpize ./configure --with-php-config=/usr/bin/php-config sudo make && sudo make install mkdir /var/tmp/xhprof

Extension=xhprof.so xhprof.output_dir="/var/tmp/xhprof"

Для папки /var/tmp/xhprof должен быть доступ на запись, т.к. туда будут сохраняться результаты профайлинга.

Можно перезагрузить PHP-FPM и проверить, установилось ли расширение. Банально, это можно сделать с помощью вывода функции phpinfo();

xhprof установлен, можно им пользоваться. В пакет xhprof входит очень удобный интерфейс для анализа отчетов профилирования. xhprof позволяет строить отчеты, как в текстовом так и графическом виде. В установочной папке xhprof находятся xhprof_html и xhprof_lib , которые нам понадобятся. Папка xhprof_html - предоставляет доступ к GUI. xhprof_lib - библиотека для отображения и анализа кода. Всю папку xhprof целесообразно перенести в /var/www/xhprof и настроить для нее виртуальный хост, например xhprof.loc. Пример для nginx:

Server { listen 80; server_name xhprof.loc; charset utf-8; root /var/www/xhprof/xhprof_html; index index.php; location / { try_files $uri $uri/ /index.php?q=$uri&$args; } location ~ \.php { fastcgi_pass 127.0.0.1:9000; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }

Также необходимо не забыть обновить файл hosts. Теперь при введении в браузерe URL xhprof.loc мы будем попадать на веб-интерфейс профилировщика, где будут доступы сгенерированные им файлы.

Теперь можно приступить непосредственно к профилированию кода.

Для включения профилировщика используется функция xhprof_enable() , которая на вход принимает следующие флаги:

  • XHPROF_FLAGS_CPU - для фиксирования статистики процессора;
  • XHPROF_FLAGS_MEMORY - для памяти;
  • XHPROF_FLAGS_NO_BUILTINS - для игнорирования встроенных функций.

Для отключения же профилировщика используется функция xhprof_disable(). Для удобства напишем два скрипта header.php и footer.php, выполняющие эти функции. header.php подключается в начало профилируемого скрипта, а footer.php - в конец. footer.php занимается также и сохранением данных профилирования.

header.php: if (extension_loaded("xhprof")) { include_once "/var/www/xhprof/xhprof_lib/utils/xhprof_lib.php"; include_once "/var/www/xhprof/xhprof_lib/utils/xhprof_runs.php"; xhprof_enable(XHPROF_FLAGS_CPU); } footer.php: if (extension_loaded("xhprof")) { $profilerNamespace = "ЗДЕСЬ_ИМЯ_ПРОФИЛИРУЕМОГО_СКРИПТА"; $xhprofData = xhprof_disable(); $xhprofRuns = new XHProfRuns_Default(); $runId = $xhprofRuns->save_run($xhprofData, $profilerNamespace); }
Использование

Подключив header.php и footer.php к профилируемому скриту, можно начинать: при выполнении профилируемого скрипта сгенерируется файл, который сохранится в директории /var/tmp/xhprof , содержащий информацию о работе скрипта. При открытии веб-интерфейса xhprof.loc, будет доступен этот сгенерированный файл:


При открытии файла профилирования появляется детальная информация о работе приложения, весь стек вызовов:


Что значат столбцы:

  • Calls - количество и процентное соотношение вызовов функции;
  • Incl. Wall Time - время выполнения функции с вложенными функциями;
  • Excl. Wall Time - время выполнения функции без вложенных функций;
  • Incl. CPU - процессорное время с вложенными функциями;
  • Excl. CPU - процессорное время без вложенных функций;
  • Incl. MemUse - потребление памяти с вложенными функциями;
  • Excl. MemUse - потребление памяти без вложенных функций;
  • Incl. PeakMemUse - максимальное потребление памяти с вложенными функциями;
  • Excl. PeakMemUse - максимальное потребление памяти без вложенных функций.

Если перейти по ссылке , то отобразится прекрасное дерево вызовов с визуальной индикацией наиболее тормознутого кода. Если же этого не произошло, то скорее всего нужно установить библиотеку graphviz:

Apt-get install graphviz

Пример построенного графика:

В моем случае самое узкое место - это взаимодействие с БД.


Использование xhprof на боевом сервере

Изначально xhprof разрабатывался именно с целью профилирования кода в бою, на production серверах. Другого бесплатного и эффективного инструмента профилирования php7-кода в бою по-просту нет, поэтому у xhprof нет конкурентов. Конкретно у меня есть опыт использования xhprof на production сервере, который обрабатывает миллион запросов в сутки. Там используется php7, и проблем пока не было обнаружено. Однако, xhprof не запускается для каждого запроса - генерировалось бы слишком много файлов профилирования. У меня профилировщик запускается только в том случае, если в запросе указан заголовок «XHPROF_ENABLE» и он установлен в true. Также можно использовать и другую стратегию, например, запускать профилировщик случайно с вероятностью, скажем, в 1/1000. Тогда тоже будет достаточно ясная картина.


Вывод

Даже несмотря на то, что xhprof официально не поддерживается для php7, он по-прежнему остается незаменимым инструментом для php-разработчика.