qtools_profiler-8.x-1.x-dev/src/Plugin/Profiler/TidewaysXhprof.php

src/Plugin/Profiler/TidewaysXhprof.php
<?php

namespace Drupal\qtools_profiler\Plugin\Profiler;

use Drupal\Component\Plugin\PluginBase;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Url;
use Drupal\qtools_profiler\ProfilerPluginInterface;
use Drupal\qtools_profiler\XHProfLib\Parser\Parser;
use Drupal\qtools_profiler\XHProfLib\Report\Report;
use Drupal\qtools_profiler\XHProfLib\Report\ReportConstants;
use Drupal\qtools_profiler\XHProfLib\Report\ReportInterface;
use Drupal\qtools_profiler\XHProfLib\Run;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Provides TidewaysXhprof profiler plugin.
 *
 * @Plugin(
 *   id = "tideways_xhprof",
 *   label = @Translation("Tideways xhprof"),
 *   description = @Translation("Tideways xhprof php profiler.")
 * )
 */
class TidewaysXhprof extends PluginBase implements ProfilerPluginInterface {

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public static function isLoaded() {
    return extension_loaded('tideways_xhprof');
  }

  /**
   * {@inheritdoc}
   */
  public function getSettingsForm(array $conf) {
    $profiler_options = [
      'FLAGS_CPU' => t('FLAGS_CPU'),
      'FLAGS_MEMORY' => t('FLAGS_MEMORY'),
    ];
    $form['options'] = [
      '#type' => 'checkboxes',
      '#title' => t('Profiling options'),
      '#default_value' => $conf['profiling']['profilers']['tideways_xhprof']['options'] ?? [],
      '#options' => $profiler_options,
      '#description' => t('Support depends on particular extension'),
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function enable($options) {
    if (!static::isLoaded()) {
      return;
    }

    $flags = 0;
    if (!empty($options['options']['FLAGS_CPU'])) {
      $flags = $flags | TIDEWAYS_XHPROF_FLAGS_CPU;
    }
    if (!empty($options['options']['FLAGS_MEMORY'])) {
      $flags = $flags | TIDEWAYS_XHPROF_FLAGS_MEMORY;
    }
    tideways_xhprof_enable($flags);
  }

  /**
   * {@inheritdoc}
   */
  public function disable() {
    if (!static::isLoaded()) {
      return [];
    }

    return tideways_xhprof_disable();
  }

  /**
   * {@inheritdoc}
   */
  public function buildProfilePage(Request $request, $id) {

    $route_name = $request->attributes->get('_route');

    // Build run from data.
    $reportService = \Drupal::service('qtools_profiler.report');
    $data = $reportService->getProfileDetails($id);
    if (empty($data)) {
      throw new NotFoundHttpException();
    }

    // Parse run.
    $run = new Run($id, 'space', $data);

    // Get filter/sort.
    $length = $request->get('length', 100);
    $sort = $request->get('sort', 'excl_wt');

    $parser = new Parser($run, $sort, NULL);
    $report = new Report($parser);
    $build['#title'] = t('XHProf view report for %id', ['%id' => $run->getId()]);
    $descriptions = ReportConstants::getDescriptions();

    $build['summary'] = [
      'title' => [
        '#type' => 'inline_template',
        '#template' => '<h3>Summary</h3>',
      ],
      'table' => [
        '#theme' => 'table',
        '#header' => [],
        '#rows' => $this->getSummaryRows($report, $descriptions),
      ],
    ];

    $build['length'] = [
      '#type' => 'inline_template',
      '#template' => ($length == -1) ? '<h3>Displaying all functions, sorted by <em>{{ sort }}</em>.</h3>' : '<h3>Displaying top {{ length }} functions, sorted by {{ sort }}. [{{ all }}]</h3>',
      '#context' => [
        'length' => $length,
        'all' => \Drupal::service('link_generator')->generate(t('show all'), Url::fromRoute($route_name, [
          'id' => $run->getId(),
          'length' => -1,
        ])),
        'sort' => Xss::filter($descriptions[$sort], []),
      ],
    ];

    $build['table'] = [
      '#theme' => 'table',
      '#header' => $this->getRunHeader($report, $descriptions, $run, $route_name),
      '#rows' => $this->getRunRows($report, $length),
      '#attributes' => ['class' => ['responsive']],
    ];

    return $build;
  }

  /**
   * Get rows summary from report.
   */
  protected 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;
  }

  /**
   * Ger run header from report.
   */
  protected function getRunHeader(ReportInterface $report, $descriptions, Run $run, $route_name) {
    $headers = ['fn', 'ct', 'ct_perc'];

    $metrics = $report->getMetrics();

    foreach ($metrics as $metric) {
      $headers[] = $metric;
      $headers[] = $metric . '_perc';
      $headers[] = 'excl_' . $metric;
      $headers[] = 'excl_' . $metric . '_perc';
    }

    foreach ($headers as &$header) {
      $description = strip_tags($descriptions[$header]);
      $link = \Drupal::service('link_generator')->generate($description, Url::fromRoute($route_name, [
        'id' => $run->getId(),
        'length' => -1,
        'sort' => str_replace('_perc', '', $header),
      ]));
      $header = new FormattableMarkup($link, []);
    }

    return $headers;
  }

  /**
   * Get run Rows from report.
   */
  protected function getRunRows(ReportInterface $report, $length) {
    $symbols = $report->getSymbols($length);

    foreach ($symbols as &$symbol) {
      $symbol[0] = $this->abbrClass($symbol[0]);
    }

    return $symbols;
  }

  /**
   * Theme class.
   */
  protected 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,
    ]);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc