-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
How to use xhprof
pecl update-channels
pecl install xhprof
(You may need to add the DEB sury repo: https://gist.github.com/janus57/37b079a383dd0507149bd94fd35053d1)
apt install php-xhprof
# More specific
apt install php8.0-xhprof
Run php --ini
and it will say Scan for additional .ini files in
Example:
php --ini
Configuration File (php.ini) Path: /etc/php/7.4/cli
Loaded Configuration File: /etc/php/7.4/cli/php.ini
Scan for additional .ini files in: /etc/php/7.4/cli/conf.d
Run echo 'extension=xhprof.so' > /etc/php/7.4/cli/conf.d/docker-php-ext-xhprof.ini
to activate the extension.
Note: /etc/php/7.4/cli/conf.d
is a path given by php --ini
Run echo 'extension=xhprof.so' > /etc/php/7.4/fpm/conf.d/docker-php-ext-xhprof.ini
to activate the extension.
Note: /etc/php/7.4/fpm/conf.d
is a path given by phpinfo();
on a web page in the "Scan this dir for additional .ini files" line
No phpMyAdmin is not an app that "runs". That said you need to restart your php-fpm worker pool or your apache2 webserver. It will read the new extension file config and load it.
Examples:
service apache2 restart
-
docker restart phpfpm74
(wherephpfpm74
is the container name) service php7.2-fpm restart
/etc/init.d/php7.2-fpm restart
class XhProfProfiling
{
/** @var string */
private $requestUuid;
public function __construct()
{
$this->requestUuid = uniqid() . '.' . str_replace('+', '-', date('c'));
if (! extension_loaded('xhprof')) {
$this->log('The xhprof extension is not enabled');
return;
}
xhprof_enable(XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY);
$this->log('Loaded xhprof');
}
public function log(string $msg): void
{
// Enable this to print logs to error logs
// error_log('[' . $this->requestUuid . '] ' . $msg);
}
public function __destruct()
{
global $route;
if (! extension_loaded('xhprof')) {
return;
}
$buildXhprofs = __DIR__ . '/build/profiles/';
if (! is_dir($buildXhprofs)) {
mkdir($buildXhprofs, 0777, true);
}
$xhprofData = xhprof_disable();
$xhprofData = serialize($xhprofData);
$this->requestUuid .= str_replace('/', '--', $route);
$profilePath = $buildXhprofs . $this->requestUuid . '_capture.xhprof';
$wrote = file_put_contents($profilePath, $xhprofData);
$this->log('Wrote xhprof profile to "' . $profilePath . '": ' . ($wrote === false ? 'no' : 'yes'));
$metaPath = $buildXhprofs . $this->requestUuid . '_metadata.json';
$metadata = [
'route' => $route,
'method' => $_SERVER['REQUEST_METHOD'] ?? 'php ini bug',
'params' => [
'GET' => $_GET,
'POST' => $_POST,
'COOKIES' => $_COOKIE,
],
];
// Replace tokens with "*"
$ssoValue = $GLOBALS['cfg']['Server']['SignonSession'] ?? 'n/a';
foreach (['phpMyAdmin', 'phpMyAdmin_https', $ssoValue] as $key) {
if (! isset($metadata['params']['COOKIES'][$key])) {
continue;
}
$metadata['params']['COOKIES'][$key] = str_repeat('*', strlen($metadata['params']['COOKIES'][$key]));
}
foreach (array_keys($metadata['params']) as $key) {
if (! isset($metadata['params'][$key]['token'])) {
continue;
}
$metadata['params'][$key]['token'] = str_repeat('*', strlen($metadata['params'][$key]['token']));
}
$metadata = (string) json_encode($metadata, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
$wrote = file_put_contents($metaPath, $metadata);
$this->log('Wrote metadata to "' . $metaPath . '": ' . ($wrote === false ? 'no' : 'yes'));
}
}
$keepMeInMemory = new XhProfProfiling();
Please check that the metadata files have nothing private
They normally contain no private data (only the queries could be in the files)
They are in {phpMyAdmin}/build/profiles/
Popular destinations:
- Team meetings
- GSoC home
- Developer guidelines
- How to install on Debian and Ubuntu
- Issue and pull-request management
User resources: