Skip to content

Commit fad28b9

Browse files
RoyHypeMC
authored andcommitted
Add priority field to processor tags
So that the order in which the processors are used by monolog can be determined.
1 parent 06ddd76 commit fad28b9

File tree

2 files changed

+72
-26
lines changed

2 files changed

+72
-26
lines changed

DependencyInjection/Compiler/AddProcessorsPass.php

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,40 +31,65 @@ public function process(ContainerBuilder $container)
3131
return;
3232
}
3333

34+
$processors = [];
35+
3436
foreach ($container->findTaggedServiceIds('monolog.processor') as $id => $tags) {
3537
foreach ($tags as $tag) {
36-
if (!empty($tag['channel']) && !empty($tag['handler'])) {
37-
throw new \InvalidArgumentException(sprintf('you cannot specify both the "handler" and "channel" attributes for the "monolog.processor" tag on service "%s"', $id));
38+
if (!isset($tag['priority'])) {
39+
$tag['priority'] = 0;
3840
}
3941

40-
if (!empty($tag['handler'])) {
41-
$definition = $container->findDefinition(sprintf('monolog.handler.%s', $tag['handler']));
42-
$parentDef = $definition;
43-
while (!$parentDef->getClass() && $parentDef instanceof ChildDefinition) {
44-
$parentDef = $container->findDefinition($parentDef->getParent());
45-
}
46-
$class = $container->getParameterBag()->resolveValue($parentDef->getClass());
47-
if (!method_exists($class, 'pushProcessor')) {
48-
throw new \InvalidArgumentException(sprintf('The "%s" handler does not accept processors', $tag['handler']));
49-
}
50-
} elseif (!empty($tag['channel'])) {
51-
if ('app' === $tag['channel']) {
52-
$definition = $container->getDefinition('monolog.logger');
53-
} else {
54-
$definition = $container->getDefinition(sprintf('monolog.logger.%s', $tag['channel']));
55-
}
56-
} else {
57-
$definition = $container->getDefinition('monolog.logger_prototype');
58-
}
42+
$processors[] = [
43+
'id' => $id,
44+
'tag' => $tag,
45+
];
46+
}
47+
}
48+
49+
// Sort by priority so that higher-prio processors are added last.
50+
// The effect is the monolog will call the higher-prio processors first
51+
usort(
52+
$processors,
53+
function (array $left, array $right) {
54+
return $left['tag']['priority'] - $right['tag']['priority'];
55+
}
56+
);
5957

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

Tests/DependencyInjection/Compiler/AddProcessorsPassTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ public function testHandlerProcessors()
3838
$calls = $service->getMethodCalls();
3939
$this->assertCount(1, $calls);
4040
$this->assertEquals(['pushProcessor', [new Reference('test2')]], $calls[0]);
41+
42+
$service = $container->getDefinition('monolog.handler.priority_test');
43+
$calls = $service->getMethodCalls();
44+
$this->assertCount(3, $calls);
45+
$this->assertEquals(['pushProcessor', [new Reference('processor-10')]], $calls[0]);
46+
$this->assertEquals(['pushProcessor', [new Reference('processor+10')]], $calls[1]);
47+
$this->assertEquals(['pushProcessor', [new Reference('processor+20')]], $calls[2]);
4148
}
4249

4350
public function testFailureOnHandlerWithoutPushProcessor()
@@ -76,9 +83,11 @@ protected function getContainer()
7683
$container->setParameter('monolog.handler.console.class', ConsoleHandler::class);
7784
$container->setDefinition('monolog.handler.test', new Definition('%monolog.handler.console.class%', [100, false]));
7885
$container->setDefinition('handler_test', new Definition('%monolog.handler.console.class%', [100, false]));
86+
$container->setDefinition('monolog.handler.priority_test', new Definition('%monolog.handler.console.class%', [100, false]));
7987
$container->setAlias('monolog.handler.test2', 'handler_test');
8088
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.test')]);
8189
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.test2')]);
90+
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.priority_test')]);
8291

8392
$service = new Definition('TestClass', ['false', new Reference('logger')]);
8493
$service->addTag('monolog.processor', ['handler' => 'test']);
@@ -88,6 +97,18 @@ protected function getContainer()
8897
$service->addTag('monolog.processor', ['handler' => 'test2']);
8998
$container->setDefinition('test2', $service);
9099

100+
$service = new Definition('TestClass', ['false', new Reference('logger')]);
101+
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => 10]);
102+
$container->setDefinition('processor+10', $service);
103+
104+
$service = new Definition('TestClass', ['false', new Reference('logger')]);
105+
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => -10]);
106+
$container->setDefinition('processor-10', $service);
107+
108+
$service = new Definition('TestClass', ['false', new Reference('logger')]);
109+
$service->addTag('monolog.processor', ['handler' => 'priority_test', 'priority' => 20]);
110+
$container->setDefinition('processor+20', $service);
111+
91112
$container->getCompilerPassConfig()->setOptimizationPasses([]);
92113
$container->getCompilerPassConfig()->setRemovingPasses([]);
93114
$container->addCompilerPass(new AddProcessorsPass());

0 commit comments

Comments
 (0)