diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index bad48b84..79b902e5 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -75,6 +75,13 @@
* - [stop_buffering]: bool to disable buffering once the handler has been activated, defaults to true
* - [bubble]: bool, defaults to true
*
+ * - filter:
+ * - handler: the wrapped handler's name
+ * - [accepted_levels]: list of levels to accept
+ * - [min_level]: minimum level to accept (only used if accepted_levels not specified)
+ * - [max_level]: maximum level to accept (only used if accepted_levels not specified)
+ * - [bubble]: bool, defaults to true
+ *
* - buffer:
* - handler: the wrapped handler's name
* - [buffer_size]: defaults to 0 (unlimited)
@@ -219,6 +226,7 @@ public function getConfigTreeBuilder()
->fixXmlConfig('member')
->fixXmlConfig('excluded_404')
->fixXmlConfig('tag')
+ ->fixXmlConfig('accepted_level')
->canBeUnset()
->children()
->scalarNode('type')
@@ -245,6 +253,12 @@ public function getConfigTreeBuilder()
->canBeUnset()
->prototype('scalar')->end()
->end()
+ ->arrayNode('accepted_levels') // filter
+ ->canBeUnset()
+ ->prototype('scalar')->end()
+ ->end()
+ ->scalarNode('min_level')->defaultValue('DEBUG')->end() // filter
+ ->scalarNode('max_level')->defaultValue('EMERGENCY')->end() //filter
->scalarNode('buffer_size')->defaultValue(0)->end() // fingers_crossed and buffer
->scalarNode('handler')->end() // fingers_crossed and buffer
->scalarNode('url')->end() // cube
@@ -475,13 +489,21 @@ public function getConfigTreeBuilder()
->thenInvalid('Service handlers can not have a formatter configured in the bundle, you must reconfigure the service itself instead')
->end()
->validate()
- ->ifTrue(function($v) { return ('fingers_crossed' === $v['type'] || 'buffer' === $v['type']) && 1 !== count($v['handler']); })
- ->thenInvalid('The handler has to be specified to use a FingersCrossedHandler or BufferHandler')
+ ->ifTrue(function($v) { return ('fingers_crossed' === $v['type'] || 'buffer' === $v['type'] || 'filter' === $v['type']) && 1 !== count($v['handler']); })
+ ->thenInvalid('The handler has to be specified to use a FingersCrossedHandler or BufferHandler or FilterHandler')
->end()
->validate()
->ifTrue(function($v) { return 'fingers_crossed' === $v['type'] && !empty($v['excluded_404s']) && !empty($v['activation_strategy']); })
->thenInvalid('You can not use excluded_404s together with a custom activation_strategy in a FingersCrossedHandler')
->end()
+ ->validate()
+ ->ifTrue(function($v) { return 'filter' === $v['type'] && "DEBUG" !== $v['min_level'] && !empty($v['accepted_levels']); })
+ ->thenInvalid('You can not use min_level together with accepted_levels in a FilterHandler')
+ ->end()
+ ->validate()
+ ->ifTrue(function($v) { return 'filter' === $v['type'] && "EMERGENCY" !== $v['max_level'] && !empty($v['accepted_levels']); })
+ ->thenInvalid('You can not use max_level together with accepted_levels in a FilterHandler')
+ ->end()
->validate()
->ifTrue(function($v) { return 'swift_mailer' === $v['type'] && empty($v['email_prototype']) && (empty($v['from_email']) || empty($v['to_email']) || empty($v['subject'])); })
->thenInvalid('The sender, recipient and subject or an email prototype have to be specified to use a SwiftMailerHandler')
diff --git a/DependencyInjection/MonologExtension.php b/DependencyInjection/MonologExtension.php
index 31251380..00762eb5 100644
--- a/DependencyInjection/MonologExtension.php
+++ b/DependencyInjection/MonologExtension.php
@@ -31,6 +31,11 @@ class MonologExtension extends Extension
private $swiftMailerHandlers = array();
+ private function levelToMonologConst($level)
+ {
+ return is_int($level) ? $level : constant('Monolog\Logger::'.strtoupper($level));
+ }
+
/**
* Loads the Monolog configuration.
*
@@ -85,6 +90,7 @@ public function load(array $configs, ContainerBuilder $container)
'Monolog\\Handler\\AbstractProcessingHandler',
'Monolog\\Handler\\StreamHandler',
'Monolog\\Handler\\FingersCrossedHandler',
+ 'Monolog\\Handler\\FilterHandler',
'Monolog\\Handler\\TestHandler',
'Monolog\\Logger',
'Symfony\\Bridge\\Monolog\\Logger',
@@ -116,7 +122,7 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
{
$handlerId = $this->getHandlerId($name);
$definition = new Definition(sprintf('%%monolog.handler.%s.class%%', $handler['type']));
- $handler['level'] = is_int($handler['level']) ? $handler['level'] : constant('Monolog\Logger::'.strtoupper($handler['level']));
+ $handler['level'] = $this->levelToMonologConst($handler['level']);
switch ($handler['type']) {
case 'service':
@@ -240,7 +246,7 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
break;
case 'fingers_crossed':
- $handler['action_level'] = is_int($handler['action_level']) ? $handler['action_level'] : constant('Monolog\Logger::'.strtoupper($handler['action_level']));
+ $handler['action_level'] = $this->levelToMonologConst($handler['action_level']);
$nestedHandlerId = $this->getHandlerId($handler['handler']);
$this->nestedHandlers[] = $nestedHandlerId;
@@ -264,6 +270,25 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
));
break;
+ case 'filter':
+ $handler['min_level'] = $this->levelToMonologConst($handler['min_level']);
+ $handler['max_level'] = $this->levelToMonologConst($handler['max_level']);
+ foreach (array_keys($handler['accepted_levels']) as $k) {
+ $handler['accepted_levels'][$k] = $this->levelToMonologConst($handler['accepted_levels'][$k]);
+ }
+
+ $nestedHandlerId = $this->getHandlerId($handler['handler']);
+ $this->nestedHandlers[] = $nestedHandlerId;
+ $minLevelOrList = !empty($handler['accepted_levels']) ? $handler['accepted_levels'] : $handler['min_level'];
+
+ $definition->setArguments(array(
+ new Reference($nestedHandlerId),
+ $minLevelOrList,
+ $handler['max_level'],
+ $handler['bubble']
+ ));
+ break;
+
case 'buffer':
$nestedHandlerId = $this->getHandlerId($handler['handler']);
$this->nestedHandlers[] = $nestedHandlerId;
diff --git a/Resources/config/monolog.xml b/Resources/config/monolog.xml
index a672cbb0..7f213821 100644
--- a/Resources/config/monolog.xml
+++ b/Resources/config/monolog.xml
@@ -37,6 +37,7 @@
Monolog\Handler\FingersCrossedHandler
Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy
+ Monolog\Handler\FilterHandler
Monolog\Handler\MongoDBHandler
MongoClient
diff --git a/Resources/config/schema/monolog-1.0.xsd b/Resources/config/schema/monolog-1.0.xsd
index 73a47156..c177919c 100644
--- a/Resources/config/schema/monolog-1.0.xsd
+++ b/Resources/config/schema/monolog-1.0.xsd
@@ -22,6 +22,7 @@
+
@@ -35,6 +36,8 @@
+
+
diff --git a/Tests/DependencyInjection/FixtureMonologExtensionTest.php b/Tests/DependencyInjection/FixtureMonologExtensionTest.php
index 96c24218..9fc1ee5d 100644
--- a/Tests/DependencyInjection/FixtureMonologExtensionTest.php
+++ b/Tests/DependencyInjection/FixtureMonologExtensionTest.php
@@ -28,9 +28,10 @@ public function testLoadWithSeveralHandlers()
$this->assertTrue($container->hasDefinition('monolog.handler.nested'));
$logger = $container->getDefinition('monolog.logger');
- $this->assertCount(2, $logger->getMethodCalls());
- $this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom')));
- $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.main')));
+ $this->assertCount(3, $logger->getMethodCalls());
+ $this->assertDICDefinitionMethodCallAt(2, $logger, 'pushHandler', array(new Reference('monolog.handler.custom')));
+ $this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.main')));
+ $this->assertDICDefinitionMethodCallAt(0, $logger, 'pushHandler', array(new Reference('monolog.handler.filtered')));
$handler = $container->getDefinition('monolog.handler.custom');
$this->assertDICDefinitionClass($handler, '%monolog.handler.stream.class%');
@@ -39,6 +40,10 @@ public function testLoadWithSeveralHandlers()
$handler = $container->getDefinition('monolog.handler.main');
$this->assertDICDefinitionClass($handler, '%monolog.handler.fingers_crossed.class%');
$this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested'), \Monolog\Logger::ERROR, 0, true, true));
+
+ $handler = $container->getDefinition('monolog.handler.filtered');
+ $this->assertDICDefinitionClass($handler, '%monolog.handler.filter.class%');
+ $this->assertDICConstructorArguments($handler, array(new Reference('monolog.handler.nested2'), array(\Monolog\Logger::WARNING, \Monolog\Logger::ERROR), \Monolog\Logger::EMERGENCY, true));
}
public function testLoadWithOverwriting()
diff --git a/Tests/DependencyInjection/Fixtures/xml/multiple_handlers.xml b/Tests/DependencyInjection/Fixtures/xml/multiple_handlers.xml
index fe98c55c..8abe0875 100644
--- a/Tests/DependencyInjection/Fixtures/xml/multiple_handlers.xml
+++ b/Tests/DependencyInjection/Fixtures/xml/multiple_handlers.xml
@@ -10,5 +10,10 @@
+
+ WARNING
+ ERROR
+
+
diff --git a/Tests/DependencyInjection/Fixtures/yml/multiple_handlers.yml b/Tests/DependencyInjection/Fixtures/yml/multiple_handlers.yml
index 14af13e3..32f69c70 100644
--- a/Tests/DependencyInjection/Fixtures/yml/multiple_handlers.yml
+++ b/Tests/DependencyInjection/Fixtures/yml/multiple_handlers.yml
@@ -11,3 +11,9 @@ monolog:
handler: nested
nested:
type: stream
+ filtered:
+ type: filter
+ accepted_levels: [WARNING, ERROR]
+ handler: nested2
+ nested2:
+ type: stream
diff --git a/Tests/DependencyInjection/MonologExtensionTest.php b/Tests/DependencyInjection/MonologExtensionTest.php
index 2e8fe052..9dac6d69 100644
--- a/Tests/DependencyInjection/MonologExtensionTest.php
+++ b/Tests/DependencyInjection/MonologExtensionTest.php
@@ -70,6 +70,17 @@ public function testExceptionWhenUsingFingerscrossedWithoutHandler()
$loader->load(array(array('handlers' => array('main' => array('type' => 'fingers_crossed')))), $container);
}
+ /**
+ * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+ */
+ public function testExceptionWhenUsingFilterWithoutHandler()
+ {
+ $container = new ContainerBuilder();
+ $loader = new MonologExtension();
+
+ $loader->load(array(array('handlers' => array('main' => array('type' => 'filter')))), $container);
+ }
+
/**
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
*/
diff --git a/composer.json b/composer.json
index 23ce3fde..b647232a 100644
--- a/composer.json
+++ b/composer.json
@@ -21,7 +21,7 @@
"symfony/dependency-injection": "~2.3",
"symfony/config": "~2.3",
"symfony/http-kernel": "~2.3",
- "monolog/monolog": "~1.6"
+ "monolog/monolog": "~1.8"
},
"require-dev": {
"symfony/yaml": "~2.3",