[Bridge\Monolog][FrameworkBundle] Add & wire a DebugProcessor

This commit is contained in:
Nicolas Grekas 2016-11-04 21:47:40 +01:00
parent 31d5fffc3c
commit 7572a53b84
7 changed files with 168 additions and 3 deletions

View File

@ -11,6 +11,8 @@
namespace Symfony\Bridge\Monolog\Handler; namespace Symfony\Bridge\Monolog\Handler;
@trigger_error('The '.__NAMESPACE__.'\DebugHandler class is deprecated since version 3.2 and will be removed in 4.0. Use Symfony\Bridge\Monolog\Processor\DebugProcessor instead.', E_USER_DEPRECATED);
use Monolog\Logger; use Monolog\Logger;
use Monolog\Handler\TestHandler; use Monolog\Handler\TestHandler;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
@ -19,6 +21,8 @@ use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
* DebugLogger. * DebugLogger.
* *
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
*
* @deprecated since version 3.2, to be removed in 4.0. Use Symfony\Bridge\Monolog\Processor\DebugProcessor instead.
*/ */
class DebugHandler extends TestHandler implements DebugLoggerInterface class DebugHandler extends TestHandler implements DebugLoggerInterface
{ {

View File

@ -52,6 +52,12 @@ class Logger extends BaseLogger implements DebugLoggerInterface
*/ */
private function getDebugLogger() private function getDebugLogger()
{ {
foreach ($this->processors as $processor) {
if ($processor instanceof DebugLoggerInterface) {
return $processor;
}
}
foreach ($this->handlers as $handler) { foreach ($this->handlers as $handler) {
if ($handler instanceof DebugLoggerInterface) { if ($handler instanceof DebugLoggerInterface) {
return $handler; return $handler;

View File

@ -0,0 +1,58 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\Monolog\Processor;
use Monolog\Logger;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
class DebugProcessor implements DebugLoggerInterface
{
private $records = array();
private $errorCount = 0;
public function __invoke(array $record)
{
$this->records[] = array(
'timestamp' => $record['datetime']->getTimestamp(),
'message' => $record['message'],
'priority' => $record['level'],
'priorityName' => $record['level_name'],
'context' => $record['context'],
'channel' => isset($record['channel']) ? $record['channel'] : '',
);
switch ($record['level']) {
case Logger::ERROR:
case Logger::CRITICAL:
case Logger::ALERT:
case Logger::EMERGENCY:
++$this->errorCount;
}
return $record;
}
/**
* {@inheritdoc}
*/
public function getLogs()
{
return $this->records;
}
/**
* {@inheritdoc}
*/
public function countErrors()
{
return $this->errorCount;
}
}

View File

@ -13,10 +13,14 @@ namespace Symfony\Bridge\Monolog\Tests;
use Monolog\Handler\TestHandler; use Monolog\Handler\TestHandler;
use Symfony\Bridge\Monolog\Handler\DebugHandler; use Symfony\Bridge\Monolog\Handler\DebugHandler;
use Symfony\Bridge\Monolog\Processor\DebugProcessor;
use Symfony\Bridge\Monolog\Logger; use Symfony\Bridge\Monolog\Logger;
class LoggerTest extends \PHPUnit_Framework_TestCase class LoggerTest extends \PHPUnit_Framework_TestCase
{ {
/**
* @group legacy
*/
public function testGetLogsWithDebugHandler() public function testGetLogsWithDebugHandler()
{ {
$handler = new DebugHandler(); $handler = new DebugHandler();
@ -26,7 +30,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
$this->assertSame(1, count($logger->getLogs())); $this->assertSame(1, count($logger->getLogs()));
} }
public function testGetLogsWithoutDebugHandler() public function testGetLogsWithoutDebugProcessor()
{ {
$handler = new TestHandler(); $handler = new TestHandler();
$logger = new Logger(__METHOD__, array($handler)); $logger = new Logger(__METHOD__, array($handler));
@ -35,6 +39,9 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
$this->assertSame(array(), $logger->getLogs()); $this->assertSame(array(), $logger->getLogs());
} }
/**
* @group legacy
*/
public function testCountErrorsWithDebugHandler() public function testCountErrorsWithDebugHandler()
{ {
$handler = new DebugHandler(); $handler = new DebugHandler();
@ -53,7 +60,10 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
$this->assertSame(4, $logger->countErrors()); $this->assertSame(4, $logger->countErrors());
} }
public function testGetLogs() /**
* @group legacy
*/
public function testGetLogsWithDebugHandler2()
{ {
$logger = new Logger('test'); $logger = new Logger('test');
$logger->pushHandler(new DebugHandler()); $logger->pushHandler(new DebugHandler());
@ -66,7 +76,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(Logger::INFO, $record['priority']); $this->assertEquals(Logger::INFO, $record['priority']);
} }
public function testCountErrorsWithoutDebugHandler() public function testCountErrorsWithoutDebugProcessor()
{ {
$handler = new TestHandler(); $handler = new TestHandler();
$logger = new Logger(__METHOD__, array($handler)); $logger = new Logger(__METHOD__, array($handler));
@ -74,4 +84,47 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($logger->error('error message')); $this->assertTrue($logger->error('error message'));
$this->assertSame(0, $logger->countErrors()); $this->assertSame(0, $logger->countErrors());
} }
public function testGetLogsWithDebugProcessor()
{
$handler = new TestHandler();
$processor = new DebugProcessor();
$logger = new Logger(__METHOD__, array($handler), array($processor));
$this->assertTrue($logger->error('error message'));
$this->assertSame(1, count($logger->getLogs()));
}
public function testCountErrorsWithDebugProcessor()
{
$handler = new TestHandler();
$processor = new DebugProcessor();
$logger = new Logger(__METHOD__, array($handler), array($processor));
$this->assertTrue($logger->debug('test message'));
$this->assertTrue($logger->info('test message'));
$this->assertTrue($logger->notice('test message'));
$this->assertTrue($logger->warning('test message'));
$this->assertTrue($logger->error('test message'));
$this->assertTrue($logger->critical('test message'));
$this->assertTrue($logger->alert('test message'));
$this->assertTrue($logger->emergency('test message'));
$this->assertSame(4, $logger->countErrors());
}
public function testGetLogsWithDebugProcessor2()
{
$handler = new TestHandler();
$logger = new Logger('test', array($handler));
$logger->pushProcessor(new DebugProcessor());
$logger->addInfo('test');
$this->assertCount(1, $logger->getLogs());
list($record) = $logger->getLogs();
$this->assertEquals('test', $record['message']);
$this->assertEquals(Logger::INFO, $record['priority']);
}
} }

View File

@ -0,0 +1,35 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;
class AddDebugLogProcessorPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('profiler')) {
return;
}
if (!$container->hasDefinition('monolog.logger_prototype')) {
return;
}
if (!$container->hasDefinition('debug.log_processor')) {
return;
}
$definition = $container->getDefinition('monolog.logger_prototype');
$definition->addMethodCall('pushProcessor', array(new Reference('debug.log_processor')));
}
}

View File

@ -12,6 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection; namespace Symfony\Bundle\FrameworkBundle\DependencyInjection;
use Doctrine\Common\Annotations\Reader; use Doctrine\Common\Annotations\Reader;
use Symfony\Bridge\Monolog\Processor\DebugProcessor;
use Symfony\Component\Cache\Adapter\AdapterInterface; use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
@ -468,6 +469,12 @@ class FrameworkExtension extends Extension
$definition->replaceArgument(4, $debug); $definition->replaceArgument(4, $debug);
$definition->replaceArgument(6, $debug); $definition->replaceArgument(6, $debug);
if ($debug && class_exists(DebugProcessor::class)) {
$definition = new Definition(DebugProcessor::class);
$definition->setPublic(false);
$container->setDefinition('debug.log_processor', $definition);
}
} }
/** /**

View File

@ -12,6 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle; namespace Symfony\Bundle\FrameworkBundle;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddDebugLogProcessorPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPass;
@ -95,6 +96,7 @@ class FrameworkBundle extends Bundle
$container->addCompilerPass(new CachePoolClearerPass(), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new CachePoolClearerPass(), PassConfig::TYPE_AFTER_REMOVING);
if ($container->getParameter('kernel.debug')) { if ($container->getParameter('kernel.debug')) {
$container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1);
$container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new CompilerDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new CompilerDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);