10000 Use a specific channel for deprecations · symfony/symfony@9867d58 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9867d58

Browse files
committed
Use a specific channel for deprecations
1 parent 4170346 commit 9867d58

File tree

5 files changed

+147
-26
lines changed

5 files changed

+147
-26
lines changed

src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
<service id="debug.debug_handlers_listener" class="Symfony\Component\HttpKernel\EventListener\DebugHandlersListener">
1515
<tag name="kernel.event_subscriber" />
1616
<tag name="monolog.logger" channel="php" />
17+
<tag name="monolog.logger" channel="deprecation" />
1718
<argument>null</argument><!-- Exception handler -->
18-
<argument type="service" id="logger" on-invalid="null" />
19+
<argument type="service" id="monolog.logger.php" on-invalid="null" />
1920
<argument>null</argument><!-- Log levels map for enabled error levels -->
2021
<argument>%debug.error_handler.throw_at%</argument>
2122
<argument>%kernel.debug%</argument>
2223
<argument type="service" id="debug.file_link_formatter" />
2324
<argument>%kernel.debug%</argument>
25+
<argument type="service" id="monolog.logger.deprecation" on-invalid="null" />
2426
</service>
2527

2628
<service id="debug.file_link_formatter" class="Symfony\Component\HttpKernel\Debug\FileLinkFormatter">

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ public function testEnabledPhpErrorsConfig()
425425
$container = $this->createContainerFromFile('php_errors_enabled');
426426

427427
$definition = $container->getDefinition('debug.debug_handlers_listener');
428-
$this->assertEquals(new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(1));
428+
$this->assertEquals(new Reference('monolog.logger.php', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(1));
429429
$this->assertNull($definition->getArgument(2));
430430
$this->assertSame(-1, $container->getParameter('debug.error_handler.throw_at'));
431431
}
@@ -445,7 +445,7 @@ public function testPhpErrorsWithLogLevel()
445445
$container = $this->createContainerFromFile('php_errors_log_level');
446446

447447
$definition = $container->getDefinition('debug.debug_handlers_listener');
448-
$this->assertEquals(new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(1));
< 6D40 code>448+
$this->assertEquals(new Reference('monolog.logger.php', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(1));
449449
$this->assertSame(8, $definition->getArgument(2));
450450
}
451451

src/Symfony/Component/HttpKernel/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
CHANGELOG
22
=========
33

4+
5.2.0
5+
-----
6+
* Allow to use a specific logger channel for deprecations
7+
48
5.1.0
59
-----
610

