[DoctrineBridge][DoctrineBundle] Refactored the DBAL logging

This allows enabling the logging and the profiling separately for instance
when doing batch processing leading to memory issue due to the profiling.
This commit is contained in:
Christophe Coevoet 2011-12-15 20:19:09 +01:00
parent 2750adb52d
commit 8713c2d540
11 changed files with 98 additions and 19 deletions

View File

@ -12,10 +12,10 @@
namespace Symfony\Bridge\Doctrine\DataCollector;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\DBAL\Logging\DebugStack;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bridge\Doctrine\Logger\DbalLogger;
/**
* DoctrineDataCollector.
@ -28,7 +28,7 @@ class DoctrineDataCollector extends DataCollector
private $managers;
private $logger;
public function __construct(ManagerRegistry $registry, DbalLogger $logger = null)
public function __construct(ManagerRegistry $registry, DebugStack $logger = null)
{
$this->connections = $registry->getConnectionNames();
$this->managers = $registry->getManagerNames();

View File

@ -13,14 +13,14 @@ namespace Symfony\Bridge\Doctrine\Logger;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Debug\Stopwatch;
use Doctrine\DBAL\Logging\DebugStack;
use Doctrine\DBAL\Logging\SQLLogger;
/**
* DbalLogger.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class DbalLogger extends DebugStack
class DbalLogger implements SQLLogger
{
protected $logger;
protected $stopwatch;
@ -42,8 +42,6 @@ class DbalLogger extends DebugStack
*/
public function startQuery($sql, array $params = null, array $types = null)
{
parent::startQuery($sql, $params, $types);
if (null !== $this->stopwatch) {
$this->stopwatch->start('doctrine', 'doctrine');
}
@ -58,8 +56,6 @@ class DbalLogger extends DebugStack
*/
public function stopQuery()
{
parent::stopQuery();
if (null !== $this->stopwatch) {
$this->stopwatch->stop('doctrine');
}

View File

@ -78,6 +78,7 @@ class Configuration implements ConfigurationInterface
'platform_service',
'charset',
'logging',
'profiling',
'mapping_types',
) as $key) {
if (array_key_exists($key, $v)) {
@ -130,6 +131,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('platform_service')->end()
->scalarNode('charset')->end()
->booleanNode('logging')->defaultValue($this->debug)->end()
->booleanNode('profiling')->defaultValue($this->debug)->end()
->scalarNode('driver_class')->end()
->scalarNode('wrapper_class')->end()
->arrayNode('options')

View File

@ -92,9 +92,18 @@ class DoctrineExtension extends AbstractDoctrineExtension
{
// configuration
$configuration = $container->setDefinition(sprintf('doctrine.dbal.%s_connection.configuration', $name), new DefinitionDecorator('doctrine.dbal.connection.configuration'));
if (isset($connection['logging']) && $connection['logging']) {
$configuration->addMethodCall('setSQLLogger', array(new Reference('doctrine.dbal.logger')));
unset ($connection['logging']);
$logger = null;
if ($connection['logging']) {
$logger = new Reference('doctrine.dbal.logger');
}
unset ($connection['logging']);
if ($connection['profiling']) {
$logger = $logger ? new Reference('doctrine.dbal.logger.chain') : new Reference('doctrine.dbal.logger.profiling');
}
unset($connection['profiling']);
if ($logger) {
$configuration->addMethodCall('setSQLLogger', array($logger));
}
// event manager

View File

@ -5,7 +5,8 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="doctrine.dbal.logger.debug.class">Doctrine\DBAL\Logging\DebugStack</parameter>
<parameter key="doctrine.dbal.logger.chain.class">Doctrine\DBAL\Logging\LoggerChain</parameter>
<parameter key="doctrine.dbal.logger.profiling.class">Doctrine\DBAL\Logging\DebugStack</parameter>
<parameter key="doctrine.dbal.logger.class">Symfony\Bridge\Doctrine\Logger\DbalLogger</parameter>
<parameter key="doctrine.dbal.configuration.class">Doctrine\DBAL\Configuration</parameter>
<parameter key="doctrine.data_collector.class">Symfony\Bridge\Doctrine\DataCollector\DoctrineDataCollector</parameter>
@ -19,7 +20,16 @@
</parameters>
<services>
<service id="doctrine.dbal.logger.debug" class="%doctrine.dbal.logger.debug.class%" public="false" />
<service id="doctrine.dbal.logger.chain" class="%doctrine.dbal.logger.chain.class%" public="false">
<call method="addLogger">
<argument type="service" id="doctrine.dbal.logger" />
</call>
<call method="addLogger">
<argument type="service" id="doctrine.dbal.logger.profiling" />
</call>
</service>
<service id="doctrine.dbal.logger.profiling" class="%doctrine.dbal.logger.profiling.class%" public="false" />
<service id="doctrine.dbal.logger" class="%doctrine.dbal.logger.class%" public="false">
<tag name="monolog.logger" channel="doctrine" />
@ -30,7 +40,7 @@
<service id="data_collector.doctrine" class="%doctrine.data_collector.class%" public="false">
<tag name="data_collector" template="DoctrineBundle:Collector:db" id="db" />
<argument type="service" id="doctrine" />
<argument type="service" id="doctrine.dbal.logger" />
<argument type="service" id="doctrine.dbal.logger.profiling" />
</service>
<service id="doctrine.dbal.connection_factory" class="%doctrine.dbal.connection_factory.class%">

View File

@ -29,6 +29,7 @@
<xsd:attribute name="wrapper-class" type="xsd:string" />
<xsd:attribute name="platform-service" type="xsd:string" />
<xsd:attribute name="logging" type="xsd:string" default="false" />
<xsd:attribute name="profiling" type="xsd:string" default="false" />
</xsd:attributeGroup>
<xsd:complexType name="dbal">

View File

@ -18,8 +18,9 @@ class ContainerTest extends TestCase
public function testContainer()
{
$container = $this->createYamlBundleTestContainer();
$this->assertInstanceOf('Doctrine\DBAL\Logging\DebugStack', $container->get('doctrine.dbal.logger.debug'));
$this->assertInstanceOf('Doctrine\DBAL\Logging\DebugStack', $container->get('doctrine.dbal.logger'));
$this->assertInstanceOf('Doctrine\DBAL\Logging\DebugStack', $container->get('doctrine.dbal.logger.profiling'));
$this->assertInstanceOf('Doctrine\DBAL\Logging\LoggerChain', $container->get('doctrine.dbal.logger.chain'));
$this->assertInstanceOf('Symfony\Bridge\Doctrine\Logger\DbalLogger', $container->get('doctrine.dbal.logger'));
$this->assertInstanceOf('Symfony\Bridge\Doctrine\DataCollector\DoctrineDataCollector', $container->get('data_collector.doctrine'));
$this->assertInstanceOf('Doctrine\DBAL\Configuration', $container->get('doctrine.dbal.default_connection.configuration'));
$this->assertInstanceOf('Doctrine\Common\EventManager', $container->get('doctrine.dbal.default_connection.event_manager'));

View File

@ -218,7 +218,6 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
'user' => 'root',
'password' => null,
'driver' => 'pdo_mysql',
'logging' => false,
'driverOptions' => array(),
),
new Reference('doctrine.dbal.default_connection.configuration'),
@ -258,7 +257,6 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
'password' => 'sqlite_s3cr3t',
'dbname' => 'sqlite_db',
'memory' => true,
'logging' => false,
),
new Reference('doctrine.dbal.default_connection.configuration'),
new Reference('doctrine.dbal.default_connection.event_manager'),
@ -337,6 +335,26 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
$this->assertEquals('%doctrine.orm.cache.array.class%', $definition->getClass());
}
public function testLoadLogging()
{
$container = $this->getContainer();
$loader = new DoctrineExtension();
$container->registerExtension($loader);
$this->loadFromFile($container, 'dbal_logging');
$this->compileContainer($container);
$definition = $container->getDefinition('doctrine.dbal.log_connection.configuration');
$this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', array(new Reference('doctrine.dbal.logger')));
$definition = $container->getDefinition('doctrine.dbal.profile_connection.configuration');
$this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', array(new Reference('doctrine.dbal.logger.profiling')));
$definition = $container->getDefinition('doctrine.dbal.both_connection.configuration');
$this->assertDICDefinitionMethodCallOnce($definition, 'setSQLLogger', array(new Reference('doctrine.dbal.logger.chain')));
}
public function testBundleEntityAliases()
{
$container = $this->getContainer();

View File

@ -0,0 +1,29 @@
<?xml version="1.0" ?>
<srv:container xmlns="http://symfony.com/schema/dic/doctrine"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/doctrine http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">
<config>
<dbal default-connection="mysql">
<connection
name="log"
logging="true"
profiling="false" />
<connection
name="profile"
logging="false"
profiling="true" />
<connection
name="both"
logging="true"
profiling="true" />
<connection
name="none"
logging="false"
profiling="false" />
</dbal>
</config>
</srv:container>

View File

@ -0,0 +1,13 @@
doctrine:
dbal:
default_connection: mysql
connections:
log:
logging: true
profiling: false
profile:
logging: false
profiling: true
both:
logging: true
profiling: true

View File

@ -123,7 +123,7 @@ class DoctrineDataCollectorTest extends \PHPUnit_Framework_TestCase
->method('getManagerNames')
->will($this->returnValue(array('default' => 'doctrine.orm.default_entity_manager')));
$logger = $this->getMock('Symfony\Bridge\Doctrine\Logger\DbalLogger');
$logger = $this->getMock('Doctrine\Dbal\Logging\DebugStack');
$logger->queries = $queries;
return new DoctrineDataCollector($registry, $logger);