Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c6b64c3

Browse filesBrowse files
committed
feature #485 Add priority field to processor tags (HypeMC)
This PR was merged into the 3.x branch. Discussion ---------- Add priority field to processor tags | Q | A | ------------- | --- | Branch? | 3.x | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | - | License | MIT Continuation of #455. ```yaml Foo\Bar\Log\Processors\FirstProcessor: tags: - { name: monolog.processor, channel: http } Foo\Bar\Log\Processors\SecondProcessor: tags: - { name: monolog.processor, channel: http, priority: -10 } # last Foo\Bar\Log\Processors\ThirdProcessor: tags: - { name: monolog.processor, channel: http, priority: -20 } # very last ``` ```php #[AsMonologProcessor(priority: -10)] class SecondProcessor {} #[AsMonologProcessor(priority: -20)] class ThirdProcessor {} ``` **Probably better to review with [whitespace changes ignored](https://github.com/symfony/monolog-bundle/pull/485/files?w=1).** Commits ------- 4165954 Add priority field to processor tags
2 parents a716f93 + 4165954 commit c6b64c3
Copy full SHA for c6b64c3

File tree

Expand file treeCollapse file tree

5 files changed

+126
-35
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+126
-35
lines changed
Open diff view settings
Collapse file

‎CHANGELOG.md‎

Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* Fix `host` configuration for `elastic_search` handler
1717
* Add `hosts` configuration for `elastica` handler
1818
* Add `enabled` option to `handlers` configuration
19+
* Add `priority` field to `processor` tag
1920

2021
## 3.10.0 (2023-11-06)
2122

Collapse file

‎config/monolog.php‎

Copy file name to clipboardExpand all lines: config/monolog.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
->parent('monolog.logger_prototype')
3939
->args(['index_0' => 'app'])
4040
->call('useMicrosecondTimestamps', [param('monolog.use_microseconds')])
41+
->tag('monolog.channel_logger')
4142

4243
->set('monolog.logger_prototype', Logger::class)
4344
->args([abstract_arg('channel')])
Collapse file

‎src/DependencyInjection/Compiler/AddProcessorsPass.php‎

Copy file name to clipboardExpand all lines: src/DependencyInjection/Compiler/AddProcessorsPass.php
+50-29Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111

1212
namespace Symfony\Bundle\MonologBundle\DependencyInjection\Compiler;
1313

14+
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
1415
use Symfony\Component\DependencyInjection\ChildDefinition;
1516
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17+
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
1618
use Symfony\Component\DependencyInjection\ContainerBuilder;
17-
use Symfony\Component\DependencyInjection\Reference;
1819

