Skip to content

Commit cb5189e

Browse files
committed
Add 404 exclusion via a NotFoundActivationStrategy, fixes #5
To configure use: monolog: handlers: main: type: fingers_crossed action_level: error handler: nested excluded_404s: - ^/foo/
1 parent dfdcc72 commit cb5189e

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed

DependencyInjection/Configuration.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
* - fingers_crossed:
5959
* - handler: the wrapped handler's name
6060
* - [action_level|activation_strategy]: minimum level or service id to activate the handler, defaults to WARNING
61+
* - [excluded_404s]: if set, the strategy will be changed to one that excludes 404s coming from URLs matching any of those patterns
6162
* - [buffer_size]: defaults to 0 (unlimited)
6263
* - [stop_buffering]: bool to disable buffering once the handler has been activated, defaults to true
6364
* - [bubble]: bool, defaults to true
@@ -205,6 +206,10 @@ public function getConfigTreeBuilder()
205206
->scalarNode('action_level')->defaultValue('WARNING')->end() // fingers_crossed
206207
->scalarNode('activation_strategy')->defaultNull()->end() // fingers_crossed
207208
->booleanNode('stop_buffering')->defaultTrue()->end()// fingers_crossed
209+
->arrayNode('excluded_404s') // fingers_crossed
210+
->canBeUnset()
211+
->prototype('scalar')->end()
212+
->end()
208213
->scalarNode('buffer_size')->defaultValue(0)->end() // fingers_crossed and buffer
209214
->scalarNode('handler')->end() // fingers_crossed and buffer
210215
->scalarNode('url')->end() // cube
@@ -391,6 +396,10 @@ public function getConfigTreeBuilder()
391396
->ifTrue(function($v) { return ('fingers_crossed' === $v['type'] || 'buffer' === $v['type']) && 1 !== count($v['handler']); })
392397
->thenInvalid('The handler has to be specified to use a FingersCrossedHandler or BufferHandler')
393398
->end()
399+
->validate()
400+
->ifTrue(function($v) { return 'fingers_crossed' === $v['type'] && !empty($v['excluded_404s']) && !empty($v['activation_strategy']); })
401+
->thenInvalid('You can not use excluded_404s together with a custom activation_strategy in a FingersCrossedHandler')
402+
->end()
394403
->validate()
395404
->ifTrue(function($v) { return 'swift_mailer' === $v['type'] && empty($v['email_prototype']) && (empty($v['from_email']) || empty($v['to_email']) || empty($v['subject'])); })
396405
->thenInvalid('The sender, recipient and subject or an email prototype have to be specified to use a SwiftMailerHandler')

DependencyInjection/MonologExtension.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Config\FileLocator;
1818
use Symfony\Component\DependencyInjection\Definition;
1919
use Symfony\Component\DependencyInjection\Reference;
20+
use Symfony\Component\DependencyInjection\ContainerInterface;
2021
use Symfony\Component\HttpKernel\Kernel;
2122

2223
/**
@@ -192,6 +193,11 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
192193

193194
if (isset($handler['activation_strategy'])) {
194195
$activation = new Reference($handler['activation_strategy']);
196+
} elseif (!empty($handler['excluded_404s'])) {
197+
$activationDef = new Definition('%monolog.activation_strategy.not_found.class%', array($handler['excluded_404s'], $handler['action_level']));
198+
$activationDef->addMethodCall('setRequest', array(new Reference('request', ContainerInterface::NULL_ON_INVALID_REFERENCE, false)));
199+
$container->setDefinition($handlerId.'.not_found_strategy', $activationDef);
200+
$activation = new Reference($handlerId.'.not_found_strategy');
195201
} else {
196202
$activation = $handler['action_level'];
197203
}

NotFoundActivationStrategy.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MonologBundle;
13+
14+
use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
15+
use Symfony\Component\HttpKernel\Exception\HttpException;
16+
use Symfony\Component\HttpFoundation\Request;
17+
18+
/**
19+
* Activation strategy that ignores 404s for certain URLs
20+
*
21+
* Configure with:
22+
*
23+
* monolog:
24+
* handlers:
25+
* main:
26+
* type: fingers_crossed
27+
* action_level: error
28+
* handler: nested
29+
* excluded_404s:
30+
* - ^/foo/
31+
*
32+
* @author Jordi Boggiano <j.boggiano@seld.be>
33+
*/
34+
class NotFoundActivationStrategy extends ErrorLevelActivationStrategy
35+
{
36+
private $blacklist;
37+
private $request;
38+
39+
public function __construct(array $excludedUrls, $actionLevel)
40+
{
41+
parent::__construct($actionLevel);
42+
$this->blacklist = '{('.implode('|', $excludedUrls).')}i';
43+
}
44+
45+
public function isHandlerActivated(array $record)
46+
{
47+
if (parent::isHandlerActivated($record) && $this->request && isset($record['context']['exception']) && $record['context']['exception'] instanceof HttpException && $record['context']['exception']->getStatusCode() == 404) {
48+
return !preg_match($this->blacklist, $this->request->getPathInfo());
49+
}
50+
51+
return false;
52+
}
53+
54+
public function setRequest(Request $req = null)
55+
{
56+
$this->request = $req;
57+
}
58+
}

Resources/config/monolog.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<parameter key="monolog.handler.cube.class">Monolog\Handler\CubeHandler</parameter>
3030
<parameter key="monolog.handler.amqp.class">Monolog\Handler\AmqpHandler</parameter>
3131
<parameter key="monolog.handler.error_log.class">Monolog\Handler\ErrorLogHandler</parameter>
32+
<parameter key="monolog.activation_strategy.not_found.class">Symfony\Bundle\MonologBundle\NotFoundActivationStrategy</parameter>
3233

3334
<parameter key="monolog.handler.fingers_crossed.class">Monolog\Handler\FingersCrossedHandler</parameter>
3435
<parameter key="monolog.handler.fingers_crossed.error_level_activation_strategy.class">Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy</parameter>

0 commit comments

Comments
 (0)