diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 78718d7d..631d9608 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -592,6 +592,7 @@ public function getConfigTreeBuilder() ->end() ->end() ->scalarNode('formatter')->end() + ->booleanNode('nested')->defaultFalse()->end() ->end() ->validate() ->ifTrue(function ($v) { return 'service' === $v['type'] && !empty($v['formatter']); }) diff --git a/DependencyInjection/MonologExtension.php b/DependencyInjection/MonologExtension.php index c411d530..ace34397 100644 --- a/DependencyInjection/MonologExtension.php +++ b/DependencyInjection/MonologExtension.php @@ -308,7 +308,7 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler $handler['passthru_level'] = $this->levelToMonologConst($handler['passthru_level']); } $nestedHandlerId = $this->getHandlerId($handler['handler']); - $this->nestedHandlers[] = $nestedHandlerId; + $this->markNestedHandler($nestedHandlerId); if (isset($handler['activation_strategy'])) { $activation = new Reference($handler['activation_strategy']); @@ -339,7 +339,7 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler } $nestedHandlerId = $this->getHandlerId($handler['handler']); - $this->nestedHandlers[] = $nestedHandlerId; + $this->markNestedHandler($nestedHandlerId); $minLevelOrList = !empty($handler['accepted_levels']) ? $handler['accepted_levels'] : $handler['min_level']; $definition->setArguments(array( @@ -352,7 +352,7 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler case 'buffer': $nestedHandlerId = $this->getHandlerId($handler['handler']); - $this->nestedHandlers[] = $nestedHandlerId; + $this->markNestedHandler($nestedHandlerId); $definition->setArguments(array( new Reference($nestedHandlerId), @@ -368,7 +368,7 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler $references = array(); foreach ($handler['members'] as $nestedHandler) { $nestedHandlerId = $this->getHandlerId($nestedHandler); - $this->nestedHandlers[] = $nestedHandlerId; + $this->markNestedHandler($nestedHandlerId); $references[] = new Reference($nestedHandlerId); } @@ -631,6 +631,10 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler throw new \InvalidArgumentException(sprintf('Invalid handler type "%s" given for handler "%s"', $handler['type'], $name)); } + if (!empty($handler['nested']) && true === $handler['nested']) { + $this->markNestedHandler($handlerId); + } + if (!empty($handler['formatter'])) { $definition->addMethodCall('setFormatter', array(new Reference($handler['formatter']))); } @@ -639,6 +643,15 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler return $handlerId; } + private function markNestedHandler($nestedHandlerId) + { + if (in_array($nestedHandlerId, $this->nestedHandlers)) { + return; + } + + $this->nestedHandlers[] = $nestedHandlerId; + } + private function getHandlerId($name) { return sprintf('monolog.handler.%s', $name); diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php index 3fb49e0c..904a596a 100644 --- a/Tests/DependencyInjection/ConfigurationTest.php +++ b/Tests/DependencyInjection/ConfigurationTest.php @@ -36,6 +36,7 @@ public function testProcessSimpleCase() $this->assertArrayHasKey('foobar', $config['handlers']); $this->assertEquals('stream', $config['handlers']['foobar']['type']); $this->assertEquals('/foo/bar', $config['handlers']['foobar']['path']); + $this->assertFalse($config['handlers']['foobar']['nested']); } public function provideProcessStringChannels() @@ -321,6 +322,20 @@ public function testWithFilePermission() $this->assertSame(0777, $config['handlers']['bar']['file_permission']); } + public function testWithNestedHandler() + { + $configs = array( + array( + 'handlers' => array('foobar' => array('type' => 'stream', 'path' => '/foo/bar', 'nested' => true)) + ) + ); + + $config = $this->process($configs); + + + $this->assertTrue($config['handlers']['foobar']['nested']); + } + /** * Processes an array of configurations and returns a compiled version. * diff --git a/Tests/DependencyInjection/MonologExtensionTest.php b/Tests/DependencyInjection/MonologExtensionTest.php index d0ddb64e..f0567768 100644 --- a/Tests/DependencyInjection/MonologExtensionTest.php +++ b/Tests/DependencyInjection/MonologExtensionTest.php @@ -50,6 +50,25 @@ public function testLoadWithCustomValues() $this->assertDICConstructorArguments($handler, array('/tmp/symfony.log', \Monolog\Logger::ERROR, false, 0666)); } + public function testLoadWithNestedHandler() + { + $container = $this->getContainer(array(array('handlers' => array( + 'custom' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => false, 'level' => 'ERROR', 'file_permission' => '0666'), + 'nested' => array('type' => 'stream', 'path' => '/tmp/symfony.log', 'bubble' => false, 'level' => 'ERROR', 'file_permission' => '0666', 'nested' => true) + )))); + $this->assertTrue($container->hasDefinition('monolog.logger')); + $this->assertTrue($container->hasDefinition('monolog.handler.custom')); + $this->assertTrue($container->hasDefinition('monolog.handler.nested')); + + $logger = $container->getDefinition('monolog.logger'); + // Nested handler must not be pushed to logger + $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.custom'))); + + $handler = $container->getDefinition('monolog.handler.custom'); + $this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%'); + $this->assertDICConstructorArguments($handler, array('/tmp/symfony.log', \Monolog\Logger::ERROR, false, 0666)); + } + /** * @expectedException InvalidArgumentException */