vendor/ekino/newrelic-bundle/Listener/ResponseListener.php line 56

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of Ekino New Relic bundle.
  5.  *
  6.  * (c) Ekino - Thomas Rabaix <thomas.rabaix@ekino.com>
  7.  *
  8.  * For the full copyright and license information, please view the LICENSE
  9.  * file that was distributed with this source code.
  10.  */
  11. namespace Ekino\NewRelicBundle\Listener;
  12. use Ekino\NewRelicBundle\NewRelic\Config;
  13. use Ekino\NewRelicBundle\NewRelic\NewRelicInteractorInterface;
  14. use Ekino\NewRelicBundle\Twig\NewRelicExtension;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. use Symfony\Component\HttpFoundation\StreamedResponse;
  17. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  18. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  19. use Symfony\Component\HttpKernel\KernelEvents;
  20. class ResponseListener implements EventSubscriberInterface
  21. {
  22.     private $newRelic;
  23.     private $interactor;
  24.     private $instrument;
  25.     private $symfonyCache;
  26.     private $newRelicTwigExtension;
  27.     public function __construct(
  28.         Config $newRelic,
  29.         NewRelicInteractorInterface $interactor,
  30.         bool $instrument false,
  31.         bool $symfonyCache false,
  32.         NewRelicExtension $newRelicTwigExtension null
  33.     ) {
  34.         $this->newRelic $newRelic;
  35.         $this->interactor $interactor;
  36.         $this->instrument $instrument;
  37.         $this->symfonyCache $symfonyCache;
  38.         $this->newRelicTwigExtension $newRelicTwigExtension;
  39.     }
  40.     public static function getSubscribedEvents(): array
  41.     {
  42.         return [
  43.             KernelEvents::RESPONSE => [
  44.                 ['onKernelResponse', -255],
  45.             ],
  46.         ];
  47.     }
  48.     public function onKernelResponse(KernelResponseEvent $event): void
  49.     {
  50.         $isMainRequest method_exists($event'isMainRequest') ? $event->isMainRequest() : $event->isMasterRequest();
  51.         if (!$isMainRequest) {
  52.             return;
  53.         }
  54.         if (null === $this->newRelicTwigExtension || false === $this->newRelicTwigExtension->isUsed()) {
  55.             foreach ($this->newRelic->getCustomMetrics() as $name => $value) {
  56.                 $this->interactor->addCustomMetric((string) $name, (float) $value);
  57.             }
  58.             foreach ($this->newRelic->getCustomParameters() as $name => $value) {
  59.                 $this->interactor->addCustomParameter((string) $name$value);
  60.             }
  61.         }
  62.         foreach ($this->newRelic->getCustomEvents() as $name => $events) {
  63.             foreach ($events as $attributes) {
  64.                 $this->interactor->addCustomEvent((string) $name$attributes);
  65.             }
  66.         }
  67.         if ($this->instrument) {
  68.             if (null === $this->newRelicTwigExtension || false === $this->newRelicTwigExtension->isUsed()) {
  69.                 $this->interactor->disableAutoRUM();
  70.             }
  71.             // Some requests might not want to get instrumented
  72.             if ($event->getRequest()->attributes->get('_instrument'true)) {
  73.                 $response $event->getResponse();
  74.                 // We can only instrument HTML responses
  75.                 if (!$response instanceof StreamedResponse
  76.                     && 'text/html' === substr($response->headers->get('Content-Type'''), 09)
  77.                 ) {
  78.                     $responseContent $response->getContent();
  79.                     $response->setContent(''); // free the memory
  80.                     if (null === $this->newRelicTwigExtension || false === $this->newRelicTwigExtension->isHeaderCalled()) {
  81.                         $responseContent preg_replace('|<head>|i''$0'.$this->interactor->getBrowserTimingHeader(), $responseContent);
  82.                     }
  83.                     if (null === $this->newRelicTwigExtension || false === $this->newRelicTwigExtension->isFooterCalled()) {
  84.                         $responseContent preg_replace('|</body>|i'$this->interactor->getBrowserTimingFooter().'$0'$responseContent);
  85.                     }
  86.                     $response->setContent($responseContent);
  87.                 }
  88.             }
  89.         }
  90.         if ($this->symfonyCache) {
  91.             $this->interactor->endTransaction();
  92.         }
  93.     }
  94. }
  95. if (!class_exists(KernelResponseEvent::class)) {
  96.     if (class_exists(ResponseEvent::class)) {
  97.         class_alias(ResponseEvent::class, KernelResponseEvent::class);
  98.     } else {
  99.         class_alias(FilterResponseEvent::class, KernelResponseEvent::class);
  100.     }
  101. }