Skip to content

Commit c3fbde4

Browse files
fabpotstof
authored andcommitted
fixed logger that logs to STDERR when no handlers are registered
1 parent 77618b5 commit c3fbde4

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MonologBundle\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Definition;
17+
use Symfony\Component\DependencyInjection\Reference;
18+
19+
/**
20+
* Fixes loggers with no handlers (by registering a "null" one).
21+
*
22+
* Monolog 1.x adds a default handler logging on STDERR when a logger has
23+
* no registered handlers. This is NOT what what we want in Symfony, so in such
24+
* cases, we add a "null" handler to avoid the issue.
25+
*
26+
* Note that Monolog 2.x does not register a default handler anymore, so this pass can
27+
* be removed when MonologBundle minimum version of Monolog is bumped to 2.0.
28+
*
29+
* @author Fabien Potencier <[email protected]>
30+
*
31+
* @see https://github.com/Seldaek/monolog/commit/ad37b7b2d11f300cbace9f5e84f855d329519e28
32+
*/
33+
class FixEmptyLoggerPass implements CompilerPassInterface
34+
{
35+
private $channelPass;
36+
37+
public function __construct(LoggerChannelPass $channelPass)
38+
{
39+
$this->channelPass = $channelPass;
40+
}
41+
42+
public function process(ContainerBuilder $container)
43+
{
44+
$container->register('monolog.handler.null_internal', 'Monolog\Handler\NullHandler');
45+
foreach ($this->channelPass->getChannels() as $channel) {
46+
$def = $container->getDefinition($channel === 'app' ? 'monolog.logger' : 'monolog.logger.'.$channel);
47+
foreach ($def->getMethodCalls() as $method) {
48+
if ('pushHandler' === $method[0]) {
49+
continue 2;
50+
}
51+
}
52+
53+
$def->addMethodCall('pushHandler', array(new Reference('monolog.handler.null_internal')));
54+
}
55+
}
56+
}

MonologBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass;
2121
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\DebugHandlerPass;
2222
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\AddProcessorsPass;
23+
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\RemoveEmptyLoggerPass;
2324

2425
/**
2526
* Bundle.
@@ -34,6 +35,7 @@ public function build(ContainerBuilder $container)
3435

3536
$container->addCompilerPass($channelPass = new LoggerChannelPass());
3637
$container->addCompilerPass(new DebugHandlerPass($channelPass));
38+
$container->addCompilerPass(new RemoveEmptyLoggerPass($channelPass));
3739
$container->addCompilerPass(new AddProcessorsPass());
3840
$container->addCompilerPass(new AddSwiftMailerTransportPass());
3941
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection\Compiler;
13+
14+
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\FixEmptyLoggerPass;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
17+
class FixEmptyLoggerPassTest extends \PHPUnit_Framework_TestCase
18+
{
19+
public function testProcess()
20+
{
21+
$loggerChannelPass = $this->getMockBuilder('Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass')->getMock();
22+
$loggerChannelPass->expects($this->any())->method('getChannels')->will($this->returnValue(array('foo', 'bar')));
23+
24+
$container = new ContainerBuilder();
25+
$container->register('monolog.logger.foo', 'Monolog\Logger');
26+
$container->register('monolog.logger.bar', 'Monolog\Logger')->addMethodCall('pushHandler');
27+
28+
$pass = new FixEmptyLoggerPass($loggerChannelPass);
29+
$pass->process($container);
30+
31+
$calls = $container->getDefinition('monolog.logger.foo')->getMethodCalls();
32+
$this->assertCount(1, $calls);
33+
$this->assertSame('pushHandler', $calls[0][0]);
34+
$this->assertSame('monolog.handler.null_internal', (string) $calls[0][1][0]);
35+
36+
$calls = $container->getDefinition('monolog.logger.bar')->getMethodCalls();
37+
$this->assertCount(1, $calls);
38+
}
39+
}

0 commit comments

Comments
 (0)