1920
/**
2021
* Registers processors in Monolog loggers or handlers.
@@ -25,48 +26,68 @@
2526
*/
2627
class AddProcessorsPass implements CompilerPassInterface
2728
{
29+
use PriorityTaggedServiceTrait;
30+
2831
public function process(ContainerBuilder $container)
2932
{
3033
if (!$container->hasDefinition('monolog.logger')) {
3134
return;
3235
}
3336

37+
$indexedTags = [];
38+
$i = 1;
39+
3440
foreach ($container->findTaggedServiceIds('monolog.processor') as $id => $tags) {
3541
if (array_any($tags, $closure = function (array $tag) { return (bool) $tag; })) {
3642
$tags = array_filter($tags, $closure);
3743
}
3844

39-
foreach ($tags as $tag) {
40-
if (!empty($tag['channel']) && !empty($tag['handler'])) {
41-
throw new \InvalidArgumentException(\sprintf('you cannot specify both the "handler" and "channel" attributes for the "monolog.processor" tag on service "%s".', $id));
42-
}
45+
foreach ($tags as &$tag) {
46+
$indexedTags[$tag['index'] = $i++] = $tag;
47+
}
48+
unset($tag);
49+
$definition = $container->getDefinition($id);
50+
$definition->setTags(array_merge($definition->getTags(), ['monolog.processor' => $tags]));
51+
}
4352

44-
if (!empty($tag['handler'])) {
45-
$definition = $container->findDefinition(\sprintf('monolog.handler.%s', $tag['handler']));
46-
$parentDef = $definition;
47-
while (!$parentDef->getClass() && $parentDef instanceof ChildDefinition) {
48-
$parentDef = $container->findDefinition($parentDef->getParent());
49-
}
50-
$class = $container->getParameterBag()->resolveValue($parentDef->getClass());
51-
if (!method_exists($class, 'pushProcessor')) {
52-
throw new \InvalidArgumentException(\sprintf('The "%s" handler does not accept processors.', $tag['handler']));
53-
}
54-
} elseif (!empty($tag['channel'])) {
55-
if ('app' === $tag['channel']) {
56-
$definition = $container->getDefinition('monolog.logger');
57-
} else {
58-
$definition = $container->getDefinition(\sprintf('monolog.logger.%s', $tag['channel']));
59-
}
60-
} else {
61-
$definition = $container->getDefinition('monolog.logger_prototype');
62-
}
53+
$taggedIteratorArgument = new TaggedIteratorArgument('monolog.processor', 'index', null, true);
54+
// array_reverse is used because ProcessableHandlerTrait::pushProcessor prepends processors to the beginning of the stack
55+
foreach (array_reverse($this->findAndSortTaggedServices($taggedIteratorArgument, $container), true) as $index => $reference) {
56+
$tag = $indexedTags[$index];
6357

64-
if (!empty($tag['method'])) {
65-
$processor = [new Reference($id), $tag['method']];
66-
} else {
67-
// If no method is defined, fallback to use __invoke
68-
$processor = new Reference($id);
58+
if (!empty($tag['channel']) && !empty($tag['handler'])) {
59+
throw new \InvalidArgumentException(\sprintf('You cannot specify both the "handler" and "channel" attributes for the "monolog.processor" tag on service "%s".', $reference));
60+
}
61+
62+
if (!empty($tag['handler'])) {
63+
$parentDef = $container->findDefinition(\sprintf('monolog.handler.%s', $tag['handler']));
64+
$definitions = [$parentDef];
65+
while (!$parentDef->getClass() && $parentDef instanceof ChildDefinition) {
66+
$parentDef = $container->findDefinition($parentDef->getParent());
67+
}
68+
$class = $container->getParameterBag()->resolveValue($parentDef->getClass());
69+
if (!method_exists($class, 'pushProcessor')) {
70+
throw new \InvalidArgumentException(\sprintf('The "%s" handler does not accept processors.', $tag['handler']));
71+
}
72+
} elseif (!empty($tag['channel'])) {
73+
$loggerId = 'app' === $tag['channel'] ? 'monolog.logger' : \sprintf('monolog.logger.%s', $tag['channel']);
74+
$definitions = [$container->getDefinition($loggerId)];
75+
} elseif ($loggerIds = $container->findTaggedServiceIds('monolog.channel_logger')) {
76+
$definitions = [];
77+
foreach ($loggerIds as $loggerId => $tags) {
78+
$definitions[] = $container->getDefinition($loggerId);
6979
}
80+
} else {
81+
$definitions = [$container->getDefinition('monolog.logger_prototype')];
82+
}
83+
84+
if (!empty($tag['method'])) {
85+
$processor = [$reference, $tag['method']];
86+
} else {
87+
// If no method is defined, fallback to use __invoke
88+
$processor = $reference;
89+
}
90+
foreach ($definitions as $definition) {
7091
$definition->addMethodCall('pushProcessor', [$processor]);
7192
}
7293
}
Collapse file

‎src/DependencyInjection/Compiler/LoggerChannelPass.php‎

Copy file name to clipboardExpand all lines: src/DependencyInjection/Compiler/LoggerChannelPass.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ protected function createLogger(string $channel, string $loggerId, ContainerBuil
138138
if (!\in_array($channel, $this->channels)) {
139139
$logger = new ChildDefinition('monolog.logger_prototype');
140140
$logger->replaceArgument(0, $channel);
141+
$logger->addTag('monolog.channel_logger');
141142
$container->setDefinition($loggerId, $logger);
142143
$this->channels[] = $channel;
143144
}
Collapse file

‎tests/DependencyInjection/Compiler/AddProcessorsPassTest.php‎

Copy file name to clipboardExpand all lines: tests/DependencyInjection/Compiler/AddProcessorsPassTest.php
+73-6Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Symfony\Component\DependencyInjection\Definition;
2525
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
2626
use Symfony\Component\DependencyInjection\Reference;
27+
use Symfony\Component\DependencyInjection\TypedReference;
2728

2829
class AddProcessorsPassTest extends TestCase
2930
{
@@ -34,12 +35,40 @@ public function testHandlerProcessors()
3435
$service = $container->getDefinition('monolog.handler.test');
3536
$calls = $service->getMethodCalls();
3637
$this->assertCount(1, $calls);
37-
$this->assertEquals(['pushProcessor', [new Reference('test')]], $calls[0]);
38+
$this->assertEquals(['pushProcessor', [new TypedReference('test', 'TestClass')]], $calls[0]);
3839

3940
$service = $container->getDefinition('handler_test');
4041
$calls = $service->getMethodCalls();
4142
$this->assertCount(1, $calls);
42-
$this->assertEquals(['pushProcessor', [new Reference('test2')]], $calls[0]);
43+
$this->assertEquals(['pushProcessor', [new TypedReference('test2', 'TestClass')]], $calls[0]);
44+
45+
$service = $container->getDefinition('monolog.handler.priority_test');
46+
$calls = $service->getMethodCalls();
47+
$this->assertCount(5, $calls);
48+
$this->assertEquals(['pushProcessor', [new TypedReference('processor-10', 'TestClass')]], $calls[0]);
49+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+10', 'TestClass')]], $calls[1]);
50+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+20', 'TestClass')]], $calls[2]);
51+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+20', 'TestClass')]], $calls[2]);
52+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+25+35', 'TestClass')]], $calls[3]);
53+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+35+25', 'TestClass')]], $calls[4]);
54+
55+
$service = $container->getDefinition('monolog.handler.priority_test_2');
56+
$calls = $service->getMethodCalls();
57+
$this->assertCount(2, $calls);
58+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+35+25', 'TestClass')]], $calls[0]);
59+
$this->assertEquals(['pushProcessor', [new TypedReference('processor+25+35', 'TestClass')]], $calls[1]);
60+
61+
$service = $container->getDefinition('monolog.logger');
62+
$calls = $service->getMethodCalls();
63+
$this->assertCount(2, $calls);
64+
$this->assertEquals(['useMicrosecondTimestamps', ['%monolog.use_microseconds%']], $calls[0]);
65+
$this->assertEquals(['pushProcessor', [new TypedReference('processor_all_channels+0', 'TestClass')]], $calls[1]);
66+
67+
$service = $container->getDefinition('monolog.logger.test');
68+
$calls = $service->getMethodCalls();
69+
$this->assertCount(2, $calls);
70+
$this->assertEquals(['pushProcessor', [new TypedReference('processor_test_channel-25', 'TestClass')]], $calls[0]);
71+
$this->assertEquals(['pushProcessor', [new TypedReference('processor_all_channels+0', 'TestClass')]], $calls[1]);
4372
}
4473

4574
public function testFailureOnHandlerWithoutPushProcessor()
@@ -97,7 +126,7 @@ public static function provideEmptyTagsData(): iterable
97126
{
98127
yield 'with empty tag' => [
99128
[[]],
100-
[['pushProcessor', [new Reference('TestClass')]], ['useMicrosecondTimestamps', ['%monolog.use_microseconds%']]],
129+
[['useMicrosecondTimestamps', ['%monolog.use_microseconds%']], ['pushProcessor', [new Reference('TestClass')]]],
101130
[['pushProcessor', [new Reference('TestClass')]]],
102131
];
103132

@@ -115,7 +144,7 @@ public static function provideEmptyTagsData(): iterable
115144

116145
yield 'with method and no channel' => [
117146
[[], ['method' => 'foo']],
118-
[['pushProcessor', [[new Reference('TestClass'), 'foo']]], ['useMicrosecondTimestamps', ['%monolog.use_microseconds%']]],
147+
[['useMicrosecondTimestamps', ['%monolog.use_microseconds%']], ['pushProcessor', [[new Reference('TestClass'), 'foo']]]],
119148
[['pushProcessor', [[new Reference('TestClass'), 'foo']]]],
120149
];
121150
}
@@ -126,24 +155,62 @@ protected function getContainer()
126155
$loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../../../config'));
127156
$loader->load('monolog.php');
128157

158+
$container->setParameter('monolog.additional_channels', ['test']);
159+
$container->setParameter('monolog.handlers_to_channels', []);
160+
129161
$definition = $container->getDefinition('monolog.logger_prototype');
130162
$container->setParameter('monolog.handler.console.class', ConsoleHandler::class);
131163
$container->setDefinition('monolog.handler.test', new Definition('%monolog.handler.console.class%', [100, false]));
132164
$container->setDefinition('handler_test', new Definition('%monolog.handler.console.class%', [100, false]));
165+
$container->setDefinition('monolog.handler.priority_test', new Definition('%monolog.handler.console.class%', [100, false]));
166+
$container->setDefinition('monolog.handler.priority_test_2', new Definition('%monolog.handler.console.class%', [100, false]));
133167
$container->setAlias('monolog.handler.test2', 'handler_test');
134168
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.test')]);
135169
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.test2')]);
170+
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.priority_test')]);
171+
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.priority_test_2')]);
136172

137-
$service = new Definition('TestClass', ['false', new Reference('logger')]);
173+
$service = new Definition('TestClass');
138174
$service->addTag('monolog.processor', ['handler' => 'test']);
139175
$container->setDefinition('test', $service);
140176

141-
$service = new Definition('TestClass', ['false', new Reference('logger')]);
177+
$service = new Definition('TestClass');
142178
$service->addTag('monolog.processor', ['handler' => 'test2']);
143179
$container->setDefinition('test2', $service);
144180

181+
$service = new Definition('TestClass');
182+
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => 10]);
183+
$container->setDefinition('processor+10', $service);
184+
185+
$service = new Definition('TestClass');
186+
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => -10]);
187+
$container->setDefinition('processor-10', $service);
188+
189+
$service = new Definition('TestClass');
190+
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => 20]);
191+
$container->setDefinition('processor+20', $service);
192+
193+
$service = new Definition('TestClass');
194+
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => 35]);
195+
$service->addTag('monolog.processor', ['handler' => 'priority_test_2', 'priority' => 25]);
196+
$container->setDefinition('processor+35+25', $service);
197+
198+
$service = new Definition('TestClass');
199+
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => 25]);
200+
$service->addTag('monolog.processor', ['handler' => 'priority_test_2', 'priority' => 35]);
201+
$container->setDefinition('processor+25+35', $service);
202+
203+
$service = new Definition('TestClass');
204+
$service->addTag('monolog.processor', ['priority' => 0]);
205+
$container->setDefinition('processor_all_channels+0', $service);
206+
207+
$service = new Definition('TestClass');
208+
$service->addTag('monolog.processor', ['channel' => 'test', 'priority' => -25]);
209+
$container->setDefinition('processor_test_channel-25', $service);
210+
145211
$container->getCompilerPassConfig()->setOptimizationPasses([]);
146212
$container->getCompilerPassConfig()->setRemovingPasses([]);
213+
$container->addCompilerPass(new LoggerChannelPass());
147214
$container->addCompilerPass(new AddProcessorsPass());
148215
$container->compile();
149216

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.