vendor/doctrine/doctrine-bundle/DataCollector/DoctrineDataCollector.php line 61

Open in your IDE?
  1. <?php
  2. namespace Doctrine\Bundle\DoctrineBundle\DataCollector;
  3. use Doctrine\Common\Persistence\ManagerRegistry;
  4. use Doctrine\ORM\Cache\Logging\CacheLoggerChain;
  5. use Doctrine\ORM\Cache\Logging\StatisticsCacheLogger;
  6. use Doctrine\ORM\Configuration;
  7. use Doctrine\ORM\EntityManager;
  8. use Doctrine\ORM\Mapping\ClassMetadataFactory;
  9. use Doctrine\ORM\Mapping\ClassMetadataInfo;
  10. use Doctrine\ORM\Tools\SchemaValidator;
  11. use Exception;
  12. use Symfony\Bridge\Doctrine\DataCollector\DoctrineDataCollector as BaseCollector;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. class DoctrineDataCollector extends BaseCollector
  16. {
  17.     /** @var ManagerRegistry */
  18.     private $registry;
  19.     /** @var int|null */
  20.     private $invalidEntityCount;
  21.     /** @var string[] */
  22.     private $groupedQueries;
  23.     public function __construct(ManagerRegistry $registry)
  24.     {
  25.         $this->registry $registry;
  26.         parent::__construct($registry);
  27.     }
  28.     /**
  29.      * {@inheritdoc}
  30.      */
  31.     public function collect(Request $requestResponse $responseException $exception null)
  32.     {
  33.         parent::collect($request$response$exception);
  34.         $errors   = [];
  35.         $entities = [];
  36.         $caches   = [
  37.             'enabled' => false,
  38.             'log_enabled' => false,
  39.             'counts' => [
  40.                 'puts' => 0,
  41.                 'hits' => 0,
  42.                 'misses' => 0,
  43.             ],
  44.             'regions' => [
  45.                 'puts' => [],
  46.                 'hits' => [],
  47.                 'misses' => [],
  48.             ],
  49.         ];
  50.         /** @var EntityManager $em */
  51.         foreach ($this->registry->getManagers() as $name => $em) {
  52.             $entities[$name] = [];
  53.             /** @var ClassMetadataFactory $factory */
  54.             $factory   $em->getMetadataFactory();
  55.             $validator = new SchemaValidator($em);
  56.             /** @var ClassMetadataInfo $class */
  57.             foreach ($factory->getLoadedMetadata() as $class) {
  58.                 if (isset($entities[$name][$class->getName()])) {
  59.                     continue;
  60.                 }
  61.                 $classErrors                        $validator->validateClass($class);
  62.                 $entities[$name][$class->getName()] = $class->getName();
  63.                 if (empty($classErrors)) {
  64.                     continue;
  65.                 }
  66.                 $errors[$name][$class->getName()] = $classErrors;
  67.             }
  68.             /** @var Configuration $emConfig */
  69.             $emConfig   $em->getConfiguration();
  70.             $slcEnabled $emConfig->isSecondLevelCacheEnabled();
  71.             if (! $slcEnabled) {
  72.                 continue;
  73.             }
  74.             $caches['enabled'] = true;
  75.             /** @var $cacheConfiguration \Doctrine\ORM\Cache\CacheConfiguration */
  76.             /** @var CacheLoggerChain $cacheLoggerChain */
  77.             $cacheConfiguration $emConfig->getSecondLevelCacheConfiguration();
  78.             $cacheLoggerChain   $cacheConfiguration->getCacheLogger();
  79.             if (! $cacheLoggerChain || ! $cacheLoggerChain->getLogger('statistics')) {
  80.                 continue;
  81.             }
  82.             /** @var StatisticsCacheLogger $cacheLoggerStats */
  83.             $cacheLoggerStats      $cacheLoggerChain->getLogger('statistics');
  84.             $caches['log_enabled'] = true;
  85.             $caches['counts']['puts']   += $cacheLoggerStats->getPutCount();
  86.             $caches['counts']['hits']   += $cacheLoggerStats->getHitCount();
  87.             $caches['counts']['misses'] += $cacheLoggerStats->getMissCount();
  88.             foreach ($cacheLoggerStats->getRegionsPut() as $key => $value) {
  89.                 if (! isset($caches['regions']['puts'][$key])) {
  90.                     $caches['regions']['puts'][$key] = 0;
  91.                 }
  92.                 $caches['regions']['puts'][$key] += $value;
  93.             }
  94.             foreach ($cacheLoggerStats->getRegionsHit() as $key => $value) {
  95.                 if (! isset($caches['regions']['hits'][$key])) {
  96.                     $caches['regions']['hits'][$key] = 0;
  97.                 }
  98.                 $caches['regions']['hits'][$key] += $value;
  99.             }
  100.             foreach ($cacheLoggerStats->getRegionsMiss() as $key => $value) {
  101.                 if (! isset($caches['regions']['misses'][$key])) {
  102.                     $caches['regions']['misses'][$key] = 0;
  103.                 }
  104.                 $caches['regions']['misses'][$key] += $value;
  105.             }
  106.         }
  107.         // Might be good idea to replicate this block in doctrine bridge so we can drop this from here after some time.
  108.         // This code is compatible with such change, because cloneVar is supposed to check if input is already cloned.
  109.         foreach ($this->data['queries'] as &$queries) {
  110.             foreach ($queries as &$query) {
  111.                 $query['params'] = $this->cloneVar($query['params']);
  112.             }
  113.         }
  114.         $this->data['entities'] = $entities;
  115.         $this->data['errors']   = $errors;
  116.         $this->data['caches']   = $caches;
  117.         $this->groupedQueries   null;
  118.     }
  119.     public function getEntities()
  120.     {
  121.         return $this->data['entities'];
  122.     }
  123.     public function getMappingErrors()
  124.     {
  125.         return $this->data['errors'];
  126.     }
  127.     public function getCacheHitsCount()
  128.     {
  129.         return $this->data['caches']['counts']['hits'];
  130.     }
  131.     public function getCachePutsCount()
  132.     {
  133.         return $this->data['caches']['counts']['puts'];
  134.     }
  135.     public function getCacheMissesCount()
  136.     {
  137.         return $this->data['caches']['counts']['misses'];
  138.     }
  139.     public function getCacheEnabled()
  140.     {
  141.         return $this->data['caches']['enabled'];
  142.     }
  143.     public function getCacheRegions()
  144.     {
  145.         return $this->data['caches']['regions'];
  146.     }
  147.     public function getCacheCounts()
  148.     {
  149.         return $this->data['caches']['counts'];
  150.     }
  151.     public function getInvalidEntityCount()
  152.     {
  153.         if ($this->invalidEntityCount === null) {
  154.             $this->invalidEntityCount array_sum(array_map('count'$this->data['errors']));
  155.         }
  156.         return $this->invalidEntityCount;
  157.     }
  158.     public function getGroupedQueries()
  159.     {
  160.         if ($this->groupedQueries !== null) {
  161.             return $this->groupedQueries;
  162.         }
  163.         $this->groupedQueries = [];
  164.         $totalExecutionMS     0;
  165.         foreach ($this->data['queries'] as $connection => $queries) {
  166.             $connectionGroupedQueries = [];
  167.             foreach ($queries as $i => $query) {
  168.                 $key $query['sql'];
  169.                 if (! isset($connectionGroupedQueries[$key])) {
  170.                     $connectionGroupedQueries[$key]                = $query;
  171.                     $connectionGroupedQueries[$key]['executionMS'] = 0;
  172.                     $connectionGroupedQueries[$key]['count']       = 0;
  173.                     $connectionGroupedQueries[$key]['index']       = $i// "Explain query" relies on query index in 'queries'.
  174.                 }
  175.                 $connectionGroupedQueries[$key]['executionMS'] += $query['executionMS'];
  176.                 $connectionGroupedQueries[$key]['count']++;
  177.                 $totalExecutionMS += $query['executionMS'];
  178.             }
  179.             usort($connectionGroupedQueries, static function ($a$b) {
  180.                 if ($a['executionMS'] === $b['executionMS']) {
  181.                     return 0;
  182.                 }
  183.                 return $a['executionMS'] < $b['executionMS'] ? : -1;
  184.             });
  185.             $this->groupedQueries[$connection] = $connectionGroupedQueries;
  186.         }
  187.         foreach ($this->groupedQueries as $connection => $queries) {
  188.             foreach ($queries as $i => $query) {
  189.                 $this->groupedQueries[$connection][$i]['executionPercent'] =
  190.                     $this->executionTimePercentage($query['executionMS'], $totalExecutionMS);
  191.             }
  192.         }
  193.         return $this->groupedQueries;
  194.     }
  195.     private function executionTimePercentage($executionTimeMS$totalExecutionTimeMS)
  196.     {
  197.         if ($totalExecutionTimeMS === 0.0 || $totalExecutionTimeMS === 0) {
  198.             return 0;
  199.         }
  200.         return $executionTimeMS $totalExecutionTimeMS 100;
  201.     }
  202.     public function getGroupedQueryCount()
  203.     {
  204.         $count 0;
  205.         foreach ($this->getGroupedQueries() as $connectionGroupedQueries) {
  206.             $count += count($connectionGroupedQueries);
  207.         }
  208.         return $count;
  209.     }
  210. }