View source
<?php
namespace Drupal\xhprof;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Link;
use Drupal\xhprof\Extension\TidewaysExtension;
use Drupal\xhprof\Extension\TidewaysXHProfExtension;
use Drupal\xhprof\Extension\UprofilerExtension;
use Drupal\xhprof\Extension\XHProfExtension;
use Drupal\xhprof\XHProfLib\Storage\StorageInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
class Profiler implements ProfilerInterface {
private $configFactory;
private $storage;
private $requestMatcher;
private $runId;
private $enabled = FALSE;
private $activeExtension;
public function __construct(ConfigFactoryInterface $configFactory, StorageInterface $storage, RequestMatcherInterface $requestMatcher) {
$this->configFactory = $configFactory;
$this->storage = $storage;
$this->requestMatcher = $requestMatcher;
$extension = $this->configFactory
->get('xhprof.config')
->get('extension');
if ($extension == 'xhprof') {
$this->activeExtension = new XHProfExtension();
}
elseif ($extension == 'uprofiler') {
$this->activeExtension = new UprofilerExtension();
}
elseif ($extension == 'tideways') {
$this->activeExtension = new TidewaysExtension();
}
elseif ($extension == 'tideways_xhprof') {
$this->activeExtension = new TidewaysXHProfExtension();
}
}
public function enable() {
$config = $this->configFactory
->get('xhprof.config');
$flags = $config
->get('flags');
$excludeIndirectFunctions = $config
->get('exclude_indirect_functions');
$modifier = 0;
$extensionOptions = $this->activeExtension
->getOptions();
foreach ($flags as $key => $value) {
if ($value !== '0') {
$extensionFlag = $extensionOptions[$key];
$modifier += @constant($extensionFlag);
}
}
$options = [];
if ($excludeIndirectFunctions) {
$options = [
'ignored_functions' => [
'call_user_func',
'call_user_func_array',
],
];
}
$this->activeExtension
->enable($modifier, $options);
$this->enabled = TRUE;
}
public function shutdown($runId) {
$xhprof_data = $this->activeExtension
->disable();
$this->enabled = FALSE;
return $this->storage
->saveRun($xhprof_data, $this
->getNamespace(), $runId);
}
public function isEnabled() {
return $this->enabled;
}
public function canEnable(Request $request) {
$config = $this->configFactory
->get('xhprof.config');
if ($this
->isLoaded() && $config
->get('enabled') && $this->requestMatcher
->matches($request)) {
$interval = $config
->get('interval');
if ($interval && mt_rand(1, $interval) % $interval != 0) {
return FALSE;
}
return TRUE;
}
return FALSE;
}
public function isLoaded() {
return count($this
->getExtensions()) >= 1;
}
public function getExtensions() {
$extensions = [];
if (XHProfExtension::isLoaded()) {
$extensions['xhprof'] = 'XHProf';
}
if (UprofilerExtension::isLoaded()) {
$extensions['uprofiler'] = 'UProfiler';
}
if (TidewaysExtension::isLoaded()) {
$extensions['tideways'] = 'Tideways';
}
if (TidewaysXHProfExtension::isLoaded()) {
$extensions['tideways_xhprof'] = 'Tideways xhprof';
}
return $extensions;
}
public function link($run_id) {
$link = Link::createFromRoute(t('XHProf output'), 'xhprof.run', [
'run' => $run_id,
], [
'absolute' => TRUE,
]);
return $link
->toString();
}
public function getStorage() {
return $this->storage;
}
public function getRunId() {
return $this->runId;
}
public function createRunId() {
if (!$this->runId) {
$this->runId = uniqid();
}
return $this->runId;
}
public function getRun($run_id) {
return $this
->getStorage()
->getRun($run_id, $this
->getNamespace());
}
private function getNamespace() {
$result = $this->configFactory
->get('system.site')
->get('name');
return str_replace([
'.',
'/',
'\\',
], '-', $result);
}
}