Skip to content

Commit 8812fcd

Browse files
committed
console handler needs to update level on each record since console output verbosity is not immutable. also added tests for everything
1 parent 3156bdf commit 8812fcd

File tree

3 files changed

+192
-31
lines changed

3 files changed

+192
-31
lines changed

Handler/ConsoleHandler.php

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class ConsoleHandler extends AbstractProcessingHandler implements EventSubscribe
3434
/**
3535
* @var OutputInterface|null
3636
*/
37-
private $output;
37+
protected $output;
3838

3939
/**
4040
* Constructor.
@@ -53,51 +53,26 @@ public function __construct($bubble = true)
5353
*/
5454
public function isHandling(array $record)
5555
{
56-
return null !== $this->output && parent::isHandling($record);
56+
return $this->updateLevel() && parent::isHandling($record);
5757
}
5858

5959
/**
6060
* {@inheritdoc}
6161
*/
6262
public function handle(array $record)
6363
{
64-
if (null === $this->output) {
65-
return false;
66-
}
67-
68-
return parent::handle($record);
64+
// we have to update the logging level each time because the verbosity of the
65+
// console output might have changed in the meantime (it is not immutable)
66+
return $this->updateLevel() && parent::handle($record);
6967
}
7068

7169
/**
7270
* Sets the console output to use for printing logs.
7371
*
74-
* It enables the writing unless the output verbosity is set to quiet.
75-
*
7672
* @param OutputInterface $output The console output to use
7773
*/
7874
public function setOutput(OutputInterface $output)
7975
{
80-
if (OutputInterface::VERBOSITY_QUIET === $output->getVerbosity()) {
81-
$this->close();
82-
83-
return;
84-
}
85-
86-
switch ($output->getVerbosity()) {
87-
case OutputInterface::VERBOSITY_NORMAL:
88-
$this->setLevel(Logger::WARNING);
89-
break;
90-
case OutputInterface::VERBOSITY_VERBOSE:
91-
$this->setLevel(Logger::NOTICE);
92-
break;
93-
case OutputInterface::VERBOSITY_VERY_VERBOSE:
94-
$this->setLevel(Logger::INFO);
95-
break;
96-
default:
97-
$this->setLevel(Logger::DEBUG);
98-
break;
99-
}
100-
10176
$this->output = $output;
10277
}
10378

