vendor/symfony/cache/DataCollector/CacheDataCollector.php line 39

  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Cache\DataCollector;
  11. use Symfony\Component\Cache\Adapter\TraceableAdapter;
  12. use Symfony\Component\Cache\Adapter\TraceableAdapterEvent;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\HttpKernel\DataCollector\DataCollector;
  16. use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
  17. /**
  18.  * @author Aaron Scherer <aequasi@gmail.com>
  19.  * @author Tobias Nyholm <tobias.nyholm@gmail.com>
  20.  *
  21.  * @final
  22.  */
  23. class CacheDataCollector extends DataCollector implements LateDataCollectorInterface
  24. {
  25.     /**
  26.      * @var TraceableAdapter[]
  27.      */
  28.     private array $instances = [];
  29.     public function addInstance(string $nameTraceableAdapter $instance)
  30.     {
  31.         $this->instances[$name] = $instance;
  32.     }
  33.     public function collect(Request $requestResponse $response\Throwable $exception null)
  34.     {
  35.         $empty = ['calls' => [], 'adapters' => [], 'config' => [], 'options' => [], 'statistics' => []];
  36.         $this->data = ['instances' => $empty'total' => $empty];
  37.         foreach ($this->instances as $name => $instance) {
  38.             $this->data['instances']['calls'][$name] = $instance->getCalls();
  39.             $this->data['instances']['adapters'][$name] = get_debug_type($instance->getPool());
  40.         }
  41.         $this->data['instances']['statistics'] = $this->calculateStatistics();
  42.         $this->data['total']['statistics'] = $this->calculateTotalStatistics();
  43.     }
  44.     public function reset()
  45.     {
  46.         $this->data = [];
  47.         foreach ($this->instances as $instance) {
  48.             $instance->clearCalls();
  49.         }
  50.     }
  51.     public function lateCollect()
  52.     {
  53.         $this->data['instances']['calls'] = $this->cloneVar($this->data['instances']['calls']);
  54.     }
  55.     public function getName(): string
  56.     {
  57.         return 'cache';
  58.     }
  59.     /**
  60.      * Method returns amount of logged Cache reads: "get" calls.
  61.      */
  62.     public function getStatistics(): array
  63.     {
  64.         return $this->data['instances']['statistics'];
  65.     }
  66.     /**
  67.      * Method returns the statistic totals.
  68.      */
  69.     public function getTotals(): array
  70.     {
  71.         return $this->data['total']['statistics'];
  72.     }
  73.     /**
  74.      * Method returns all logged Cache call objects.
  75.      */
  76.     public function getCalls(): mixed
  77.     {
  78.         return $this->data['instances']['calls'];
  79.     }
  80.     /**
  81.      * Method returns all logged Cache adapter classes.
  82.      */
  83.     public function getAdapters(): array
  84.     {
  85.         return $this->data['instances']['adapters'];
  86.     }
  87.     private function calculateStatistics(): array
  88.     {
  89.         $statistics = [];
  90.         foreach ($this->data['instances']['calls'] as $name => $calls) {
  91.             $statistics[$name] = [
  92.                 'calls' => 0,
  93.                 'time' => 0,
  94.                 'reads' => 0,
  95.                 'writes' => 0,
  96.                 'deletes' => 0,
  97.                 'hits' => 0,
  98.                 'misses' => 0,
  99.             ];
  100.             /** @var TraceableAdapterEvent $call */
  101.             foreach ($calls as $call) {
  102.                 ++$statistics[$name]['calls'];
  103.                 $statistics[$name]['time'] += ($call->end ?? microtime(true)) - $call->start;
  104.                 if ('get' === $call->name) {
  105.                     ++$statistics[$name]['reads'];
  106.                     if ($call->hits) {
  107.                         ++$statistics[$name]['hits'];
  108.                     } else {
  109.                         ++$statistics[$name]['misses'];
  110.                         ++$statistics[$name]['writes'];
  111.                     }
  112.                 } elseif ('getItem' === $call->name) {
  113.                     ++$statistics[$name]['reads'];
  114.                     if ($call->hits) {
  115.                         ++$statistics[$name]['hits'];
  116.                     } else {
  117.                         ++$statistics[$name]['misses'];
  118.                     }
  119.                 } elseif ('getItems' === $call->name) {
  120.                     $statistics[$name]['reads'] += $call->hits $call->misses;
  121.                     $statistics[$name]['hits'] += $call->hits;
  122.                     $statistics[$name]['misses'] += $call->misses;
  123.                 } elseif ('hasItem' === $call->name) {
  124.                     ++$statistics[$name]['reads'];
  125.                     foreach ($call->result ?? [] as $result) {
  126.                         ++$statistics[$name][$result 'hits' 'misses'];
  127.                     }
  128.                 } elseif ('save' === $call->name) {
  129.                     ++$statistics[$name]['writes'];
  130.                 } elseif ('deleteItem' === $call->name) {
  131.                     ++$statistics[$name]['deletes'];
  132.                 }
  133.             }
  134.             if ($statistics[$name]['reads']) {
  135.                 $statistics[$name]['hit_read_ratio'] = round(100 $statistics[$name]['hits'] / $statistics[$name]['reads'], 2);
  136.             } else {
  137.                 $statistics[$name]['hit_read_ratio'] = null;
  138.             }
  139.         }
  140.         return $statistics;
  141.     }
  142.     private function calculateTotalStatistics(): array
  143.     {
  144.         $statistics $this->getStatistics();
  145.         $totals = [
  146.             'calls' => 0,
  147.             'time' => 0,
  148.             'reads' => 0,
  149.             'writes' => 0,
  150.             'deletes' => 0,
  151.             'hits' => 0,
  152.             'misses' => 0,
  153.         ];
  154.         foreach ($statistics as $name => $values) {
  155.             foreach ($totals as $key => $value) {
  156.                 $totals[$key] += $statistics[$name][$key];
  157.             }
  158.         }
  159.         if ($totals['reads']) {
  160.             $totals['hit_read_ratio'] = round(100 $totals['hits'] / $totals['reads'], 2);
  161.         } else {
  162.             $totals['hit_read_ratio'] = null;
  163.         }
  164.         return $totals;
  165.     }
  166. }