Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ee51f74

Browse filesBrowse files
committed
feature #23707 [Monolog Bridge][DX] Add a Monolog activation strategy for ignoring specific HTTP codes (simshaun, fabpot)
This PR was merged into the 4.1-dev branch. Discussion ---------- [Monolog Bridge][DX] Add a Monolog activation strategy for ignoring specific HTTP codes | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #9712 | License | MIT | Doc PR | symfony/symfony-docs#8235 This PR introduces a Monolog activation strategy that makes it easy to ignore specific HTTP codes. e.g. Stopping logs from being flooded with 403s, 404s, and 405s. Relevant Symfony integration PR on symfony/monolog-bundle: symfony/monolog-bundle#221 Commits ------- 6fc1cc3 added some validation c11a8eb Add a Monolog activation strategy for ignoring specific HTTP codes
2 parents c9ebbce + 6fc1cc3 commit ee51f74
Copy full SHA for ee51f74

File tree

2 files changed

+155
-0
lines changed
Filter options

2 files changed

+155
-0
lines changed
+74Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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\Bridge\Monolog\Handler\FingersCrossed;
13+
14+
use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
15+
use Symfony\Component\HttpKernel\Exception\HttpException;
16+
use Symfony\Component\HttpFoundation\RequestStack;
17+
18+
/**
19+
* Activation strategy that ignores certain HTTP codes.
20+
*
21+
* @author Shaun Simmons <shaun@envysphere.com>
22+
*/
23+
class HttpCodeActivationStrategy extends ErrorLevelActivationStrategy
24+
{
25+
private $exclusions;
26+
private $requestStack;
27+
28+
/**
29+
* @param array $exclusions each exclusion must have a "code" and "urls" keys
30+
*/
31+
public function __construct(RequestStack $requestStack, array $exclusions, $actionLevel)
32+
{
33+
foreach ($exclusions as $exclusion) {
34+
if (!array_key_exists('code', $exclusion)) {
35+
throw new \LogicException(sprintf('An exclusion must have a "code" key'));
36+
}
37+
if (!array_key_exists('urls', $exclusion)) {
38+
throw new \LogicException(sprintf('An exclusion must have a "urls" key'));
39+
}
40+
}
41+
42+
parent::__construct($actionLevel);
43+
44+
$this->requestStack = $requestStack;
45+
$this->exclusions = $exclusions;
46+
}
47+
48+
public function isHandlerActivated(array $record)
49+
{
50+
$isActivated = parent::isHandlerActivated($record);
51+
52+
if (
53+
$isActivated
54+
&& isset($record['context']['exception'])
55+
&& $record['context']['exception'] instanceof HttpException
56+
&& ($request = $this->requestStack->getMasterRequest())
57+
) {
58+
foreach ($this->exclusions as $exclusion) {
59+
if ($record['context']['exception']->getStatusCode() !== $exclusion['code']) {
60+
continue;
61+
}
62+
63+
$urlBlacklist = null;
64+
if (count($exclusion['urls'])) {
65+
return !preg_match('{('.implode('|', $exclusion['urls']).')}i', $request->getPathInfo());
66+
}
67+
68+
return false;
69+
}
70+
}
71+
72+
return $isActivated;
73+
}
74+
}
+81Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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\Bridge\Monolog\Tests\Handler\FingersCrossed;
13+
14+
use Monolog\Logger;
15+
use PHPUnit\Framework\TestCase;
16+
use Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy;
17+
use Symfony\Component\HttpFoundation\Request;
18+
use Symfony\Component\HttpFoundation\RequestStack;
19+
use Symfony\Component\HttpKernel\Exception\HttpException;
20+
21+
class HttpCodeActivationStrategyTest extends TestCase
22+
{
23+
/**
24+
* @expectedException \LogicException
25+
*/
26+
public function testExclusionsWithoutCode()
27+
{
28+
new HttpCodeActivationStrategy(new RequestStack(), array(array('urls' => array())), Logger::WARNING);
29+
}
30+
31+
/**
32+
* @expectedException \LogicException
33+
*/
34+
public function testExclusionsWithoutUrls()
35+
{
36+
new HttpCodeActivationStrategy(new RequestStack(), array(array('code' => 404)), Logger::WARNING);
37+
}
38+
39+
/**
40+
* @dataProvider isActivatedProvider
41+
*/
42+
public function testIsActivated($url, $record, $expected)
43+
{
44+
$requestStack = new RequestStack();
45+
$requestStack->push(Request::create($url));
46+
47+
$strategy = new HttpCodeActivationStrategy(
48+
$requestStack,
49+
array(
50+
array('code' => 403, 'urls' => array()),
51+
array('code' => 404, 'urls' => array()),
52+
array('code' => 405, 'urls' => array()),
53+
array('code' => 400, 'urls' => array('^/400/a', '^/400/b')),
54+
),
55+
Logger::WARNING
56+
);
57+
58+
$this->assertEquals($expected, $strategy->isHandlerActivated($record));
59+
}
60+
61+
public function isActivatedProvider()
62+
{
63+
return array(
64+
array('/test', array('level' => Logger::ERROR), true),
65+
array('/400', array('level' => Logger::ERROR, 'context' => $this->getContextException(400)), true),
66+
array('/400/a', array('level' => Logger::ERROR, 'context' => $this->getContextException(400)), false),
67+
array('/400/b', array('level' => Logger::ERROR, 'context' => $this->getContextException(400)), false),
68+
array('/400/c', array('level' => Logger::ERROR, 'context' => $this->getContextException(400)), true),
69+
array('/401', array('level' => Logger::ERROR, 'context' => $this->getContextException(401)), true),
70+
array('/403', array('level' => Logger::ERROR, 'context' => $this->getContextException(403)), false),
71+
array('/404', array('level' => Logger::ERROR, 'context' => $this->getContextException(404)), false),
72+
array('/405', array('level' => Logger::ERROR, 'context' => $this->getContextException(405)), false),
73+
array('/500', array('level' => Logger::ERROR, 'context' => $this->getContextException(500)), true),
74+
);
75+
}
76+
77+
protected function getContextException($code)
78+
{
79+
return array('exception' => new HttpException($code));
80+
}
81+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.