@@ -162,4 +137,33 @@ protected function getDefaultFormatter()
162137
{
163138
return new ConsoleFormatter();
164139
}
140+
141+
/**
142+
* Updates the logging level based on the verbosity setting of the console output.
143+
*
144+
* @return Boolean Whether the handler is enabled and verbosity is not set to quiet.
145+
*/
146+
private function updateLevel()
147+
{
148+
if (null === $this->output || OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
149+
return false;
150+
}
151+
152+
switch ($this->output->getVerbosity()) {
153+
case OutputInterface::VERBOSITY_NORMAL:
154+
$this->setLevel(Logger::WARNING);
155+
break;
156+
case OutputInterface::VERBOSITY_VERBOSE:
157+
$this->setLevel(Logger::NOTICE);
158+
break;
159+
case OutputInterface::VERBOSITY_VERY_VERBOSE:
160+
$this->setLevel(Logger::INFO);
161+
break;
162+
default:
163+
$this->setLevel(Logger::DEBUG);
164+
break;
165+
}
166+
167+
return true;
168+
}
165169
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
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\Handler;
13+
14+
use Symfony\Bridge\Monolog\Logger;
15+
use Symfony\Bundle\MonologBundle\Handler\ConsoleHandler;
16+
use Symfony\Bundle\MonologBundle\Tests\TestCase;
17+
use Symfony\Component\Console\Output\OutputInterface;
18+
19+
/**
20+
* Tests the ConsoleHandler and also the ConsoleFormatter.
21+
*
22+
* @author Tobias Schultze <http://tobion.de>
23+
*/
24+
class ConsoleHandlerTest extends TestCase
25+
{
26+
public function testConstructor()
27+
{
28+
$handler = new ConsoleHandler(false);
29+
$this->assertFalse($handler->getBubble(), 'the bubble parameter gets propagated');
30+
}
31+
32+
public function testIsHandling()
33+
{
34+
$handler = new ConsoleHandler();
35+
$this->assertFalse($handler->isHandling(array()), '->isHandling returns false when no output is set');
36+
}
37+
38+
/**
39+
* @dataProvider provideVerbosityMappingTests
40+
*/
41+
public function testVerbosityMapping($verbosity, $level, $isHandling)
42+
{
43+
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
44+
$output
45+
->expects($this->atLeastOnce())
46+
->method('getVerbosity')
47+
->will($this->returnValue($verbosity))
48+
;
49+
$handler = new ConsoleHandler();
50+
$handler->setOutput($output);
51+
$this->assertSame($isHandling, $handler->isHandling(array('level' => $level)),
52+
'->isHandling returns correct value depending on console verbosity and log level'
53+
);
54+
}
55+
56+
public function provideVerbosityMappingTests()
57+
{
58+
return array(
59+
array(OutputInterface::VERBOSITY_QUIET, Logger::ERROR, false),
60+
array(OutputInterface::VERBOSITY_NORMAL, Logger::WARNING, true),
61+
array(OutputInterface::VERBOSITY_NORMAL, Logger::NOTICE, false),
62+
array(OutputInterface::VERBOSITY_VERBOSE, Logger::NOTICE, true),
63+
array(OutputInterface::VERBOSITY_VERBOSE, Logger::INFO, false),
64+
array(OutputInterface::VERBOSITY_VERY_VERBOSE, Logger::INFO, true),
65+
array(OutputInterface::VERBOSITY_VERY_VERBOSE, Logger::DEBUG, false),
66+
array(OutputInterface::VERBOSITY_DEBUG, Logger::DEBUG, true),
67+
array(OutputInterface::VERBOSITY_DEBUG, Logger::EMERGENCY, true),
68+
);
69+
}
70+
71+
public function testVerbosityChanged()
72+
{
73+
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
74+
$output
75+
->expects($this->at(0))
76+
->method('getVerbosity')
77+
->will($this->returnValue(OutputInterface::VERBOSITY_QUIET))
78+
;
79+
$output
80+
->expects($this->at(1))
81+
->method('getVerbosity')
82+
->will($this->returnValue(OutputInterface::VERBOSITY_DEBUG))
83+
;
84+
$handler = new ConsoleHandler();
85+
$handler->setOutput($output);
86+
$this->assertFalse($handler->isHandling(array('level' => Logger::NOTICE)),
87+
'when verbosity is set to quiet, the handler does not handle the log'
88+
);
89+
$this->assertTrue($handler->isHandling(array('level' => Logger::NOTICE)),
90+
'since the verbosity of the output increased externally, the handler is now handling the log'
91+
);
92+
}
93+
94+
public function testGetFormatter()
95+
{
96+
$handler = new ConsoleHandler();
97+
$this->assertInstanceOf('Symfony\Bundle\MonologBundle\Formatter\ConsoleFormatter', $handler->getFormatter(),
98+
'-getFormatter returns ConsoleFormatter by default'
99+
);
100+
}
101+
102+
public function testWritingAndFormatting()
103+
{
104+
$output = $this->getMock('Symfony\Component\Console\Output\ConsoleOutputInterface');
105+
$output
106+
->expects($this->any())
107+
->method('getVerbosity')
108+
->will($this->returnValue(OutputInterface::VERBOSITY_DEBUG))
109+
;
110+
$output
111+
->expects($this->once())
112+
->method('write')
113+
->with('<info>[2013-05-29 16:21:54] app.INFO:</info> My info message [] []'."\n")
114+
;
115+
116+
$errorOutput = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
117+
$errorOutput
118+
->expects($this->once())
119+
->method('write')
120+
->with('<error>[2013-05-29 16:21:54] app.ERROR:</error> My error message [] []'."\n")
121+
;
122+
123+
$output
124+
->expects($this->any())
125+
->method('getErrorOutput')
126+
->will($this->returnValue($errorOutput))
127+
;
128+
129+
$handler = new ConsoleHandler(false);
130+
$handler->setOutput($output);
131+
132+
$infoRecord = array(
133+
'message' => 'My info message',
134+
'context' => array(),
135+
'level' => Logger::INFO,
136+
'level_name' => Logger::getLevelName(Logger::INFO),
137+
'channel' => 'app',
138+
'datetime' => new \DateTime('2013-05-29 16:21:54'),
139+
'extra' => array(),
140+
);
141+
142+
$this->assertTrue($handler->handle($infoRecord), 'The handler finished handling the log as bubble is false.');
143+
144+
$errorRecord = array(
145+
'message' => 'My error message',
146+
'context' => array(),
147+
'level' => Logger::ERROR,
148+
'level_name' => Logger::getLevelName(Logger::ERROR),
149+
'channel' => 'app',
150+
'datetime' => new \DateTime('2013-05-29 16:21:54'),
151+
'extra' => array(),
152+
);
153+
154+
$this->assertTrue($handler->handle($errorRecord), 'The handler finished handling the log as bubble is false.');
155+
}
156+
}

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"monolog/monolog": "~1.3"
2424
},
2525
"require-dev": {
26-
"symfony/yaml": "~2.2-beta2"
26+
"symfony/yaml": "~2.2-beta2",
27+
"symfony/console": "~2.2-beta2"
2728
},
2829
"suggest": {
2930
"symfony/console": "For the possibility to show log messages in console commands depending on verbosity settings."

0 commit comments

Comments
 (0)