Display orphaned events in profiler

This commit is contained in:
Mateusz Sip 2017-10-01 22:31:12 +02:00 committed by Fabien Potencier
parent 07766b3905
commit 509f9a9233
11 changed files with 142 additions and 11 deletions

View File

@ -1,6 +1,11 @@
UPGRADE FROM 4.0 to 4.1
=======================
EventDispatcher
---------------
* The `TraceableEventDispatcherInterface` has been deprecated and will be removed in 5.0.
HttpFoundation
--------------

View File

@ -1,6 +1,11 @@
UPGRADE FROM 4.x to 5.0
=======================
EventDispatcher
---------------
* The `TraceableEventDispatcherInterface` has been removed.
HttpFoundation
--------------

View File

@ -1,6 +1,11 @@
CHANGELOG
=========
4.1.0
-----
* added information about orphaned events
4.0.0
-----

View File

@ -45,6 +45,26 @@
{% endif %}
</div>
</div>
<div class="tab">
<h3 class="tab-title">Orphaned events <span class="badge">{{ collector.orphanedEvents|length }}</span></h3>
<div class="tab-content">
{% if collector.orphanedEvents is empty %}
<div class="empty">
<p>
<strong>There are no orphaned events</strong>.
</p>
<p>
All dispatched events were handled or an error occurred
when trying to collect orphaned events (in which case check the
logs to get more information).
</p>
</div>
{% else %}
{{ helper.render_table(collector.orphanedEvents) }}
{% endif %}
</div>
</div>
</div>
{% endif %}
{% endblock %}

View File

@ -1,6 +1,12 @@
CHANGELOG
=========
4.1.0
-----
* The `TraceableEventDispatcher::getOrphanedEvents()` method has been added.
* The `TraceableEventDispatcherInterface` has been deprecated and will be removed in 5.0.
4.0.0
-----

View File

@ -32,6 +32,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
private $called;
private $dispatcher;
private $wrappedListeners;
private $orphanedEvents;
public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null)
{
@ -40,6 +41,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$this->logger = $logger;
$this->called = array();
$this->wrappedListeners = array();
$this->orphanedEvents = array();
}
/**
@ -207,6 +209,16 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
return $notCalled;
}
/**
* Gets the orphaned events.
*
* @return array An array of orphaned events
*/
public function getOrphanedEvents()
{
return $this->orphanedEvents;
}
public function reset()
{
$this->called = array();
@ -247,6 +259,12 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
private function preProcess($eventName)
{
if (!$this->dispatcher->hasListeners($eventName)) {
$this->orphanedEvents[] = $eventName;
return;
}
foreach ($this->dispatcher->getListeners($eventName) as $listener) {
$priority = $this->getListenerPriority($eventName, $listener);
$wrappedListener = new WrappedListener($listener, null, $this->stopwatch, $this);

View File

@ -14,6 +14,8 @@ namespace Symfony\Component\EventDispatcher\Debug;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* @deprecated since version 4.1, will be removed in 5.0.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface TraceableEventDispatcherInterface extends EventDispatcherInterface

View File

@ -153,6 +153,40 @@ class TraceableEventDispatcherTest extends TestCase
$this->assertCount(2, $dispatcher->getCalledListeners());
}
public function testItReturnsNoOrphanedEventsWhenCreated()
{
// GIVEN
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
// WHEN
$events = $tdispatcher->getOrphanedEvents();
// THEN
$this->assertEmpty($events);
}
public function testItReturnsOrphanedEventsAfterDispatch()
{
// GIVEN
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
$tdispatcher->dispatch('foo');
// WHEN
$events = $tdispatcher->getOrphanedEvents();
// THEN
$this->assertCount(1, $events);
$this->assertEquals(array('foo'), $events);
}
public function testItDoesNotReturnHandledEvents()
{
// GIVEN
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
$tdispatcher->addListener('foo', function () {});
$tdispatcher->dispatch('foo');
// WHEN
$events = $tdispatcher->getOrphanedEvents();
// THEN
$this->assertEmpty($events);
}
public function testLogger()
{
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();

View File

@ -4,6 +4,7 @@ CHANGELOG
4.1.0
-----
* added orphaned events support to `EventDataCollector`
* `ExceptionListener` now logs and collects exceptions at priority `2048` (previously logged at `-128` and collected at `0`)
4.0.0

View File

@ -11,10 +11,11 @@
namespace Symfony\Component\HttpKernel\DataCollector;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface;
/**
* EventDataCollector.
@ -38,6 +39,7 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
$this->data = array(
'called_listeners' => array(),
'not_called_listeners' => array(),
'orphaned_events' => array(),
);
}
@ -56,6 +58,11 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
$this->setCalledListeners($this->dispatcher->getCalledListeners());
$this->setNotCalledListeners($this->dispatcher->getNotCalledListeners());
}
if ($this->dispatcher instanceof TraceableEventDispatcher) {
$this->setOrphanedEvents($this->dispatcher->getOrphanedEvents());
}
$this->data = $this->cloneVar($this->data);
}
@ -64,7 +71,7 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
*
* @param array $listeners An array of called listeners
*
* @see TraceableEventDispatcherInterface
* @see TraceableEventDispatcher
*/
public function setCalledListeners(array $listeners)
{
@ -76,7 +83,7 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
*
* @return array An array of called listeners
*
* @see TraceableEventDispatcherInterface
* @see TraceableEventDispatcher
*/
public function getCalledListeners()
{
@ -86,9 +93,9 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
/**
* Sets the not called listeners.
*
* @param array $listeners An array of not called listeners
* @param array $listeners
*
* @see TraceableEventDispatcherInterface
* @see TraceableEventDispatcher
*/
public function setNotCalledListeners(array $listeners)
{
@ -98,15 +105,39 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
/**
* Gets the not called listeners.
*
* @return array An array of not called listeners
* @return array
*
* @see TraceableEventDispatcherInterface
* @see TraceableEventDispatcher
*/
public function getNotCalledListeners()
{
return $this->data['not_called_listeners'];
}
/**
* Sets the orphaned events.
*
* @param array $events An array of orphaned events
*
* @see TraceableEventDispatcher
*/
public function setOrphanedEvents(array $events)
{
$this->data['orphaned_events'] = $events;
}
/**
* Gets the orphaned events.
*
* @return array An array of orphaned events
*
* @see TraceableEventDispatcher
*/
public function getOrphanedEvents()
{
return $this->data['orphaned_events'];
}
/**
* {@inheritdoc}
*/

View File

@ -11,10 +11,9 @@
namespace Symfony\Component\HttpKernel\Tests\Fixtures;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
class TestEventDispatcher extends EventDispatcher implements TraceableEventDispatcherInterface
class TestEventDispatcher extends TraceableEventDispatcher
{
public function getCalledListeners()
{
@ -29,4 +28,9 @@ class TestEventDispatcher extends EventDispatcher implements TraceableEventDispa
public function reset()
{
}
public function getOrphanedEvents()
{
return array();
}
}