Skip to content

Commit 7bd4ddc

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 ed0e4a2 commit 7bd4ddc

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
@@ -37,6 +37,13 @@ public function testHandlerProcessors()
3737
$calls = $service->getMethodCalls();
3838
$this->assertCount(1, $calls);
3939
$this->assertEquals(['pushProcessor', [new Reference('test2')]], $calls[0]);
40+
41+
$service = $container->getDefinition('monolog.handler.priority_test');
42+
$calls = $service->getMethodCalls();
43+
$this->assertCount(3, $calls);
44+
$this->assertEquals(['pushProcessor', [new Reference('processor-10')]], $calls[0]);
45+
$this->assertEquals(['pushProcessor', [new Reference('processor+10')]], $calls[1]);
46+
$this->assertEquals(['pushProcessor', [new Reference('processor+20')]], $calls[2]);
4047
}
4148

4249
public function testFailureOnHandlerWithoutPushProcessor()
@@ -75,9 +82,11 @@ protected function getContainer()
7582
$container->setParameter('monolog.handler.console.class', ConsoleHandler::class);
7683
$container->setDefinition('monolog.handler.test', new Definition('%monolog.handler.console.class%', [100, false]));
7784
$container->setDefinition('handler_test', new Definition('%monolog.handler.console.class%', [100, false]));
85+
$container->setDefinition('monolog.handler.priority_test', new Definition('%monolog.handler.console.class%', [100, false]));
7886
$container->setAlias('monolog.handler.test2', 'handler_test');
7987
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.test')]);
8088
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.test2')]);
89+
$definition->addMethodCall('pushHandler', [new Reference('monolog.handler.priority_test')]);
8190

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

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

0 commit comments

Comments
 (0)