class XHProfController in XHProf 8
Displays profiling results.
Hierarchy
- class \Drupal\Core\Controller\ControllerBase implements ContainerInjectionInterface uses LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\xhprof\Controller\XHProfController
Expanded class hierarchy of XHProfController
File
- src/
Controller/ XHProfController.php, line 19
Namespace
Drupal\xhprof\ControllerView source
class XHProfController extends ControllerBase {
/**
* The profiler.
*
* @var \Drupal\xhprof\ProfilerInterface
*/
private $profiler;
/**
* The report engine.
*
* @var \Drupal\xhprof\XHProfLib\Report\ReportEngine
*/
private $reportEngine;
/**
* The date formatter.
*
* @var \Drupal\Core\Datetime\DateFormatterInterface
*/
private $dateFormatter;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->profiler = $container
->get('xhprof.profiler');
$instance->reportEngine = $container
->get('xhprof.report_engine');
$instance->dateFormatter = $container
->get('date.formatter');
return $instance;
}
/**
* Returns list of runs.
*
* @return array
* A render array.
*/
public function runsAction() {
$runs = $run = $this->profiler
->getStorage()
->getRuns();
$rows = [];
foreach ($runs as $run) {
$rows[] = [
Link::createFromRoute($run['run_id'], 'xhprof.run', [
'run' => $run['run_id'],
]),
format_size($run['size']),
isset($run['path']) ? $run['path'] : '',
$this->dateFormatter
->format($run['date'], 'small'),
];
}
return [
'table' => [
'#type' => 'table',
'#header' => [
[
'data' => $this
->t('View'),
],
[
'data' => $this
->t('File size'),
],
[
'data' => $this
->t('Path'),
'field' => 'path',
],
[
'data' => $this
->t('Date'),
'field' => 'date',
'sort' => 'desc',
],
],
'#rows' => $rows,
'#empty' => $this
->t('No runs collected'),
'#attributes' => [
'id' => 'xhprof-runs-table',
],
],
];
}
/**
* Renders the run.
*
* @param \Drupal\xhprof\XHProfLib\Run $run
* The run.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
*
* @return array
* A render array.
*/
public function runAction(Run $run, Request $request) {
$length = $request->query
->get('length', 100);
$sort = $request->query
->get('sort', 'wt');
$report = $this->reportEngine
->getReport(NULL, NULL, $run, NULL, NULL, $sort, NULL, NULL);
$run_id = $run
->getId();
$build['#title'] = $this
->t('XHProf view report for %id', [
'%id' => $run_id,
]);
$descriptions = ReportConstants::getDescriptions();
$build['summary'] = [
'table' => [
'#type' => 'table',
'#responsive' => FALSE,
'#header' => [
$this
->t('Overall summary'),
$this
->t('%mu is <a href=":wiki">microseconds</a>', [
'%mu' => 'μs',
':wiki' => 'https://en.wikipedia.org/wiki/Microsecond',
]),
],
'#rows' => $this
->getSummaryRows($report, $descriptions),
],
];
$build['length'] = [
'#type' => 'inline_template',
'#template' => $length == -1 ? '<h3>Displaying all functions, sorted by {{ sort }}. [{{ top }}]</h3>' : '<h3>Displaying top {{ length }} functions, sorted by {{ sort }}. [{{ all }}]</h3>',
'#context' => [
'length' => $length,
'all' => Link::createFromRoute($this
->t('show all'), 'xhprof.run', [
'run' => $run_id,
'length' => -1,
]),
'top' => Link::createFromRoute($this
->t('show top'), 'xhprof.run', [
'run' => $run_id,
'length' => 100,
]),
'sort' => Xss::filter($descriptions[$sort], []),
],
];
$build['table'] = [
'#type' => 'table',
'#responsive' => FALSE,
'#sticky' => TRUE,
'#header' => $this
->getRunHeader($report, $descriptions, $run_id),
'#rows' => $this
->getRunRows($run, $report, $length),
'#attributes' => [
'class' => [
'responsive',
],
],
'#attached' => [
'library' => [
'xhprof/xhprof',
],
],
'#cache' => [
'contexts' => [
'url.query_args',
],
],
];
return $build;
}
/**
* Renders diff of two runs.
*
* @param \Drupal\xhprof\XHProfLib\Run $run1
* The first run.
* @param \Drupal\xhprof\XHProfLib\Run $run2
* The second run.
*
* @return array
* A render array.
*/
public function diffAction(Run $run1, Run $run2) {
return [
'#markup' => 'Not working yet',
];
}
/**
* @param \Drupal\xhprof\XHProfLib\Run $run
* @param $symbol
*
* @return array
*/
public function symbolAction(Run $run, $symbol, Request $request) {
$sort = $request->query
->get('sort', 'wt');
$globalReport = $this->reportEngine
->getReport(NULL, NULL, $run, NULL, NULL, $sort, NULL, NULL);
$report = $this->reportEngine
->getReport(NULL, NULL, $run, NULL, [
$symbol,
], $sort, NULL, NULL);
$build['#title'] = $this
->t('XHProf view report for %id', [
'%id' => $run
->getId(),
]);
$descriptions = ReportConstants::getDescriptions();
$build['title'] = [
'#type' => 'inline_template',
'#template' => '<strong>Parent/Child report for ' . $symbol . '</strong>',
];
$build['table'] = [
'#theme' => 'table',
'#header' => $this
->getRunHeader($report, $descriptions, $run
->getId()),
'#rows' => $this
->getRunRows($run, $report, -1, $globalReport, $symbol),
'#attributes' => [
'class' => [
'responsive',
],
],
'#attached' => [
'library' => [
'xhprof/xhprof',
],
],
];
return $build;
}
/**
* @param string $class
*
* @return \Drupal\Component\Render\FormattableMarkup
*/
private function abbrClass($class) {
$parts = explode('\\', $class);
$short = array_pop($parts);
if (strlen($short) >= 40) {
$short = substr($short, 0, 30) . " … " . substr($short, -5);
}
return new FormattableMarkup('<abbr title="@class">@short</abbr>', [
'@class' => $class,
'@short' => $short,
]);
}
/**
* @param \Drupal\xhprof\XHProfLib\Report\ReportInterface $report
* @param array $descriptions
*
* @return array
*/
private function getRunHeader(ReportInterface $report, $descriptions, $run_id) {
$headers = [
'fn',
'ct',
'ct_perc',
];
$metrics = $report
->getMetrics();
foreach ($metrics as $metric) {
$headers[] = $metric;
$headers[] = $metric . '_perc';
$headers[] = 'excl_' . $metric;
$headers[] = 'excl_' . $metric . '_perc';
}
$sortable = ReportConstants::getSortableColumns();
foreach ($headers as &$header) {
if (isset($sortable[$header])) {
$header = [
'data' => Link::createFromRoute($descriptions[$header], 'xhprof.run', [
'run' => $run_id,
], [
'query' => [
'sort' => $header,
],
])
->toRenderable(),
];
}
else {
$header = new FormattableMarkup($descriptions[$header], []);
}
}
return $headers;
}
/**
* @param \Drupal\xhprof\XHProfLib\Run $run
* @param \Drupal\xhprof\XHProfLib\Report\ReportInterface $report
* @param int $length
*
* @return array
*/
private function getRunRows(Run $run, ReportInterface $report, $length, ReportInterface $globalReport = NULL, $symbol = NULL) {
$rows = [];
$runId = $run
->getId();
$symbols = $report
->getSymbols($length);
if ($symbol) {
$globalSymbols = $globalReport
->getSymbols(-1);
// Add the current function in the table.
$this
->getCurrentFunctionRows($globalSymbols[$symbol], $rows);
// Add parent functions in the table.
$runSymbols = $run
->getSymbols();
$parents = [];
$children = [];
foreach ($runSymbols as $value) {
if ($value
->getChild() == $symbol && ($parent = $value
->getParent())) {
$parents[$parent] = $globalSymbols[$parent];
}
elseif ($value
->getParent() == $symbol && ($child = $value
->getChild())) {
$children[$child] = $value;
}
}
$this
->getParentFunctionsRows($parents, $runId, $rows);
if (\count($children)) {
$columns = \current($symbols);
$rows[] = [
[
'data' => new FormattableMarkup('<strong>@value</strong>', [
'@value' => $this
->formatPlural(\count($children), 'Child function', 'Child functions (@count)'),
]),
'colspan' => \count($columns),
],
];
}
}
foreach ($symbols as $value) {
// If its a symbol table, display only the children in the list.
if (!$symbol || !empty($children[$value[0]])) {
$text = $value[0];
$url = Url::fromRoute('xhprof.symbol', [
'run' => $runId,
'symbol' => $value[0],
]);
$value[0] = Link::fromTextAndUrl($text, $url)
->toString();
$rows[] = $value;
}
}
return $rows;
}
private function getCurrentFunctionRows($symbol, &$rows) {
$rows[] = [
[
'data' => new FormattableMarkup('<strong>@value</strong>', [
'@value' => $this
->t('Current function'),
]),
'colspan' => \count($symbol),
],
];
$symbol[0] = Link::fromTextAndUrl($symbol[0], Url::fromRoute('<current>'));
$rows[] = $symbol;
return $rows;
}
private function getParentFunctionsRows($parents, $runId, &$rows) {
if (!empty($parents)) {
$columns = \current($parents);
$rows[] = [
[
'data' => new FormattableMarkup('<strong>@value</strong>', [
'@value' => $this
->formatPlural(\count($parents), 'Parent function', 'Parent functions (@count)'),
]),
'colspan' => \count($columns),
],
];
foreach ($parents as $parent) {
$parent[0] = Link::fromTextAndUrl($parent[0], Url::fromRoute('xhprof.symbol', [
'run' => $runId,
'symbol' => $parent[0],
]));
$rows[] = $parent;
}
}
return $rows;
}
/**
* @param \Drupal\xhprof\XHProfLib\Report\ReportInterface $report
* @param array $descriptions
*
* @return array
*/
private function getSummaryRows(ReportInterface $report, $descriptions) {
$summaryRows = [];
$possibileMetrics = $report
->getPossibleMetrics();
foreach ($report
->getSummary() as $metric => $value) {
$key = 'Total ' . Xss::filter($descriptions[$metric], []);
$unit = isset($possibileMetrics[$metric]) ? $possibileMetrics[$metric][1] : '';
$value = new FormattableMarkup('@value @unit', [
'@value' => $value,
'@unit' => $unit,
]);
$summaryRows[] = [
$key,
$value,
];
}
return $summaryRows;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ControllerBase:: |
protected | property | The configuration factory. | |
ControllerBase:: |
protected | property | The current user service. | 1 |
ControllerBase:: |
protected | property | The entity form builder. | |
ControllerBase:: |
protected | property | The entity manager. | |
ControllerBase:: |
protected | property | The entity type manager. | |
ControllerBase:: |
protected | property | The form builder. | 2 |
ControllerBase:: |
protected | property | The key-value storage. | 1 |
ControllerBase:: |
protected | property | The language manager. | 1 |
ControllerBase:: |
protected | property | The module handler. | 2 |
ControllerBase:: |
protected | property | The state service. | |
ControllerBase:: |
protected | function | Returns the requested cache bin. | |
ControllerBase:: |
protected | function | Retrieves a configuration object. | |
ControllerBase:: |
private | function | Returns the service container. | |
ControllerBase:: |
protected | function | Returns the current user. | 1 |
ControllerBase:: |
protected | function | Retrieves the entity form builder. | |
ControllerBase:: |
protected | function | Retrieves the entity manager service. | |
ControllerBase:: |
protected | function | Retrieves the entity type manager. | |
ControllerBase:: |
protected | function | Returns the form builder service. | 2 |
ControllerBase:: |
protected | function | Returns a key/value storage collection. | 1 |
ControllerBase:: |
protected | function | Returns the language manager service. | 1 |
ControllerBase:: |
protected | function | Returns the module handler. | 2 |
ControllerBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
ControllerBase:: |
protected | function | Returns the state storage service. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. | |
XHProfController:: |
private | property | The date formatter. | |
XHProfController:: |
private | property | The profiler. | |
XHProfController:: |
private | property | The report engine. | |
XHProfController:: |
private | function | ||
XHProfController:: |
public static | function |
Instantiates a new instance of this class. Overrides ControllerBase:: |
|
XHProfController:: |
public | function | Renders diff of two runs. | |
XHProfController:: |
private | function | ||
XHProfController:: |
private | function | ||
XHProfController:: |
private | function | ||
XHProfController:: |
private | function | ||
XHProfController:: |
private | function | ||
XHProfController:: |
public | function | Renders the run. | |
XHProfController:: |
public | function | Returns list of runs. | |
XHProfController:: |
public | function |