Skip to content

Commit 541e6e5

Browse files
Denis Brumannlyrixx
andcommitted
Allow log level from envvar or parameter
Co-authored-by: Grégoire Pineau <[email protected]>
1 parent 365b6fa commit 541e6e5

File tree

3 files changed

+119
-10
lines changed

3 files changed

+119
-10
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## 3.6.0 (xxxx-xx-xx)
22

3-
* Add support for Symfony Mailer
3+
* Added support for Symfony Mailer
4+
* Added support for setting log levels from parameters or environment variables
45

56
## 3.5.0 (2019-11-13)
67

DependencyInjection/MonologExtension.php

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
2424
use Symfony\Component\DependencyInjection\ContainerBuilder;
2525
use Symfony\Component\DependencyInjection\Definition;
26+
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
2627
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
2728
use Symfony\Component\DependencyInjection\Reference;
2829
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
@@ -41,9 +42,31 @@ class MonologExtension extends Extension
4142

4243
private $swiftMailerHandlers = [];
4344

44-
private function levelToMonologConst($level)
45+
private function levelToMonologConst($level, ContainerBuilder $container)
4546
{
46-
return is_int($level) ? $level : constant('Monolog\Logger::'.strtoupper($level));
47+
if (null === $level || is_numeric($level)) {
48+
return $level;
49+
}
50+
51+
if (defined('Monolog\Logger::'.strtoupper($level))) {
52+
return constant('Monolog\Logger::' . strtoupper($level));
53+
}
54+
55+
if ($container->hasParameter($level)) {
56+
return $this->levelToMonologConst($container->getParameter($level), $container);
57+
}
58+
59+
try {
60+
$logLevel = $container->resolveEnvPlaceholders($level, true);
61+
} catch (ParameterNotFoundException $notFoundException) {
62+
throw new \InvalidArgumentException(sprintf('Could not match "%s" to a log level.', $level));
63+
}
64+
65+
if ($logLevel !== '') {
66+
return $this->levelToMonologConst($logLevel, $container);
67+
}
68+
69+
throw new \InvalidArgumentException(sprintf('Could not match "%s" to a log level.', $level));
4770
}
4871

