TimeDataCollector.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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\HttpKernel\DataCollector;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpFoundation\Response;
  13. use Symfony\Component\HttpKernel\KernelInterface;
  14. use Symfony\Component\Stopwatch\Stopwatch;
  15. use Symfony\Component\Stopwatch\StopwatchEvent;
  16. /**
  17. * @author Fabien Potencier <fabien@symfony.com>
  18. *
  19. * @final
  20. */
  21. class TimeDataCollector extends DataCollector implements LateDataCollectorInterface
  22. {
  23. public function __construct(
  24. private readonly ?KernelInterface $kernel = null,
  25. private readonly ?Stopwatch $stopwatch = null,
  26. ) {
  27. $this->data = ['events' => [], 'stopwatch_installed' => false, 'start_time' => 0];
  28. }
  29. public function collect(Request $request, Response $response, ?\Throwable $exception = null): void
  30. {
  31. if (null !== $this->kernel) {
  32. $startTime = $this->kernel->getStartTime();
  33. } else {
  34. $startTime = $request->server->get('REQUEST_TIME_FLOAT');
  35. }
  36. $this->data = [
  37. 'token' => $request->attributes->get('_stopwatch_token'),
  38. 'start_time' => $startTime * 1000,
  39. 'events' => [],
  40. 'stopwatch_installed' => class_exists(Stopwatch::class, false),
  41. ];
  42. }
  43. public function reset(): void
  44. {
  45. $this->data = ['events' => [], 'stopwatch_installed' => false, 'start_time' => 0];
  46. $this->stopwatch?->reset();
  47. }
  48. public function lateCollect(): void
  49. {
  50. if (null !== $this->stopwatch && isset($this->data['token'])) {
  51. $this->setEvents($this->stopwatch->getSectionEvents($this->data['token']));
  52. }
  53. unset($this->data['token']);
  54. }
  55. /**
  56. * @param StopwatchEvent[] $events The request events
  57. */
  58. public function setEvents(array $events): void
  59. {
  60. foreach ($events as $event) {
  61. $event->ensureStopped();
  62. }
  63. $this->data['events'] = $events;
  64. }
  65. /**
  66. * @return StopwatchEvent[]
  67. */
  68. public function getEvents(): array
  69. {
  70. return $this->data['events'];
  71. }
  72. /**
  73. * Gets the request elapsed time.
  74. */
  75. public function getDuration(): float
  76. {
  77. if (!isset($this->data['events']['__section__'])) {
  78. return 0;
  79. }
  80. $lastEvent = $this->data['events']['__section__'];
  81. return $lastEvent->getOrigin() + $lastEvent->getDuration() - $this->getStartTime();
  82. }
  83. /**
  84. * Gets the initialization time.
  85. *
  86. * This is the time spent until the beginning of the request handling.
  87. */
  88. public function getInitTime(): float
  89. {
  90. if (!isset($this->data['events']['__section__'])) {
  91. return 0;
  92. }
  93. return $this->data['events']['__section__']->getOrigin() - $this->getStartTime();
  94. }
  95. public function getStartTime(): float
  96. {
  97. return $this->data['start_time'];
  98. }
  99. public function isStopwatchInstalled(): bool
  100. {
  101. return $this->data['stopwatch_installed'];
  102. }
  103. public function getName(): string
  104. {
  105. return 'time';
  106. }
  107. }