Skip to content

Commit

Permalink
Allow to use dbal logging middleware
Browse files Browse the repository at this point in the history
instead of deprecated SQLLogger
  • Loading branch information
l-vo committed Jan 2, 2022
1 parent b75fb15 commit c416af5
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
25 changes: 25 additions & 0 deletions DependencyInjection/DoctrineExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
use Doctrine\DBAL\Driver\Middleware;
use Doctrine\DBAL\Logging\LoggerChain;
use Doctrine\DBAL\Tools\Console\Command\ImportCommand;
use Doctrine\DBAL\Tools\Console\ConnectionProvider;
Expand Down Expand Up @@ -41,6 +42,7 @@
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
Expand Down Expand Up @@ -156,6 +158,7 @@ protected function loadDbalConnection($name, array $connection, ContainerBuilder
$configuration = $container->setDefinition(sprintf('doctrine.dbal.%s_connection.configuration', $name), new ChildDefinition('doctrine.dbal.connection.configuration'));
$logger = null;
if ($connection['logging']) {
$this->useMiddlewaresIfAvailable($connection, $container, $name, $configuration);
$logger = new Reference('doctrine.dbal.logger');
}

Expand Down Expand Up @@ -1066,4 +1069,26 @@ private function createArrayAdapterCachePool(ContainerBuilder $container, string

return $id;
}

/** @param array<string, mixed> $connection */
protected function useMiddlewaresIfAvailable(array $connection, ContainerBuilder $container, string $name, Definition $configuration): void
{
/** @psalm-suppress UndefinedClass */
if (! interface_exists(Middleware::class)) {
return;
}

$container
->getDefinition('doctrine.dbal.logger')
->replaceArgument(0, null);

$loggingMiddlewareDef = $container->setDefinition(
sprintf('doctrine.dbal.%s_connection.logging_middleware', $name),
new ChildDefinition('doctrine.dbal.logging_middleware')
);
$loggingMiddlewareDef->addArgument(new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE));
$loggingMiddlewareDef->addTag('monolog.logger', ['channel' => 'doctrine']);

$configuration->addMethodCall('setMiddlewares', [[$loggingMiddlewareDef]]);
}
}
3 changes: 3 additions & 0 deletions Resources/config/dbal.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
<argument type="service" id="debug.stopwatch" on-invalid="null" />
</service>

<service id="doctrine.dbal.logging_middleware" class="Doctrine\DBAL\Logging\Middleware" abstract="true">
</service>

<service id="data_collector.doctrine" class="%doctrine.data_collector.class%" public="false">
<tag name="data_collector" template="@Doctrine/Collector/db.html.twig" id="db" priority="250" />
<argument type="service" id="doctrine" />
Expand Down
86 changes: 86 additions & 0 deletions Tests/DependencyInjection/DoctrineExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\Connection as DriverConnection;
use Doctrine\DBAL\Driver\Middleware;
use Doctrine\DBAL\Sharding\PoolingShardManager;
use Doctrine\DBAL\Sharding\SQLAzure\SQLAzureShardManager;
use Doctrine\ORM\EntityManagerInterface;
Expand All @@ -33,6 +34,7 @@
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Messenger\MessageBusInterface;

use function array_filter;
use function array_values;
use function class_exists;
use function interface_exists;
Expand Down Expand Up @@ -1143,6 +1145,90 @@ public function testAsEntityListenerAttribute()
$this->assertSame([$expected], $definition->getTag('doctrine.orm.entity_listener'));
}

public function testMiddlewaresAreNotAvailable(): void
{
/** @psalm-suppress UndefinedClass */
if (interface_exists(Middleware::class)) {
$this->markTestSkipped(sprintf('%s needs %s to not exist', __METHOD__, Middleware::class));
}

$container = $this->getContainer();
$extension = new DoctrineExtension();

$config = BundleConfigurationBuilder::createBuilderWithBaseValues()
->addConnection([
'connections' => [
'default' => [
'password' => 'foo',
'logging' => true,
],
],
])
->addBaseEntityManager()
->build();

$extension->load([$config], $container);

$loggerDef = $container->getDefinition('doctrine.dbal.logger');
$tags = $loggerDef->getTag('monolog.logger');
$doctrineLoggerTags = array_filter($tags, static function (array $tag): bool {
return ($tag['channel'] ?? null) === 'doctrine';
});
$this->assertCount(1, $doctrineLoggerTags);

$this->assertInstanceOf(Reference::class, $loggerDef->getArgument(0));
$this->assertSame('logger', (string) $loggerDef->getArgument(0));

$this->assertFalse($container->hasDefinition('doctrine.dbal.default_connection.logging_middleware'));
}

public function testMiddlewaresAreAvailable(): void
{
/** @psalm-suppress UndefinedClass */
if (! interface_exists(Middleware::class)) {
$this->markTestSkipped(sprintf('%s needs %s to exist', __METHOD__, Middleware::class));
}

$container = $this->getContainer();
$extension = new DoctrineExtension();

$config = BundleConfigurationBuilder::createBuilderWithBaseValues()
->addConnection([
'connections' => [
'default' => [
'password' => 'foo',
'logging' => true,
],
],
])
->addBaseEntityManager()
->build();

$extension->load([$config], $container);

$loggerDef = $container->getDefinition('doctrine.dbal.logger');
$this->assertNull($loggerDef->getArgument(0));

$loggingMiddlewareDef = $container->getDefinition('doctrine.dbal.default_connection.logging_middleware');
$this->assertInstanceOf(Reference::class, $loggingMiddlewareDef->getArgument(0));
$this->assertSame('logger', (string) $loggingMiddlewareDef->getArgument(0));
$tags = $loggingMiddlewareDef->getTag('monolog.logger');
$doctrineLoggerTags = array_filter($tags, static function (array $tag): bool {
return ($tag['channel'] ?? null) === 'doctrine';
});
$this->assertCount(1, $doctrineLoggerTags);

$connectionConfiguration = $container->getDefinition('doctrine.dbal.default_connection.configuration');
$setMiddlewareCalls = array_filter($connectionConfiguration->getMethodCalls(), static function (array $call) {
return $call[0] === 'setMiddlewares';
});
$this->assertCount(1, $setMiddlewareCalls);
$callArgs = $setMiddlewareCalls[0][1];
$this->assertCount(1, $callArgs);
$this->assertCount(1, $callArgs[0]);
$this->assertInstanceOf(Definition::class, $callArgs[0][0]);
}

// phpcs:enable

/** @param list<string> $bundles */
Expand Down

0 comments on commit c416af5

Please sign in to comment.