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

Skip to content

Commit 669f6b2

Browse files
trakosfabpot
authored andcommitted
[MonologBridge] Add monolog processors adding route and command info
1 parent 3778585 commit 669f6b2

File tree

5 files changed

+398
-0
lines changed

5 files changed

+398
-0
lines changed

src/Symfony/Bridge/Monolog/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
4.3.0
5+
-----
6+
7+
* added `ConsoleCommandProcessor`: monolog processor that adds command name and arguments
8+
* added `RouteProcessor`: monolog processor that adds route name, controller::action and route params
9+
410
4.2.0
511
-----
612

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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\Processor;
13+
14+
use Symfony\Component\Console\ConsoleEvents;
15+
use Symfony\Component\Console\Event\ConsoleEvent;
16+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
17+
use Symfony\Contracts\Service\ResetInterface;
18+
19+
/**
20+
* Adds the current console command information to the log entry.
21+
*
22+
* @author Piotr Stankowski <[email protected]>
23+
*/
24+
class ConsoleCommandProcessor implements EventSubscriberInterface, ResetInterface
25+
{
26+
private $commandData;
27+
private $includeArguments;
28+
private $includeOptions;
29+
30+
public function __construct(bool $includeArguments = true, bool $includeOptions = false)
31+
{
32+
$this->includeArguments = $includeArguments;
33+
$this->includeOptions = $includeOptions;
34+
}
35+
36+
public function __invoke(array $records)
37+
{
38+
if (null !== $this->commandData && !isset($records['extra']['command'])) {
39+
$records['extra']['command'] = $this->commandData;
40+
}
41+
42+
return $records;
43+
}
44+
45+
public function reset()
46+
{
47+
$this->commandData = null;
48+
}
49+
50+
public function addCommandData(ConsoleEvent $event)
51+
{
52+
$this->commandData = array(
53+
'name' => $event->getCommand()->getName(),
54+
);
55+
if ($this->includeArguments) {
56+
$this->commandData['arguments'] = $event->getInput()->getArguments();
57+
}
58+
if ($this->includeOptions) {
59+
$this->commandData['options'] = $event->getInput()->getOptions();
60+
}
61+
}
62+
63+
public static function getSubscribedEvents()
64+
{
65+
return array(
66+
ConsoleEvents::COMMAND => array('addCommandData', 1),
67+
);
68+
}
69+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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\Processor;
13+
14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
16+
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
17+
use Symfony\Component\HttpKernel\KernelEvents;
18+
use Symfony\Contracts\Service\ResetInterface;
19+
20+
/**
21+
* Adds the current route information to the log entry.
22+
*
23+
* @author Piotr Stankowski <[email protected]>
24+
*/
25+
class RouteProcessor implements EventSubscriberInterface, ResetInterface
26+
{
27+
private $routeData;
28+
private $includeParams;
29+
30+
public function __construct(bool $includeParams = true)
31+
{
32+
$this->includeParams = $includeParams;
33+
$this->reset();
34+
}
35+
36+
public function __invoke(array $records)
37+
{
38+
if ($this->routeData && !isset($records['extra']['requests'])) {
39+
$records['extra']['requests'] = array_values($this->routeData);
40+
}
41+
42+
return $records;
43+
}
44+
45+
public function reset()
46+
{
47+
$this->routeData = array();
48+
}
49+
50+
public function addRouteData(GetResponseEvent $event)
51+
{
52+
if ($event->isMasterRequest()) {
53+
$this->reset();
54+
}
55+
56+
$request = $event->getRequest();
57+
if (!$request->attributes->has('_controller')) {
58+
return;
59+
}
60+
61+
$currentRequestData = array(
62+
'controller' => $request->attributes->get('_controller'),
63+
'route' => $request->attributes->get('_route'),
64+
);
65+
66+
if ($this->includeParams) {
67+
$currentRequestData['route_params'] = $request->attributes->get('_route_params');
68+
}
69+
70+
$this->routeData[spl_object_id($request)] = $currentRequestData;
71+
}
72+
73+
public function removeRouteData(FinishRequestEvent $event)
74+
{
75+
$requestId = spl_object_id($event->getRequest());
76+
unset($this->routeData[$requestId]);
77+
}
78+
79+
public static function getSubscribedEvents()
80+
{
81+
return array(
82+
KernelEvents::REQUEST => array('addRouteData', 1),
83+
KernelEvents::FINISH_REQUEST => array('removeRouteData', 1),
84+
);
85+
}
86+
}
Lines 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 <[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\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+
private const TEST_ARGUMENTS = array('test' => 'argument');
23+
private const TEST_OPTIONS = array('test' => 'option');
24+
private const TEST_NAME = 'some:test';
25+
26+
public function testProcessor()
27+
{
28+
$processor = new ConsoleCommandProcessor();
29+
$processor->addCommandData($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->addCommandData($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+
}

0 commit comments

Comments
 (0)