feature #24289 [FrameworkBundle][HttpKernel] Reset profiler (derrabus)
This PR was merged into the 3.4 branch.
Discussion
----------
[FrameworkBundle][HttpKernel] Reset profiler
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | yes
| Tests pass? | yes
| Fixed tickets | #18244
| License | MIT
| Doc PR | N/A
This PR adds the ability to reset the profiler between requests. Furthermore, the profiler service has been tagged with the new `kernel.reset` tag from #24155. For this, I had to readd the ability to define multiple reset methods for a service.
Note: This PR requires twigphp/Twig#2560.
Commits
-------
8c39bf7845
Reset profiler.
This commit is contained in:
commit
86684f1c07
@ -63,6 +63,12 @@ Debug
|
|||||||
|
|
||||||
* Support for stacked errors in the `ErrorHandler` is deprecated and will be removed in Symfony 4.0.
|
* Support for stacked errors in the `ErrorHandler` is deprecated and will be removed in Symfony 4.0.
|
||||||
|
|
||||||
|
EventDispatcher
|
||||||
|
---------------
|
||||||
|
|
||||||
|
* Implementing `TraceableEventDispatcherInterface` without the `reset()` method
|
||||||
|
is deprecated and will be unsupported in 4.0.
|
||||||
|
|
||||||
Filesystem
|
Filesystem
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -270,6 +276,10 @@ HttpKernel
|
|||||||
|
|
||||||
* The `Symfony\Component\HttpKernel\Config\EnvParametersResource` class has been deprecated and will be removed in 4.0.
|
* The `Symfony\Component\HttpKernel\Config\EnvParametersResource` class has been deprecated and will be removed in 4.0.
|
||||||
|
|
||||||
|
* Implementing `DataCollectorInterface` without a `reset()` method has been deprecated and will be unsupported in 4.0.
|
||||||
|
|
||||||
|
* Implementing `DebugLoggerInterface` without a `clear()` method has been deprecated and will be unsupported in 4.0.
|
||||||
|
|
||||||
* The `ChainCacheClearer::add()` method has been deprecated and will be removed in 4.0,
|
* The `ChainCacheClearer::add()` method has been deprecated and will be removed in 4.0,
|
||||||
inject the list of clearers as a constructor argument instead.
|
inject the list of clearers as a constructor argument instead.
|
||||||
|
|
||||||
|
@ -192,6 +192,8 @@ EventDispatcher
|
|||||||
* The `ContainerAwareEventDispatcher` class has been removed.
|
* The `ContainerAwareEventDispatcher` class has been removed.
|
||||||
Use `EventDispatcher` with closure factories instead.
|
Use `EventDispatcher` with closure factories instead.
|
||||||
|
|
||||||
|
* The `reset()` method has been added to `TraceableEventDispatcherInterface`.
|
||||||
|
|
||||||
ExpressionLanguage
|
ExpressionLanguage
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
@ -611,6 +613,10 @@ HttpKernel
|
|||||||
|
|
||||||
* The `Symfony\Component\HttpKernel\Config\EnvParametersResource` class has been removed.
|
* The `Symfony\Component\HttpKernel\Config\EnvParametersResource` class has been removed.
|
||||||
|
|
||||||
|
* The `reset()` method has been added to `Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface`.
|
||||||
|
|
||||||
|
* The `clear()` method has been added to `Symfony\Component\HttpKernel\Log\DebugLoggerInterface`.
|
||||||
|
|
||||||
* The `ChainCacheClearer::add()` method has been removed,
|
* The `ChainCacheClearer::add()` method has been removed,
|
||||||
inject the list of clearers as a constructor argument instead.
|
inject the list of clearers as a constructor argument instead.
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
"ext-xml": "*",
|
"ext-xml": "*",
|
||||||
"doctrine/common": "~2.4",
|
"doctrine/common": "~2.4",
|
||||||
"fig/link-util": "^1.0",
|
"fig/link-util": "^1.0",
|
||||||
"twig/twig": "~1.34|~2.4",
|
"twig/twig": "^1.35|^2.4.4",
|
||||||
"psr/cache": "~1.0",
|
"psr/cache": "~1.0",
|
||||||
"psr/container": "^1.0",
|
"psr/container": "^1.0",
|
||||||
"psr/link": "^1.0",
|
"psr/link": "^1.0",
|
||||||
|
@ -28,6 +28,10 @@ class DoctrineDataCollector extends DataCollector
|
|||||||
private $registry;
|
private $registry;
|
||||||
private $connections;
|
private $connections;
|
||||||
private $managers;
|
private $managers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DebugStack[]
|
||||||
|
*/
|
||||||
private $loggers = array();
|
private $loggers = array();
|
||||||
|
|
||||||
public function __construct(ManagerRegistry $registry)
|
public function __construct(ManagerRegistry $registry)
|
||||||
@ -65,6 +69,16 @@ class DoctrineDataCollector extends DataCollector
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
|
||||||
|
foreach ($this->loggers as $logger) {
|
||||||
|
$logger->queries = array();
|
||||||
|
$logger->currentQuery = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getManagers()
|
public function getManagers()
|
||||||
{
|
{
|
||||||
return $this->data['managers'];
|
return $this->data['managers'];
|
||||||
|
@ -101,6 +101,20 @@ class DoctrineDataCollectorTest extends TestCase
|
|||||||
$this->assertTrue($collectedQueries['default'][1]['explainable']);
|
$this->assertTrue($collectedQueries['default'][1]['explainable']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testReset()
|
||||||
|
{
|
||||||
|
$queries = array(
|
||||||
|
array('sql' => 'SELECT * FROM table1', 'params' => array(), 'types' => array(), 'executionMS' => 1),
|
||||||
|
);
|
||||||
|
$c = $this->createCollector($queries);
|
||||||
|
$c->collect(new Request(), new Response());
|
||||||
|
|
||||||
|
$c->reset();
|
||||||
|
$c->collect(new Request(), new Response());
|
||||||
|
|
||||||
|
$this->assertEquals(array('default' => array()), $c->getQueries());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider paramProvider
|
* @dataProvider paramProvider
|
||||||
*/
|
*/
|
||||||
|
@ -45,6 +45,16 @@ class Logger extends BaseLogger implements DebugLoggerInterface
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function clear()
|
||||||
|
{
|
||||||
|
if (($logger = $this->getDebugLogger()) && method_exists($logger, 'clear')) {
|
||||||
|
$logger->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a DebugLoggerInterface instance if one is registered with this logger.
|
* Returns a DebugLoggerInterface instance if one is registered with this logger.
|
||||||
*
|
*
|
||||||
|
@ -55,4 +55,13 @@ class DebugProcessor implements DebugLoggerInterface
|
|||||||
{
|
{
|
||||||
return $this->errorCount;
|
return $this->errorCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function clear()
|
||||||
|
{
|
||||||
|
$this->records = array();
|
||||||
|
$this->errorCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,4 +128,17 @@ class LoggerTest extends TestCase
|
|||||||
$this->assertEquals('test', $record['message']);
|
$this->assertEquals('test', $record['message']);
|
||||||
$this->assertEquals(Logger::INFO, $record['priority']);
|
$this->assertEquals(Logger::INFO, $record['priority']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testClear()
|
||||||
|
{
|
||||||
|
$handler = new TestHandler();
|
||||||
|
$logger = new Logger('test', array($handler));
|
||||||
|
$logger->pushProcessor(new DebugProcessor());
|
||||||
|
|
||||||
|
$logger->addInfo('test');
|
||||||
|
$logger->clear();
|
||||||
|
|
||||||
|
$this->assertEmpty($logger->getLogs());
|
||||||
|
$this->assertSame(0, $logger->countErrors());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,16 @@ class TwigDataCollector extends DataCollector implements LateDataCollectorInterf
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->profile->reset();
|
||||||
|
$this->computed = null;
|
||||||
|
$this->data = array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^5.5.9|>=7.0.8",
|
"php": "^5.5.9|>=7.0.8",
|
||||||
"twig/twig": "~1.34|~2.4"
|
"twig/twig": "^1.35|^2.4.4"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"fig/link-util": "^1.0",
|
"fig/link-util": "^1.0",
|
||||||
|
@ -609,9 +609,9 @@ class FrameworkExtension extends Extension
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$config['collect']) {
|
$container->getDefinition('profiler')
|
||||||
$container->getDefinition('profiler')->addMethodCall('disable', array());
|
->addArgument($config['collect'])
|
||||||
}
|
->addTag('kernel.reset', array('method' => 'reset'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,6 +203,14 @@ class SecurityDataCollector extends DataCollector implements LateDataCollectorIn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
}
|
||||||
|
|
||||||
public function lateCollect()
|
public function lateCollect()
|
||||||
{
|
{
|
||||||
$this->data = $this->cloneVar($this->data);
|
$this->data = $this->cloneVar($this->data);
|
||||||
|
@ -53,6 +53,15 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter
|
|||||||
$this->data['total']['statistics'] = $this->calculateTotalStatistics();
|
$this->data['total']['statistics'] = $this->calculateTotalStatistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
foreach ($this->instances as $instance) {
|
||||||
|
// Calling getCalls() will clear the calls.
|
||||||
|
$instance->getCalls();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function lateCollect()
|
public function lateCollect()
|
||||||
{
|
{
|
||||||
$this->data = $this->cloneVar($this->data);
|
$this->data = $this->cloneVar($this->data);
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
3.4.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* Implementing `TraceableEventDispatcherInterface` without the `reset()` method has been deprecated.
|
||||||
|
|
||||||
3.3.0
|
3.3.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -212,6 +212,11 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
|
|||||||
return $notCalled;
|
return $notCalled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->called = array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Proxies all method calls to the original event dispatcher.
|
* Proxies all method calls to the original event dispatcher.
|
||||||
*
|
*
|
||||||
|
@ -15,6 +15,8 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* @method reset() Resets the trace.
|
||||||
*/
|
*/
|
||||||
interface TraceableEventDispatcherInterface extends EventDispatcherInterface
|
interface TraceableEventDispatcherInterface extends EventDispatcherInterface
|
||||||
{
|
{
|
||||||
|
@ -124,6 +124,21 @@ class TraceableEventDispatcherTest extends TestCase
|
|||||||
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
|
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testClearCalledListeners()
|
||||||
|
{
|
||||||
|
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
|
||||||
|
$tdispatcher->addListener('foo', function () {}, 5);
|
||||||
|
|
||||||
|
$tdispatcher->dispatch('foo');
|
||||||
|
$tdispatcher->reset();
|
||||||
|
|
||||||
|
$listeners = $tdispatcher->getNotCalledListeners();
|
||||||
|
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
|
||||||
|
unset($listeners['foo.closure']['stub']);
|
||||||
|
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
|
||||||
|
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetCalledListenersNested()
|
public function testGetCalledListenersNested()
|
||||||
{
|
{
|
||||||
$tdispatcher = null;
|
$tdispatcher = null;
|
||||||
|
@ -72,12 +72,9 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf
|
|||||||
public function __construct(FormDataExtractorInterface $dataExtractor)
|
public function __construct(FormDataExtractorInterface $dataExtractor)
|
||||||
{
|
{
|
||||||
$this->dataExtractor = $dataExtractor;
|
$this->dataExtractor = $dataExtractor;
|
||||||
$this->data = array(
|
|
||||||
'forms' => array(),
|
|
||||||
'forms_by_hash' => array(),
|
|
||||||
'nb_errors' => 0,
|
|
||||||
);
|
|
||||||
$this->hasVarDumper = class_exists(ClassStub::class);
|
$this->hasVarDumper = class_exists(ClassStub::class);
|
||||||
|
|
||||||
|
$this->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,6 +84,15 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array(
|
||||||
|
'forms' => array(),
|
||||||
|
'forms_by_hash' => array(),
|
||||||
|
'nb_errors' => 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -695,6 +695,36 @@ class FormDataCollectorTest extends TestCase
|
|||||||
$this->assertFalse(isset($child21Data['has_children_error']), 'The leaf data does not contains "has_children_error" property.');
|
$this->assertFalse(isset($child21Data['has_children_error']), 'The leaf data does not contains "has_children_error" property.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testReset()
|
||||||
|
{
|
||||||
|
$form = $this->createForm('my_form');
|
||||||
|
|
||||||
|
$this->dataExtractor->expects($this->any())
|
||||||
|
->method('extractConfiguration')
|
||||||
|
->will($this->returnValue(array()));
|
||||||
|
$this->dataExtractor->expects($this->any())
|
||||||
|
->method('extractDefaultData')
|
||||||
|
->will($this->returnValue(array()));
|
||||||
|
$this->dataExtractor->expects($this->any())
|
||||||
|
->method('extractSubmittedData')
|
||||||
|
->with($form)
|
||||||
|
->will($this->returnValue(array('errors' => array('baz'))));
|
||||||
|
|
||||||
|
$this->dataCollector->buildPreliminaryFormTree($form);
|
||||||
|
$this->dataCollector->collectSubmittedData($form);
|
||||||
|
|
||||||
|
$this->dataCollector->reset();
|
||||||
|
|
||||||
|
$this->assertSame(
|
||||||
|
array(
|
||||||
|
'forms' => array(),
|
||||||
|
'forms_by_hash' => array(),
|
||||||
|
'nb_errors' => 0,
|
||||||
|
),
|
||||||
|
$this->dataCollector->getData()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private function createForm($name)
|
private function createForm($name)
|
||||||
{
|
{
|
||||||
$builder = new FormBuilder($name, null, $this->dispatcher, $this->factory);
|
$builder = new FormBuilder($name, null, $this->dispatcher, $this->factory);
|
||||||
|
@ -14,7 +14,9 @@ CHANGELOG
|
|||||||
* deprecated the `ChainCacheClearer::add()` method
|
* deprecated the `ChainCacheClearer::add()` method
|
||||||
* deprecated the `CacheaWarmerAggregate::add()` and `setWarmers()` methods
|
* deprecated the `CacheaWarmerAggregate::add()` and `setWarmers()` methods
|
||||||
* made `CacheWarmerAggregate` and `ChainCacheClearer` classes final
|
* made `CacheWarmerAggregate` and `ChainCacheClearer` classes final
|
||||||
|
* added the possibility to reset the profiler to its initial state
|
||||||
|
* deprecated data collectors without a `reset()` method
|
||||||
|
* deprecated implementing `DebugLoggerInterface` without a `clear()` method
|
||||||
|
|
||||||
3.3.0
|
3.3.0
|
||||||
-----
|
-----
|
||||||
|
@ -26,6 +26,11 @@ class AjaxDataCollector extends DataCollector
|
|||||||
// all collecting is done client side
|
// all collecting is done client side
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
// all collecting is done client side
|
||||||
|
}
|
||||||
|
|
||||||
public function getName()
|
public function getName()
|
||||||
{
|
{
|
||||||
return 'ajax';
|
return 'ajax';
|
||||||
|
@ -95,6 +95,14 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
}
|
||||||
|
|
||||||
public function lateCollect()
|
public function lateCollect()
|
||||||
{
|
{
|
||||||
$this->data = $this->cloneVar($this->data);
|
$this->data = $this->cloneVar($this->data);
|
||||||
|
@ -18,6 +18,8 @@ use Symfony\Component\HttpFoundation\Response;
|
|||||||
* DataCollectorInterface.
|
* DataCollectorInterface.
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* @method reset() Resets this data collector to its initial state.
|
||||||
*/
|
*/
|
||||||
interface DataCollectorInterface
|
interface DataCollectorInterface
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,9 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
|
|||||||
|
|
||||||
public function __construct(EventDispatcherInterface $dispatcher = null)
|
public function __construct(EventDispatcherInterface $dispatcher = null)
|
||||||
{
|
{
|
||||||
|
if ($dispatcher instanceof TraceableEventDispatcherInterface && !method_exists($dispatcher, 'reset')) {
|
||||||
|
@trigger_error(sprintf('Implementing "%s" without the "reset()" method is deprecated since version 3.4 and will be unsupported in 4.0 for class "%s".', TraceableEventDispatcherInterface::class, \get_class($dispatcher)), E_USER_DEPRECATED);
|
||||||
|
}
|
||||||
$this->dispatcher = $dispatcher;
|
$this->dispatcher = $dispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +44,19 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
|
||||||
|
if ($this->dispatcher instanceof TraceableEventDispatcherInterface) {
|
||||||
|
if (!method_exists($this->dispatcher, 'reset')) {
|
||||||
|
return; // @deprecated
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->dispatcher->reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function lateCollect()
|
public function lateCollect()
|
||||||
{
|
{
|
||||||
if ($this->dispatcher instanceof TraceableEventDispatcherInterface) {
|
if ($this->dispatcher instanceof TraceableEventDispatcherInterface) {
|
||||||
|
@ -34,6 +34,14 @@ class ExceptionDataCollector extends DataCollector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the exception is not null.
|
* Checks if the exception is not null.
|
||||||
*
|
*
|
||||||
|
@ -29,6 +29,10 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
|
|||||||
public function __construct($logger = null, $containerPathPrefix = null)
|
public function __construct($logger = null, $containerPathPrefix = null)
|
||||||
{
|
{
|
||||||
if (null !== $logger && $logger instanceof DebugLoggerInterface) {
|
if (null !== $logger && $logger instanceof DebugLoggerInterface) {
|
||||||
|
if (!method_exists($logger, 'clear')) {
|
||||||
|
@trigger_error(sprintf('Implementing "%s" without the "clear()" method is deprecated since version 3.4 and will be unsupported in 4.0 for class "%s".', DebugLoggerInterface::class, \get_class($logger)), E_USER_DEPRECATED);
|
||||||
|
}
|
||||||
|
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +47,17 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
|
|||||||
// everything is done as late as possible
|
// everything is done as late as possible
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
if ($this->logger && method_exists($this->logger, 'clear')) {
|
||||||
|
$this->logger->clear();
|
||||||
|
}
|
||||||
|
$this->data = array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -23,10 +23,7 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte
|
|||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->data = array(
|
$this->reset();
|
||||||
'memory' => 0,
|
|
||||||
'memory_limit' => $this->convertToBytes(ini_get('memory_limit')),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,6 +34,17 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte
|
|||||||
$this->updateMemoryUsage();
|
$this->updateMemoryUsage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array(
|
||||||
|
'memory' => 0,
|
||||||
|
'memory_limit' => $this->convertToBytes(ini_get('memory_limit')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -156,6 +156,12 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
|||||||
$this->data = $this->cloneVar($this->data);
|
$this->data = $this->cloneVar($this->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
$this->controllers = new \SplObjectStorage();
|
||||||
|
}
|
||||||
|
|
||||||
public function getMethod()
|
public function getMethod()
|
||||||
{
|
{
|
||||||
return $this->data['method'];
|
return $this->data['method'];
|
||||||
|
@ -23,17 +23,14 @@ use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
|
|||||||
*/
|
*/
|
||||||
class RouterDataCollector extends DataCollector
|
class RouterDataCollector extends DataCollector
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \SplObjectStorage
|
||||||
|
*/
|
||||||
protected $controllers;
|
protected $controllers;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->controllers = new \SplObjectStorage();
|
$this->reset();
|
||||||
|
|
||||||
$this->data = array(
|
|
||||||
'redirect' => false,
|
|
||||||
'url' => null,
|
|
||||||
'route' => null,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,6 +50,17 @@ class RouterDataCollector extends DataCollector
|
|||||||
unset($this->controllers[$request]);
|
unset($this->controllers[$request]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->controllers = new \SplObjectStorage();
|
||||||
|
|
||||||
|
$this->data = array(
|
||||||
|
'redirect' => false,
|
||||||
|
'url' => null,
|
||||||
|
'route' => null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
protected function guessRoute(Request $request, $controller)
|
protected function guessRoute(Request $request, $controller)
|
||||||
{
|
{
|
||||||
return 'n/a';
|
return 'n/a';
|
||||||
|
@ -49,6 +49,14 @@ class TimeDataCollector extends DataCollector implements LateDataCollectorInterf
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -15,6 +15,8 @@ namespace Symfony\Component\HttpKernel\Log;
|
|||||||
* DebugLoggerInterface.
|
* DebugLoggerInterface.
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* @method clear() Removes all log records.
|
||||||
*/
|
*/
|
||||||
interface DebugLoggerInterface
|
interface DebugLoggerInterface
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,11 @@ class Profiler
|
|||||||
*/
|
*/
|
||||||
private $logger;
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $initiallyEnabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
@ -48,11 +53,13 @@ class Profiler
|
|||||||
/**
|
/**
|
||||||
* @param ProfilerStorageInterface $storage A ProfilerStorageInterface instance
|
* @param ProfilerStorageInterface $storage A ProfilerStorageInterface instance
|
||||||
* @param LoggerInterface $logger A LoggerInterface instance
|
* @param LoggerInterface $logger A LoggerInterface instance
|
||||||
|
* @param bool $enable The initial enabled state
|
||||||
*/
|
*/
|
||||||
public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null)
|
public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null, $enable = true)
|
||||||
{
|
{
|
||||||
$this->storage = $storage;
|
$this->storage = $storage;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
$this->initiallyEnabled = $this->enabled = (bool) $enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -188,6 +195,18 @@ class Profiler
|
|||||||
return $profile;
|
return $profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
foreach ($this->collectors as $collector) {
|
||||||
|
if (!method_exists($collector, 'reset')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$collector->reset();
|
||||||
|
}
|
||||||
|
$this->enabled = $this->initiallyEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Collectors associated with this profiler.
|
* Gets the Collectors associated with this profiler.
|
||||||
*
|
*
|
||||||
@ -218,6 +237,10 @@ class Profiler
|
|||||||
*/
|
*/
|
||||||
public function add(DataCollectorInterface $collector)
|
public function add(DataCollectorInterface $collector)
|
||||||
{
|
{
|
||||||
|
if (!method_exists($collector, 'reset')) {
|
||||||
|
@trigger_error(sprintf('Implementing "%s" without the "reset()" method is deprecated since version 3.4 and will be unsupported in 4.0 for class "%s".', DataCollectorInterface::class, \get_class($collector)), E_USER_DEPRECATED);
|
||||||
|
}
|
||||||
|
|
||||||
$this->collectors[$collector->getName()] = $collector;
|
$this->collectors[$collector->getName()] = $collector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,4 +37,23 @@ class ExceptionDataCollectorTest extends TestCase
|
|||||||
$this->assertSame('exception', $c->getName());
|
$this->assertSame('exception', $c->getName());
|
||||||
$this->assertSame($trace, $c->getTrace());
|
$this->assertSame($trace, $c->getTrace());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCollectWithoutException()
|
||||||
|
{
|
||||||
|
$c = new ExceptionDataCollector();
|
||||||
|
$c->collect(new Request(), new Response());
|
||||||
|
|
||||||
|
$this->assertFalse($c->hasException());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReset()
|
||||||
|
{
|
||||||
|
$c = new ExceptionDataCollector();
|
||||||
|
|
||||||
|
$c->collect(new Request(), new Response(), new \Exception());
|
||||||
|
$c->reset();
|
||||||
|
$c->collect(new Request(), new Response());
|
||||||
|
|
||||||
|
$this->assertFalse($c->hasException());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,10 @@ class LoggerDataCollectorTest extends TestCase
|
|||||||
{
|
{
|
||||||
public function testCollectWithUnexpectedFormat()
|
public function testCollectWithUnexpectedFormat()
|
||||||
{
|
{
|
||||||
$logger = $this->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')->getMock();
|
$logger = $this
|
||||||
|
->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')
|
||||||
|
->setMethods(array('countErrors', 'getLogs', 'clear'))
|
||||||
|
->getMock();
|
||||||
$logger->expects($this->once())->method('countErrors')->will($this->returnValue('foo'));
|
$logger->expects($this->once())->method('countErrors')->will($this->returnValue('foo'));
|
||||||
$logger->expects($this->exactly(2))->method('getLogs')->will($this->returnValue(array()));
|
$logger->expects($this->exactly(2))->method('getLogs')->will($this->returnValue(array()));
|
||||||
|
|
||||||
@ -43,7 +46,10 @@ class LoggerDataCollectorTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
public function testCollect($nb, $logs, $expectedLogs, $expectedDeprecationCount, $expectedScreamCount, $expectedPriorities = null)
|
public function testCollect($nb, $logs, $expectedLogs, $expectedDeprecationCount, $expectedScreamCount, $expectedPriorities = null)
|
||||||
{
|
{
|
||||||
$logger = $this->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')->getMock();
|
$logger = $this
|
||||||
|
->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')
|
||||||
|
->setMethods(array('countErrors', 'getLogs', 'clear'))
|
||||||
|
->getMock();
|
||||||
$logger->expects($this->once())->method('countErrors')->will($this->returnValue($nb));
|
$logger->expects($this->once())->method('countErrors')->will($this->returnValue($nb));
|
||||||
$logger->expects($this->exactly(2))->method('getLogs')->will($this->returnValue($logs));
|
$logger->expects($this->exactly(2))->method('getLogs')->will($this->returnValue($logs));
|
||||||
|
|
||||||
@ -70,6 +76,18 @@ class LoggerDataCollectorTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testReset()
|
||||||
|
{
|
||||||
|
$logger = $this
|
||||||
|
->getMockBuilder('Symfony\Component\HttpKernel\Log\DebugLoggerInterface')
|
||||||
|
->setMethods(array('countErrors', 'getLogs', 'clear'))
|
||||||
|
->getMock();
|
||||||
|
$logger->expects($this->once())->method('clear');
|
||||||
|
|
||||||
|
$c = new LoggerDataCollector($logger);
|
||||||
|
$c->reset();
|
||||||
|
}
|
||||||
|
|
||||||
public function getCollectTestData()
|
public function getCollectTestData()
|
||||||
{
|
{
|
||||||
yield 'simple log' => array(
|
yield 'simple log' => array(
|
||||||
|
@ -29,6 +29,11 @@ class CloneVarDataCollector extends DataCollector
|
|||||||
$this->data = $this->cloneVar($this->varToClone);
|
$this->data = $this->cloneVar($this->varToClone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
}
|
||||||
|
|
||||||
public function getData()
|
public function getData()
|
||||||
{
|
{
|
||||||
return $this->data;
|
return $this->data;
|
||||||
|
@ -25,4 +25,8 @@ class TestEventDispatcher extends EventDispatcher implements TraceableEventDispa
|
|||||||
{
|
{
|
||||||
return array('bar');
|
return array('bar');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\HttpKernel\Tests\Profiler;
|
namespace Symfony\Component\HttpKernel\Tests\Profiler;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
|
||||||
use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector;
|
use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector;
|
||||||
use Symfony\Component\HttpKernel\Profiler\FileProfilerStorage;
|
use Symfony\Component\HttpKernel\Profiler\FileProfilerStorage;
|
||||||
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
||||||
@ -40,6 +41,19 @@ class ProfilerTest extends TestCase
|
|||||||
$this->assertSame('bar', $profile->getCollector('request')->getRequestQuery()->all()['foo']->getValue());
|
$this->assertSame('bar', $profile->getCollector('request')->getRequestQuery()->all()['foo']->getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testReset()
|
||||||
|
{
|
||||||
|
$collector = $this->getMockBuilder(DataCollectorInterface::class)
|
||||||
|
->setMethods(['collect', 'getName', 'reset'])
|
||||||
|
->getMock();
|
||||||
|
$collector->expects($this->any())->method('getName')->willReturn('mock');
|
||||||
|
$collector->expects($this->once())->method('reset');
|
||||||
|
|
||||||
|
$profiler = new Profiler($this->storage);
|
||||||
|
$profiler->add($collector);
|
||||||
|
$profiler->reset();
|
||||||
|
}
|
||||||
|
|
||||||
public function testFindWorksWithDates()
|
public function testFindWorksWithDates()
|
||||||
{
|
{
|
||||||
$profiler = new Profiler($this->storage);
|
$profiler = new Profiler($this->storage);
|
||||||
|
@ -58,6 +58,14 @@ class TranslationDataCollector extends DataCollector implements LateDataCollecto
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->data = array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
|
|||||||
use Symfony\Component\Validator\Validator\TraceableValidator;
|
use Symfony\Component\Validator\Validator\TraceableValidator;
|
||||||
use Symfony\Component\VarDumper\Caster\Caster;
|
use Symfony\Component\VarDumper\Caster\Caster;
|
||||||
use Symfony\Component\VarDumper\Caster\ClassStub;
|
use Symfony\Component\VarDumper\Caster\ClassStub;
|
||||||
|
use Symfony\Component\VarDumper\Cloner\Data;
|
||||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,10 +32,7 @@ class ValidatorDataCollector extends DataCollector implements LateDataCollectorI
|
|||||||
public function __construct(TraceableValidator $validator)
|
public function __construct(TraceableValidator $validator)
|
||||||
{
|
{
|
||||||
$this->validator = $validator;
|
$this->validator = $validator;
|
||||||
$this->data = array(
|
$this->reset();
|
||||||
'calls' => array(),
|
|
||||||
'violations_count' => 0,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,6 +43,15 @@ class ValidatorDataCollector extends DataCollector implements LateDataCollectorI
|
|||||||
// Everything is collected once, on kernel terminate.
|
// Everything is collected once, on kernel terminate.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->validator->reset();
|
||||||
|
$this->data = array(
|
||||||
|
'calls' => $this->cloneVar(array()),
|
||||||
|
'violations_count' => 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -52,16 +59,22 @@ class ValidatorDataCollector extends DataCollector implements LateDataCollectorI
|
|||||||
{
|
{
|
||||||
$collected = $this->validator->getCollectedData();
|
$collected = $this->validator->getCollectedData();
|
||||||
$this->data['calls'] = $this->cloneVar($collected);
|
$this->data['calls'] = $this->cloneVar($collected);
|
||||||
$this->data['violations_count'] += array_reduce($collected, function ($previous, $item) {
|
$this->data['violations_count'] = array_reduce($collected, function ($previous, $item) {
|
||||||
return $previous += count($item['violations']);
|
return $previous + count($item['violations']);
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Data
|
||||||
|
*/
|
||||||
public function getCalls()
|
public function getCalls()
|
||||||
{
|
{
|
||||||
return $this->data['calls'];
|
return $this->data['calls'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getViolationsCount()
|
public function getViolationsCount()
|
||||||
{
|
{
|
||||||
return $this->data['violations_count'];
|
return $this->data['violations_count'];
|
||||||
|
@ -50,6 +50,33 @@ class ValidatorDataCollectorTest extends TestCase
|
|||||||
$this->assertCount(2, $call['violations']);
|
$this->assertCount(2, $call['violations']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testReset()
|
||||||
|
{
|
||||||
|
$originalValidator = $this->createMock(ValidatorInterface::class);
|
||||||
|
$validator = new TraceableValidator($originalValidator);
|
||||||
|
|
||||||
|
$collector = new ValidatorDataCollector($validator);
|
||||||
|
|
||||||
|
$violations = new ConstraintViolationList(array(
|
||||||
|
$this->createMock(ConstraintViolation::class),
|
||||||
|
$this->createMock(ConstraintViolation::class),
|
||||||
|
));
|
||||||
|
$originalValidator->method('validate')->willReturn($violations);
|
||||||
|
|
||||||
|
$validator->validate(new \stdClass());
|
||||||
|
|
||||||
|
$collector->lateCollect();
|
||||||
|
$collector->reset();
|
||||||
|
|
||||||
|
$this->assertCount(0, $collector->getCalls());
|
||||||
|
$this->assertSame(0, $collector->getViolationsCount());
|
||||||
|
|
||||||
|
$collector->lateCollect();
|
||||||
|
|
||||||
|
$this->assertCount(0, $collector->getCalls());
|
||||||
|
$this->assertSame(0, $collector->getViolationsCount());
|
||||||
|
}
|
||||||
|
|
||||||
protected function createMock($classname)
|
protected function createMock($classname)
|
||||||
{
|
{
|
||||||
return $this->getMockBuilder($classname)->disableOriginalConstructor()->getMock();
|
return $this->getMockBuilder($classname)->disableOriginalConstructor()->getMock();
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Validator\Validator;
|
namespace Symfony\Component\Validator\Validator;
|
||||||
|
|
||||||
use Symfony\Component\Validator\ConstraintViolationList;
|
|
||||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,13 +29,18 @@ class TraceableValidator implements ValidatorInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ConstraintViolationList[]
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getCollectedData()
|
public function getCollectedData()
|
||||||
{
|
{
|
||||||
return $this->collectedData;
|
return $this->collectedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->collectedData = array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user