8000 Add ability to configure the PsrLogMessageProcessor · symfony/monolog-bundle@0d5b6a2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0d5b6a2

Browse files
committed
Add ability to configure the PsrLogMessageProcessor
1 parent 92bd02c commit 0d5b6a2

9 files changed

+194
-18
lines changed

DependencyInjection/Configuration.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111

1212
namespace Symfony\Bundle\MonologBundle\DependencyInjection;
1313

14+
use Monolog\Logger;
1415
use Symfony\Component\Config\Definition\BaseNode;
1516
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
1617
use Symfony\Component\Config\Definition\ConfigurationInterface;
1718
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
18-
use Monolog\Logger;
1919

2020
/**
2121
* This class contains the configuration information for the bundle
@@ -390,7 +390,18 @@ public function getConfigTreeBuilder()
390390
->booleanNode('bubble')->defaultTrue()->end()
391391
->scalarNode('app_name')->defaultNull()->end()
392392
->booleanNode('include_stacktraces')->defaultFalse()->end()
393-
->booleanNode('process_psr_3_messages')->defaultNull()->end()
393+
->arrayNode('process_psr_3_messages')
394+
->addDefaultsIfNotSet()
395+
->beforeNormalization()
396+
->ifTrue(static function ($v) { return !\is_array($v); })
397+
->then(static function ($v) { return ['enabled' => $v]; })
398+
->end()
399+
->children()
400+
->booleanNode('enabled')->defaultNull()->end()
401+
->scalarNode('date_format')->end()
402+
->booleanNode('remove_used_context_fields')->end()
403+
->end()
404+
->end()
394405
->scalarNode('path')->defaultValue('%kernel.logs_dir%/%kernel.environment%.log')->end() // stream and rotating
395406
->scalarNode('file_permission') // stream and rotating
396407
->defaultNull()

DependencyInjection/MonologExtension.php

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
namespace Symfony\Bundle\MonologBundle\DependencyInjection;
1313

1414
use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
15+
use Monolog\Handler\HandlerInterface;
1516
use Monolog\Logger;
1617
use Monolog\Processor\ProcessorInterface;
17-
use Monolog\Handler\HandlerInterface;
18+
use Monolog\Processor\PsrLogMessageProcessor;
1819
use Monolog\ResettableInterface;
1920
use Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy;
2021
use Symfony\Bridge\Monolog\Processor\SwitchUserTokenProcessor;
@@ -23,7 +24,6 @@
2324
use Symfony\Bundle\FullStack;
2425
use Symfony\Component\Config\FileLocator;
2526
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
26-
use Symfony\Component\DependencyInjection\ChildDefinition;
2727
use Symfony\Component\DependencyInjection\ContainerBuilder;
2828
use Symfony\Component\DependencyInjection\Definition;
2929
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
@@ -187,21 +187,13 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
187187
$definition->setConfigurator(['Symfony\\Bundle\\MonologBundle\\MonologBundle', 'includeStacktraces']);
188188
}
189189

190-
if (null === $handler['process_psr_3_messages']) {
191-
$handler['process_psr_3_messages'] = !isset($handler['handler']) && !$handler['members'];
190+
if (null === $handler['process_psr_3_messages']['enabled']) {
191+
$handler['process_psr_3_messages']['enabled'] = !isset($handler['handler']) && !$handler['members'];
192192
}
193193

194-
if ($handler['process_psr_3_messages']) {
195-
if (method_exists($handlerClass, 'pushProcessor')) {
196-
$processorId = 'monolog.processor.psr_log_message';
197-
if (!$container->hasDefinition($processorId)) {
198-
$processor = new Definition('Monolog\\Processor\\PsrLogMessageProcessor');
199-
$processor->setPublic(false);
200-
$container->setDefinition($processorId, $processor);
201-
}
202-
203-
$definition->addMethodCall('pushProcessor', [new Reference($processorId)]);
204-
}
194+
if ($handler['process_psr_3_messages']['enabled'] && method_exists($handlerClass, 'pushProcessor')) {
195+
$processorId = $this->buildPsrLogMessageProcessor($container, $handler['process_psr_3_messages']);
196+
$definition->addMethodCall('pushProcessor', [new Reference($processorId)]);
205197
}
206198

207199
switch ($handler['type']) {
@@ -1023,4 +1015,40 @@ private function getHandlerClassByType($handlerType)
10231015

10241016
return $typeToClassMapping[$handlerType];
10251017
}
1018+
1019+
private function buildPsrLogMessageProcessor(ContainerBuilder $container, array $processorOptions): string
1020+
{
1021+
static $hasConstructorArguments;
1022+
1023+
if (!isset($hasConstructorArguments)) {
1024+
$reflectionConstructor = (new \ReflectionClass(PsrLogMessageProcessor::class))->getConstructor();
1025+
$hasConstructorArguments = null !== $reflectionConstructor && $reflectionConstructor->getNumberOfParameters() > 0;
1026+
unset($reflectionConstructor);
1027+
}
1028+
1029+
$processorId = 'monolog.processor.psr_log_message';
1030+
$processorArguments = [];
1031+
1032+
unset($processorOptions['enabled']);
1033+
1034+
if (!empty($processorOptions)) {
1035+
if (!$hasConstructorArguments) {
1036+
throw new \RuntimeException('Monolog 1.26 or higher is required for the "date_format" and "remove_used_context_fields" options to be used.');
1037+
}
1038+
$processorArguments = [
1039+
$processorOptions['date_format'] ?? null,
1040+
$processorOptions['remove_used_context_fields'] ?? false,
1041+
];
1042+
$processorId .= '.'.ContainerBuilder::hash($processorArguments);
1043+
}
1044+
1045+
if (!$container->hasDefinition($processorId)) {
1046+
$processor = new Definition(PsrLogMessageProcessor::class);
1047+
$processor->setPublic(false);
1048+
$processor->setArguments($processorArguments);
1049+
$container->setDefinition($processorId, $processor);
1050+
}
1051+
1052+
return $processorId;
1053+
}
10261054
}

Resources/config/schema/monolog-1.0.xsd

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<xsd:element name="accepted-level" type="level" minOccurs="0" maxOccurs="unbounded" />
3030
<xsd:element name="to-email" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
3131
<xsd:element name="header" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
32+
<xsd:element name="process-psr-3-messages" type="process-psr-3-messages" minOccurs="0" maxOccurs="1" />
3233
</xsd:sequence>
3334
<xsd:attribute name="type" type="xsd:string" />
3435
<xsd:attribute name="priority" type="xsd:integer" />
@@ -192,7 +193,13 @@
192193

193194
<xsd:complexType name="headers">
194195
<xsd:sequence>
195-
<xsd:any minOccurs="0" processContents="lax"/>
196+
<xsd:any minOccurs="0" processContents="lax" />
196197
</xsd:sequence>
197198
</xsd:complexType>
199+
200+
<xsd:complexType name="process-psr-3-messages">
201+
<xsd:attribute name="enabled" type="xsd:boolean" />
202+
<xsd:attribute name="date-format" type="xsd:string" />
203+
<xsd:attribute name="remove-used-context-fields" type="xsd:boolean" />
204+
</xsd:complexType>
198205
</xsd:schema>

Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,41 @@ public function testConsoleFormatterOptionsRename()
489489
$this->assertArrayNotHasKey('console_formater_options', $config['handlers']['both2']);
490490
}
491491

492+
/**
493+
* @dataProvider processPsr3MessagesProvider
494+
*/
495+
public function testWithProcessPsr3Messages(array $configuration, array $processedConfiguration): void
496+
{
497+
$configs = [
498+
[
499+
'handlers' => [
500+
'main' => ['type' => 'stream'] + $configuration,
501+
],
502+
],
503+
];
504+
505+
$config = $this->process($configs);
506+
507+
$this->assertEquals($processedConfiguration, $config['handlers']['main']['process_psr_3_messages']);
508+
}
509+
510+
public function processPsr3MessagesProvider(): iterable
511+
{
512+
yield 'Not specified' => [[], ['enabled' => null]];
513+
yield 'Null' => [['process_psr_3_messages' => null], ['enabled' => true]];
514+
yield 'True' => [['process_psr_3_messages' => true], ['enabled' => true]];
515+
yield 'False' => [['process_psr_3_messages' => false], ['enabled' => false]];
516+
517+
yield 'Date format' => [
518+
['process_psr_3_messages' => ['date_format' => 'Y']],
519+
['date_format' => 'Y', 'enabled' => null],
520+
];
521+
yield 'Enabled false & remove used' => [
522+
['process_psr_3_messages' => ['enabled' => false, 'remove_used_context_fields' => true]],
523+
['enabled' => false, 'remove_used_context_fields' => true],
524+
];
525+
}
526+
492527
/**
493528
* Processes an array of configurations and returns a compiled version.
494529
*

Tests/DependencyInjection/FixtureMonologExtensionTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection;
1313

1414
use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
15+
use Monolog\Processor\PsrLogMessageProcessor;
1516
use Symfony\Bridge\Monolog\Processor\SwitchUserTokenProcessor;
1617
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass;
1718
use Symfony\Bundle\MonologBundle\DependencyInjection\MonologExtension;
@@ -280,6 +281,55 @@ public function testPsr3MessageProcessingDisabled()
280281
$this->assertNotContainsEquals(['pushProcessor', [new Reference('monolog.processor.psr_log_message')]], $methodCalls, 'The PSR-3 processor should not be enabled');
281282
}
282283

284+
public function testPsrLogMessageProcessorHasConstructorArguments(): void
285+
{
286+
$reflectionConstructor = (new \ReflectionClass(PsrLogMessageProcessor::class))->getConstructor();
287+
if (null === $reflectionConstructor || $reflectionConstructor->getNumberOfParameters() <= 0) {
288+
$this->markTestSkipped('Monolog >= 1.26 is needed.');
289+
}
290+
291+
$container = $this->getContainer('process_psr_3_messages_with_arguments');
292+
293+
$processors = [
294+
'monolog.processor.psr_log_message' => ['name' => 'without_arguments', 'arguments' => []],
295+
'monolog.processor.psr_log_message.'.ContainerBuilder::hash($arguments = ['Y', false]) => [
296+
'name' => 'with_arguments',
297+
'arguments' => $arguments,
298+
],
299+
];
300+
foreach ($processors as $processorId => $settings) {
301+
$this->assertTrue($container->hasDefinition($processorId));
302+
$processor = $container->getDefinition($processorId);
303+
$this->assertDICConstructorArguments($processor, $settings['arguments']);
304+
305+
$this->assertTrue($container->hasDefinition($handlerId = 'monolog.handler.'.$settings['name']));
306+
$handler = $container->getDefinition($handlerId);
307+
$this->assertDICDefinitionMethodCallAt(0, $handler, 'pushProcessor', [new Reference($processorId)]);
308+
}
309+
}
310+
311+
public function testPsrLogMessageProcessorDoesNotHaveConstructorArguments(): void
312+
{
313+
$reflectionConstructor = (new \ReflectionClass(PsrLogMessageProcessor::class))->getConstructor();
314+
if (null !== $reflectionConstructor && $reflectionConstructor->getNumberOfParameters() > 0) {
315+
$this->markTestSkipped('Monolog < 1.26 is needed.');
316+
}
317+
318+
$container = $this->getContainer('process_psr_3_messages_without_arguments');
319+
320+
$this->assertTrue($container->hasDefinition($processorId = 'monolog.processor.psr_log_message'));
321+
$processor = $container->getDefinition($processorId);
322+
$this->assertDICConstructorArguments($processor, []);
323+
324+
$this->assertTrue($container->hasDefinition($handlerId = 'monolog.handler.without_arguments'));
325+
$handler = $container->getDefinition($handlerId);
326+
$this->assertDICDefinitionMethodCallAt(0, $handler, 'pushProcessor', [new Reference($processorId)]);
327+
328+
$this->expectException(\RuntimeException::class);
329+
$this->expectExceptionMessage('Monolog 1.26 or higher is required for the "date_format" and "remove_used_context_fields" options to be used.');
330+
$this->getContainer('process_psr_3_messages_with_arguments');
331+
}
332+
283333
public function testNativeMailer()
284334
{
285335
$container = $this->getContainer('native_mailer');
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:monolog="http://symfony.com/schema/dic/monolog"
6+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
7+
http://symfony.com/schema/dic/monolog http://symfony.com/schema/dic/monolog/monolog-1.0.xsd">
8+
<monolog:config>
9+
<monolog:handler name="with_arguments" type="stream">
10+
<monolog:process-psr-3-messages date-format="Y" />
11+
</monolog:handler>
12+
<monolog:handler name="without_arguments" type="stream">
13+
<monolog:process-psr-3-messages enabled="true" />
14+
</monolog:handler>
15+
</monolog:config>
16+
</container>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:monolog="http://symfony.com/schema/dic/monolog"
6+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
7+
http://symfony.com/schema/dic/monolog http://symfony.com/schema/dic/monolog/monolog-1.0.xsd">
8+
<monolog:config>
9+
<monolog:handler name="without_arguments" type="stream">
10+
<monolog:process-psr-3-messages enabled="true" />
11+
</monolog:handler>
12+
</monolog:config>
13+
</container>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
monolog:
2+
handlers:
3+
with_arguments:
4+
type: stream
5+
process_psr_3_messages:
6+
date_format: 'Y'
7+
without_arguments:
8+
type: stream
9+
process_psr_3_messages:
10+
enabled: true
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
monolog:
2+
handlers:
3+
without_arguments:
4+
type: stream
5+
process_psr_3_messages:
6+
enabled: true

0 commit comments

Comments
 (0)
0