Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ee51f74

Browse 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

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed
Lines 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 <[email protected]>
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 <[email protected]>
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+
}
Lines 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 <[email protected]>
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)