4972
/**
@@ -169,7 +192,7 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
169192
$handlerClass = $this->getHandlerClassByType($handler['type']);
170193
$definition = new Definition($handlerClass);
171194

172-
$handler['level'] = $this->levelToMonologConst($handler['level']);
195+
$handler['level'] = $this->levelToMonologConst($handler['level'], $container);
173196

174197
if ($handler['include_stacktraces']) {
175198
$definition->setConfigurator(['Symfony\\Bundle\\MonologBundle\\MonologBundle', 'includeStacktraces']);
@@ -383,9 +406,9 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
383406
break;
384407

385408
case 'fingers_crossed':
386-
$handler['action_level'] = $this->levelToMonologConst($handler['action_level']);
409+
$handler['action_level'] = $this->levelToMonologConst($handler['action_level'], $container);
387410
if (null !== $handler['passthru_level']) {
388-
$handler['passthru_level'] = $this->levelToMonologConst($handler['passthru_level']);
411+
$handler['passthru_level'] = $this->levelToMonologConst($handler['passthru_level'], $container);
389412
}
390413
$nestedHandlerId = $this->getHandlerId($handler['handler']);
391414
$this->markNestedHandler($nestedHandlerId);
@@ -429,10 +452,10 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
429452
break;
430453

431454
case 'filter':
432-
$handler['min_level'] = $this->levelToMonologConst($handler['min_level']);
433-
$handler['max_level'] = $this->levelToMonologConst($handler['max_level']);
455+
$handler['min_level'] = $this->levelToMonologConst($handler['min_level'], $container);
456+
$handler['max_level'] = $this->levelToMonologConst($handler['max_level'], $container);
434457
foreach (array_keys($handler['accepted_levels']) as $k) {
435-
$handler['accepted_levels'][$k] = $this->levelToMonologConst($handler['accepted_levels'][$k]);
458+
$handler['accepted_levels'][$k] = $this->levelToMonologConst($handler['accepted_levels'][$k], $container);
436459
}
437460

438461
$nestedHandlerId = $this->getHandlerId($handler['handler']);

Tests/DependencyInjection/MonologExtensionTest.php

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass;
1919
use Symfony\Component\DependencyInjection\ContainerBuilder;
2020
use Symfony\Component\DependencyInjection\Definition;
21+
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
2122
use Symfony\Component\DependencyInjection\Reference;
2223
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
2324
use Symfony\Component\HttpFoundation\RequestStack;
@@ -611,10 +612,94 @@ public function v1AddedDataProvider()
611612
];
612613
}
613614

615+
public function testLogLevelfromInvalidparameterThrowsException()
616+
{
617+
$container = new ContainerBuilder();
618+
$loader = new MonologExtension();
619+
$config = [['handlers' => ['main' => ['type' => 'stream', 'level' => '%some_param%']]]];
614620

615-
protected function getContainer(array $config = [], array $thirdPartyDefinitions = [])
621+
$this->expectException(InvalidArgumentException::class);
622+
$this->expectExceptionMessage('Could not match "%some_param%" to a log level.');
623+
624+
$loader->load($config, $container);
625+
}
626+
627+
/**
628+
* @dataProvider provideLoglevelParameterConfig
629+
*/
630+
public function testLogLevelfromParameter(array $parameters, array $config, $expectedClass, array $expectedArgs)
616631
{
617632
$container = new ContainerBuilder();
633+
foreach ($parameters as $name => $value) {
634+
$container->setParameter($name, $value);
635+
}
636+
$loader = new MonologExtension();
637+
$config = [['handlers' => ['main' => $config]]];
638+
$loader->load($config, $container);
639+
640+
$definition = $container->getDefinition('monolog.handler.main');
641+
$this->assertDICDefinitionClass($definition, $expectedClass);
642+
$this->assertDICConstructorArguments($definition, $expectedArgs);
643+
}
644+
645+
public function provideLoglevelParameterConfig()
646+
{
647+
return [
648+
'browser console with parameter level' => [
649+
['%log_level%' => 'info'],
650+
['type' => 'browser_console', 'level' => '%log_level%'],
651+
'Monolog\Handler\BrowserConsoleHandler',
652+
[200, true]
653+
],
654+
'browser console with envvar level' => [
655+
['%env(LOG_LEVEL)%' => 'info'],
656+
['type' => 'browser_console', 'level' => '%env(LOG_LEVEL)%'],
657+
'Monolog\Handler\BrowserConsoleHandler',
658+
[200, true]
659+
],
660+
'stream with envvar level null or "~" (in yaml config)' => [
661+
['%env(LOG_LEVEL)%' => null],
662+
['type' => 'stream', 'level' => '%env(LOG_LEVEL)%'],
663+
'Monolog\Handler\StreamHandler',
664+
[
665+
'%kernel.logs_dir%/%kernel.environment%.log',
666+
null,
667+
true,
668+
null,
669+
false,
670+
]
671+
],
672+
'stream with envvar level' => [
673+
['%env(LOG_LEVEL)%' => '400'],
674+
['type' => 'stream', 'level' => '%env(LOG_LEVEL)%'],
675+
'Monolog\Handler\StreamHandler',
676+
[
677+
'%kernel.logs_dir%/%kernel.environment%.log',
678+
400,
679+
true,
680+
null,
681+
false,
682+
]
683+
],
684+
'stream with envvar and fallback parameter' => [
685+
['%env(LOG_LEVEL)%' => '500', '%log_level%' => '%env(LOG_LEVEL)%'],
686+
['type' => 'stream', 'level' => '%log_level%'],
687+
'Monolog\Handler\StreamHandler',
688+
[
689+
'%kernel.logs_dir%/%kernel.environment%.log',
690+
500,
691+
true,
692+
null,
693+
false,
694+
]
695+
],
696+
];
697+
}
698+
699+
700+
protected function getContainer(array $config = [], array $thirdPartyDefinitions = [])
701+
{
702+
$container = new ContainerBuilder(new EnvPlaceholderParameterBag());
618703
foreach ($thirdPartyDefinitions as $id => $definition) {
619704
$container->setDefinition($id, $definition);
620705
}

0 commit comments

Comments
 (0)