src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class DebugHandlersListener implements EventSubscriberInterface
3232
{
3333
private $exceptionHandler;
3434
private $logger;
35+
private $deprecationLogger;
3536
private $levels;
3637
private $throwAt;
3738
private $scream;
@@ -48,7 +49,7 @@ class DebugHandlersListener implements EventSubscriberInterface
4849
* @param string|FileLinkFormatter|null $fileLinkFormat The format for links to source files
4950
* @param bool $scope Enables/disables scoping mode
5051
*/
51-
public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, ?int $throwAt = E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true)
52+
public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, ?int $throwAt = E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true, LoggerInterface $deprecationLogger = null)
5253
{
5354
$this->exceptionHandler = $exceptionHandler;
5455
$this->logger = $logger;
@@ -57,6 +58,7 @@ public function __construct(callable $exceptionHandler = null, LoggerInterface $
5758
$this->scream = $scream;
5859
$this->fileLinkFormat = $fileLinkFormat;
5960
$this->scope = $scope;
61+
$this->deprecationLogger = $deprecationLogger;
6062
}
6163

6264
/**
@@ -76,31 +78,30 @@ public function configure(object $event = null)
7678
$handler = \is_array($handler) ? $handler[0] : null;
7779
restore_exception_handler();
7880

79-
if ($this->logger || null !== $this->throwAt) {
80-
if ($handler instanceof ErrorHandler) {
81-
if ($this->logger) {
82-
$handler->setDefaultLogger($this->logger, $this->levels);
83-
if (\is_array($this->levels)) {
84-
$levels = 0;
85-
foreach ($this->levels as $type => $log) {
86-
$levels |= $type;
87-
}
88-
} else {
89-
$levels = $this->levels;
90-
}
91-
if ($this->scream) {
92-
$handler->screamAt($levels);
81+
if ($handler instanceof ErrorHandler) {
82+
if ($this->logger || $this->deprecationLogger) {
83+
$this->setDefaultLoggers($handler);
84+
if (\is_array($this->levels)) {
85+
$levels = 0;
86+
foreach ($this->levels as $type => $log) {
87+
$levels |= $type;
9388
}
94-
if ($this->scope) {
95-
$handler->scopeAt($levels & ~E_USER_DEPRECATED & ~E_DEPRECATED);
96-
} else {
97-
$handler->scopeAt(0, true);
98-
}
99-
$this->logger = $this->levels = null;
89+
} else {
90+
$levels = $this->levels;
10091
}
101-
if (null !== $this->throwAt) {
102-
$handler->throwAt($this->throwAt, true);
92+
93+
if ($this->scream) {
94+
$handler->screamAt($levels);
10395
}
96+
if ($this->scope) {
97+
$handler->scopeAt($levels & ~E_USER_DEPRECATED & ~E_DEPRECATED);
98+
} else {
99+
$handler->scopeAt(0, true);
100+
}
101+
$this->logger = $this->deprecationLogger = $this->levels = null;
102+
}
103+
if (null !== $this->throwAt) {
104+
$handler->throwAt($this->throwAt, true);
104105
}
105106
}
106107
if (!$this->exceptionHandler) {
@@ -135,6 +136,34 @@ public function configure(object $event = null)
135136
}
136137
}
137138

139+
private function setDefaultLoggers(ErrorHandler $handler): void
140+
{
141+
if (\is_array($this->levels)) {
142+
$levelsDeprecatedOnly = [];
143+
$levelsWithoutDeprecated = [];
144+
foreach ($this->levels as $type => $log) {
145+
if (E_DEPRECATED == $type || E_USER_DEPRECATED == $type) {
146+
$levelsDeprecatedOnly[$type] = $log;
147+
} else {
148+
$levelsWithoutDeprecated[$type] = $log;
149+
}
150+
}
151+
} else {
152+
$levelsDeprecatedOnly = $this->levels & (E_DEPRECATED | E_USER_DEPRECATED);
153+
$levelsWithoutDeprecated = $this->levels & ~E_DEPRECATED & ~E_USER_DEPRECATED;
154+
}
155+
156+
$defaultLoggerLevels = $this->levels;
157+
if ($this->deprecationLogger && $levelsDeprecatedOnly) {
158+
$handler->setDefaultLogger($this->deprecationLogger, $levelsDeprecatedOnly);
159+
$defaultLoggerLevels = $levelsWithoutDeprecated;
160+
}
161+
162+
if ($this->logger && $defaultLoggerLevels) {
163+
$handler->setDefaultLogger($this->logger, $defaultLoggerLevels);
164+
}
165+
}
166+
138167
public static function getSubscribedEvents(): array
139168
{
140169
$events = [KernelEvents::REQUEST => ['configure', 2048]];

src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\HttpKernel\Tests\EventListener;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Psr\Log\LoggerInterface;
1516
use Psr\Log\LogLevel;
1617
use Symfony\Component\Console\Application;
1718
use Symfony\Component\Console\Command\Command;
@@ -150,4 +151,89 @@ public function testReplaceExistingExceptionHandler()
150151

151152
$this->assertSame($userHandler, $eHandler->setExceptionHandler('var_dump'));
152153
}
154+
155+
public function provideLevelsAssignedToLoggers(): array
156+
{
157+
return [
158+
[false, false, '0', null, null],
159+
[false, false, E_ALL, null, null],
160+
[false, false, [], null, null],
161+
[false, false, [E_WARNING => LogLevel::WARNING, E_USER_DEPRECATED => LogLevel::NOTICE], null, null],
162+
163+
[true, false, E_ALL, E_ALL, null],
164+
[true, false, E_DEPRECATED, E_DEPRECATED, null],
165+
[true, false, [], null, null],
166+
[true, false, [E_WARNING => LogLevel::WARNING, E_DEPRECATED => LogLevel::NOTICE], [E_WARNING => LogLevel::WARNING, E_DEPRECATED => LogLevel::NOTICE], null],
167+
168+
[false, true, '0', null, null],
169+
[false, true, E_ALL, null, E_DEPRECATED | E_USER_DEPRECATED],
170+
[false, true, E_ERROR, null, null],
171+
[false, true, [], null, null],
172+
[false, true, [E_ERROR => LogLevel::ERROR, E_DEPRECATED => LogLevel::DEBUG], null, [E_DEPRECATED => LogLevel::DEBUG]],
173+
174+
[true, true, '0', null, null],
175+
[true, true, E_ALL, E_ALL & ~(E_DEPRECATED | E_USER_DEPRECATED), E_DEPRECATED | E_USER_DEPRECATED],
176+
[true, true, E_ERROR, E_ERROR, null],
177+
[true, true, E_USER_DEPRECATED, null, E_USER_DEPRECATED],
178+
[true, true, [E_ERROR => LogLevel::ERROR, E_DEPRECATED => LogLevel::DEBUG], [E_ERROR => LogLevel::ERROR], [E_DEPRECATED => LogLevel::DEBUG]],
179+
[true, true, [E_ERROR => LogLevel::ALERT], [E_ERROR => LogLevel::ALERT], null],
180+
[true, true, [E_USER_DEPRECATED => LogLevel::NOTICE], null, [E_USER_DEPRECATED => LogLevel::NOTICE]],
181+
];
182+
}
183+
184+
/**
185+
* @dataProvider provideLevelsAssignedToLoggers
186+
*
187+
* @param array|string $levels
188+
* @param array|string|null $expectedLoggerLevels
189+
* @param array|string|null $expectedDeprecationLoggerLevels
190+
*/
191+
public function testLevelsAssignedToLoggers(bool $hasLogger, bool $hasDeprecationLogger, $levels, $expectedLoggerLevels, $expectedDeprecationLoggerLevels)
192+
{
193+
if (!class_exists(ErrorHandler::class)) {
194+
$this->markTestSkipped('ErrorHandler component is required to run this test.');
195+
}
196+
197+
$handler = $this->createMock(ErrorHandler::class);
198+
199+
$expectedCalls = [];
200+
$logger = null;
201+
202+
$deprecationLogger = null;
203+
if ($hasDeprecationLogger) {
204+
$deprecationLogger = $this->createMock(LoggerInterface::class);
205+
if (null !== $expectedDeprecationLoggerLevels) {
206+
$expectedCalls[] = [$deprecationLogger, $expectedDeprecationLoggerLevels];
207+
}
208+
}
209+
210+
if ($hasLogger) {
211+
$logger = $this->createMock(LoggerInterface::class);
212+
if (null !== $expectedLoggerLevels) {
213+
$expectedCalls[] = [$logger, $expectedLoggerLevels];
214+
}
215+
}
216+
217+
$handler
218+
->expects($this->exactly(\count($expectedCalls)))
219+
->method('setDefaultLogger')
220+
->withConsecutive(...$expectedCalls);
221+
222+
$sut = new DebugHandlersListener(null, $logger, $levels, null, true, null, true, $deprecationLogger);
223+
$prevHander = set_exception_handler([$handler, 'handleError']);
224+
225+
try {
226+
$handler
227+
->method('handleError')
228+
->willReturnCallback(function () use ($prevHander) {
229+
$prevHander(...\func_get_args());
230+
});
231+
232+
$sut->configure();
233+
set_exception_handler($prevHander);
234+
} catch (\Exception $e) {
235+
set_exception_handler($prevHander);
236+
throw $e;
237+
}
238+
}
153239
}

0 commit comments

Comments
 (0)
0