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 62ee940

Browse filesBrowse files
trakosPiotr Stankowski
authored and
Piotr Stankowski
committed
[MonologBridge] Add ConsoleCommandProcessor and RouteProcessor
1 parent bc45a0e commit 62ee940
Copy full SHA for 62ee940

File tree

5 files changed

+302
-0
lines changed
Filter options

5 files changed

+302
-0
lines changed

‎src/Symfony/Bridge/Monolog/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Monolog/CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ CHANGELOG
55
-----
66

77
* added `ProcessorInterface`: an optional interface to allow autoconfiguration of Monolog processors
8+
* added `ConsoleCommandProcessor`: monolog processor that adds command name and arguments
9+
* added `RouteProcessor`: monolog processor that adds route name, controller::action and route params
810

911
4.1.0
1012
-----
+63Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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\Processor;
13+
14+
use Symfony\Component\Console\ConsoleEvents;
15+
use Symfony\Component\Console\Event\ConsoleEvent;
16+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
17+
18+
/**
19+
* Adds the current console command information to the log entry.
20+
*
21+
* @author Piotr Stankowski <git@trakos.pl>
22+
*/
23+
class ConsoleCommandProcessor implements ProcessorInterface, EventSubscriberInterface
24+
{
25+
private $commandData;
26+
private $includeArguments;
27+
private $includeOptions;
28+
29+
public function __construct(bool $includeArguments = true, bool $includeOptions = false)
30+
{
31+
$this->includeArguments = $includeArguments;
32+
$this->includeOptions = $includeOptions;
33+
}
34+
35+
public static function getSubscribedEvents()
36+
{
37+
return array(
38+
ConsoleEvents::COMMAND => array('onCommand', 1),
39+
);
40+
}
41+
42+
public function __invoke(array $records)
43+
{
44+
if (null !== $this->commandData && !isset($records['extra']['command'])) {
45+
$records['extra']['command'] = $this->commandData;
46+
}
47+
48+
return $records;
49+
}
50+
51+
public function onCommand(ConsoleEvent $event)
52+
{
53+
$this->commandData = array(
54+
'name' => $event->getCommand()->getName(),
55+
);
56+
if ($this->includeArguments) {
57+
$this->commandData['arguments'] = $event->getInput()->getArguments();
58+
}
59+
if ($this->includeOptions) {
60+
$this->commandData['options'] = $event->getInput()->getOptions();
61+
}
62+
}
63+
}
+66Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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\Processor;
13+
14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
16+
use Symfony\Component\HttpKernel\KernelEvents;
17+
18+
/**
19+
* Adds the current route information to the log entry.
20+
*
21+
* @author Piotr Stankowski <git@trakos.pl>
22+
*/
23+
class RouteProcessor implements ProcessorInterface, EventSubscriberInterface
24+
{
25+
private $routeData;
26+
private $includeParams;
27+
28+
public function __construct(bool $includeParams = true)
29+
{
30+
$this->includeParams = $includeParams;
31+
}
32+
33+
public function __invoke(array $records)
34+
{
35+
if (null !== $this->routeData && !isset($records['extra']['route'])) {
36+
$records['extra']['route'] = $this->routeData;
37+
}
38+
39+
return $records;
40+
}
41+
42+
public function onKernelRequest(GetResponseEvent $event)
43+
{
44+
$request = $event->getRequest();
45+
46+
if (!$request->attributes->has('_controller')) {
47+
return;
48+
}
49+
50+
$this->routeData = array(
51+
'controller' => $request->attributes->get('_controller'),
52+
'route' => $request->attributes->get('_route'),
53+
);
54+
55+
if ($this->includeParams) {
56+
$this->routeData['route_params'] = $request->attributes->get('_route_params');
57+
}
58+
}
59+
60+
public static function getSubscribedEvents()
61+
{
62+
return array(
63+
KernelEvents::REQUEST => array('onKernelRequest', 1),
64+
);
65+
}
66+
}
+75Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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\Processor;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\Monolog\Processor\ConsoleCommandProcessor;
16+
use Symfony\Component\Console\Command\Command;
17+
use Symfony\Component\Console\Event\ConsoleEvent;
18+
use Symfony\Component\Console\Input\InputInterface;
19+
20+
class ConsoleCommandProcessorTest extends TestCase
21+
{
22+
const TEST_ARGUMENTS = array('test' => 'argument');
23+
const TEST_OPTIONS = array('test' => 'option');
24+
const TEST_NAME = 'some:test';
25+
26+
public function testProcessor()
27+
{
28+
$processor = new ConsoleCommandProcessor();
29+
$processor->onCommand($this->getConsoleEvent());
30+
31+
$record = $processor(array('extra' => array()));
32+
33+
$this->assertArrayHasKey('command', $record['extra']);
34+
$this->assertEquals(
35+
array('name' => self::TEST_NAME, 'arguments' => self::TEST_ARGUMENTS),
36+
$record['extra']['command']
37+
);
38+
}
39+
40+
public function testProcessorWithOptions()
41+
{
42+
$processor = new ConsoleCommandProcessor(true, true);
43+
$processor->onCommand($this->getConsoleEvent());
44+
45+
$record = $processor(array('extra' => array()));
46+
47+
$this->assertArrayHasKey('command', $record['extra']);
48+
$this->assertEquals(
49+
array('name' => self::TEST_NAME, 'arguments' => self::TEST_ARGUMENTS, 'options' => self::TEST_OPTIONS),
50+
$record['extra']['command']
51+
);
52+
}
53+
54+
public function testProcessorDoesNothingWhenNotInConsole()
55+
{
56+
$processor = new ConsoleCommandProcessor(true, true);
57+
58+
$record = $processor(array('extra' => array()));
59+
$this->assertEquals(array('extra' => array()), $record);
60+
}
61+
62+
private function getConsoleEvent(): ConsoleEvent
63+
{
64+
$input = $this->getMockBuilder(InputInterface::class)->getMock();
65+
$input->method('getArguments')->willReturn(self::TEST_ARGUMENTS);
66+
$input->method('getOptions')->willReturn(self::TEST_OPTIONS);
67+
$command = $this->getMockBuilder(Command::class)->disableOriginalConstructor()->getMock();
68+
$command->method('getName')->willReturn(self::TEST_NAME);
69+
$consoleEvent = $this->getMockBuilder(ConsoleEvent::class)->disableOriginalConstructor()->getMock();
70+
$consoleEvent->method('getCommand')->willReturn($command);
71+
$consoleEvent->method('getInput')->willReturn($input);
72+
73+
return $consoleEvent;
74+
}
75+
}
+96Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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\Processor;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\Monolog\Processor\RouteProcessor;
16+
use Symfony\Component\HttpFoundation\ParameterBag;
17+
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
18+
19+
class RouteProcessorTest extends TestCase
20+
{
21+
const TEST_CONTROLLER = 'App\Controller\SomeController::someMethod';
22+
const TEST_ROUTE = 'someRouteName';
23+
const TEST_PARAMS = array('param1' => 'value1');
24+
25+
public function testProcessor()
26+
{
27+
$processor = new RouteProcessor();
28+
$processor->onKernelRequest($this->getFilledRequestEvent());
29+
30+
$record = $processor(array('extra' => array()));
31+
32+
$this->assertArrayHasKey('route', $record['extra']);
33+
$this->assertEquals(
34+
array('controller' => self::TEST_CONTROLLER, 'route' => self::TEST_ROUTE, 'route_params' => self::TEST_PARAMS),
35+
$record['extra']['route']
36+
);
37+
}
38+
39+
public function testProcessorWithoutParams()
40+
{
41+
$processor = new RouteProcessor(false);
42+
$processor->onKernelRequest($this->getFilledRequestEvent());
43+
44+
$record = $processor(array('extra' => array()));
45+
46+
$this->assertArrayHasKey('route', $record['extra']);
47+
$this->assertEquals(
48+
array('controller' => self::TEST_CONTROLLER, 'route' => self::TEST_ROUTE),
49+
$record['extra']['route']
50+
);
51+
}
52+
53+
public function testProcessorWithEmptyRequest()
54+
{
55+
$processor = new RouteProcessor();
56+
$processor->onKernelRequest($this->getEmptyRequestEvent());
57+
58+
$record = $processor(array('extra' => array()));
59+
$this->assertEquals(array('extra' => array()), $record);
60+
}
61+
62+
public function testProcessorDoesNothingWhenNoRequest()
63+
{
64+
$processor = new RouteProcessor();
65+
66+
$record = $processor(array('extra' => array()));
67+
$this->assertEquals(array('extra' => array()), $record);
68+
}
69+
70+
private function getRequestEvent(array $attributes): GetResponseEvent
71+
{
72+
$request = new \stdClass();
73+
$request->attributes = new ParameterBag($attributes);
74+
75+
$event = $this->getMockBuilder(GetResponseEvent::class)->disableOriginalConstructor()->getMock();
76+
$event->method('getRequest')->willReturn($request);
77+
78+
return $event;
79+
}
80+
81+
private function getEmptyRequestEvent(): GetResponseEvent
82+
{
83+
return $this->getRequestEvent(array());
84+
}
85+
86+
private function getFilledRequestEvent(): GetResponseEvent
87+
{
88+
return $this->getRequestEvent(
89+
array(
90+
'_controller' => self::TEST_CONTROLLER,
91+
'_route' => self::TEST_ROUTE,
92+
'_route_params' => self::TEST_PARAMS,
93+
)
94+
);
95+
}
96+
}

0 commit comments

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