4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\HttpKernel\EventListener;
14 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15 use Symfony\Component\HttpFoundation\RequestMatcherInterface;
16 use Symfony\Component\HttpFoundation\RequestStack;
17 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
18 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
19 use Symfony\Component\HttpKernel\Event\PostResponseEvent;
20 use Symfony\Component\HttpKernel\KernelEvents;
21 use Symfony\Component\HttpKernel\Profiler\Profiler;
24 * ProfilerListener collects data for the current request by listening to the kernel events.
26 * @author Fabien Potencier <fabien@symfony.com>
28 class ProfilerListener implements EventSubscriberInterface
32 protected $onlyException;
33 protected $onlyMasterRequests;
36 protected $requestStack;
40 * @param Profiler $profiler A Profiler instance
41 * @param RequestStack $requestStack A RequestStack instance
42 * @param RequestMatcherInterface|null $matcher A RequestMatcher instance
43 * @param bool $onlyException True if the profiler only collects data when an exception occurs, false otherwise
44 * @param bool $onlyMasterRequests True if the profiler only collects data when the request is a master request, false otherwise
46 public function __construct(Profiler $profiler, RequestStack $requestStack, RequestMatcherInterface $matcher = null, $onlyException = false, $onlyMasterRequests = false)
48 $this->profiler = $profiler;
49 $this->matcher = $matcher;
50 $this->onlyException = (bool) $onlyException;
51 $this->onlyMasterRequests = (bool) $onlyMasterRequests;
52 $this->profiles = new \SplObjectStorage();
53 $this->parents = new \SplObjectStorage();
54 $this->requestStack = $requestStack;
58 * Handles the onKernelException event.
60 public function onKernelException(GetResponseForExceptionEvent $event)
62 if ($this->onlyMasterRequests && !$event->isMasterRequest()) {
66 $this->exception = $event->getException();
70 * Handles the onKernelResponse event.
72 public function onKernelResponse(FilterResponseEvent $event)
74 $master = $event->isMasterRequest();
75 if ($this->onlyMasterRequests && !$master) {
79 if ($this->onlyException && null === $this->exception) {
83 $request = $event->getRequest();
84 $exception = $this->exception;
85 $this->exception = null;
87 if (null !== $this->matcher && !$this->matcher->matches($request)) {
91 if (!$profile = $this->profiler->collect($request, $event->getResponse(), $exception)) {
95 $this->profiles[$request] = $profile;
97 $this->parents[$request] = $this->requestStack->getParentRequest();
100 public function onKernelTerminate(PostResponseEvent $event)
102 // attach children to parents
103 foreach ($this->profiles as $request) {
104 if (null !== $parentRequest = $this->parents[$request]) {
105 if (isset($this->profiles[$parentRequest])) {
106 $this->profiles[$parentRequest]->addChild($this->profiles[$request]);
112 foreach ($this->profiles as $request) {
113 $this->profiler->saveProfile($this->profiles[$request]);
116 $this->profiles = new \SplObjectStorage();
117 $this->parents = new \SplObjectStorage();
120 public static function getSubscribedEvents()
123 KernelEvents::RESPONSE => array('onKernelResponse', -100),
124 KernelEvents::EXCEPTION => 'onKernelException',
125 KernelEvents::TERMINATE => array('onKernelTerminate', -1024),