Skip to content

Commit 9e0b5ef

Browse files
[WebProfilerBundle] display profiler url in logs
1 parent cb08480 commit 9e0b5ef

File tree

3 files changed

+212
-0
lines changed

3 files changed

+212
-0
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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\Bundle\WebProfilerBundle\EventListener;
13+
14+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
15+
use Symfony\Component\HttpKernel\Event\ResponseEvent;
16+
use Symfony\Component\HttpKernel\KernelEvents;
17+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
18+
use Psr\Log\LoggerInterface;
19+
20+
/**
21+
* @author Jérémy Romey jeremyFreeAgent <[email protected]>
22+
*/
23+
class ProfilerLinkLogListener implements EventSubscriberInterface
24+
{
25+
public function __construct(
26+
protected ?LoggerInterface $logger = null,
27+
private ?UrlGeneratorInterface $urlGenerator = null,
28+
) {
29+
}
30+
31+
public function onKernelResponse(ResponseEvent $event): void
32+
{
33+
if (null === $this->logger) {
34+
return;
35+
}
36+
if (null === $this->urlGenerator) {
37+
return;
38+
}
39+
40+
$response = $event->getResponse();
41+
$request = $event->getRequest();
42+
43+
if (!$event->isMainRequest()) {
44+
return;
45+
}
46+
47+
if (false === $response->headers->has('X-Debug-Token')) {
48+
return;
49+
}
50+
51+
$this->logger->debug(\sprintf('See profiler at %s', $this->urlGenerator->generate('_profiler', ['token' => $response->headers->get('X-Debug-Token')], UrlGeneratorInterface::ABSOLUTE_URL)));
52+
}
53+
54+
public static function getSubscribedEvents(): array
55+
{
56+
return [
57+
KernelEvents::RESPONSE => ['onKernelResponse', -2048],
58+
];
59+
}
60+
}

src/Symfony/Bundle/WebProfilerBundle/Resources/config/profiler.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Bundle\WebProfilerBundle\Controller\RouterController;
1717
use Symfony\Bundle\WebProfilerBundle\Csp\ContentSecurityPolicyHandler;
1818
use Symfony\Bundle\WebProfilerBundle\Csp\NonceGenerator;
19+
use Symfony\Bundle\WebProfilerBundle\EventListener\ProfilerLinkLogListener;
1920
use Symfony\Bundle\WebProfilerBundle\Profiler\CodeExtension;
2021
use Symfony\Bundle\WebProfilerBundle\Twig\WebProfilerExtension;
2122
use Symfony\Component\ErrorHandler\ErrorRenderer\FileLinkFormatter;
@@ -84,5 +85,14 @@
8485
->set('twig.extension.code', CodeExtension::class)
8586
->args([service('debug.file_link_formatter'), param('kernel.project_dir'), param('kernel.charset')])
8687
->tag('twig.extension')
88+
89+
->set('web_profiler.profiler_link_log_listener', ProfilerLinkLogListener::class)
90+
->args([
91+
service('logger')->nullOnInvalid(),
92+
service('router')->ignoreOnInvalid(),
93+
])
94+
95+
->tag('monolog.logger', ['channel' => 'profiler'])
96+
->tag('kernel.event_subscriber')
8797
;
8898
};
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
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\Bundle\WebProfilerBundle\Tests\EventListener;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bundle\WebProfilerBundle\EventListener\ProfilerLinkLogListener;
16+
use Symfony\Component\HttpFoundation\Request;
17+
use Symfony\Component\HttpFoundation\Response;
18+
use Symfony\Component\HttpKernel\Event\ResponseEvent;
19+
use Symfony\Component\HttpKernel\HttpKernelInterface;
20+
use Symfony\Component\HttpKernel\Kernel;
21+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
22+
use Psr\Log\LoggerInterface;
23+
24+
/**
25+
* @author Jérémy Romey jeremyFreeAgent <[email protected]>
26+
*/
27+
class ProfilerLinkLogListenerTest extends TestCase
28+
{
29+
public function testProfilerLinkLog()
30+
{
31+
$response = new Response('I love Symfony', 200);
32+
$response->headers->set('Location', 'https://example.com/');
33+
$response->headers->set('X-Debug-Token', '04bb3f');
34+
35+
$event = new ResponseEvent($this->createMock(Kernel::class), new Request(), HttpKernelInterface::MAIN_REQUEST, $response);
36+
37+
$logger = $this->createMock(LoggerInterface::class);
38+
$logger
39+
->expects($this->once())
40+
->method('debug')
41+
->with('See profiler at http://mydomain.com/_profiler/04bb3f')
42+
;
43+
44+
$urlGenerator = $this->createMock(UrlGeneratorInterface::class);
45+
$urlGenerator
46+
->expects($this->once())
47+
->method('generate')
48+
->with('_profiler', ['token' => '04bb3f'], UrlGeneratorInterface::ABSOLUTE_URL)
49+
->willReturn('http://mydomain.com/_profiler/04bb3f')
50+
;
51+
52+
$listener = new ProfilerLinkLogListener($logger, $urlGenerator);
53+
$listener->onKernelResponse($event);
54+
}
55+
56+
public function testProfilerLinkLogShouldNotLogWhenNoLogger()
57+
{
58+
$response = new Response('I love Symfony', 200);
59+
$response->headers->set('Location', 'https://example.com/');
60+
$response->headers->set('X-Debug-Token', '04bb3f');
61+
62+
$event = new ResponseEvent($this->createMock(Kernel::class), new Request(), HttpKernelInterface::MAIN_REQUEST, $response);
63+
64+
$logger = null;
65+
66+
$urlGenerator = $this->createMock(UrlGeneratorInterface::class);
67+
$urlGenerator
68+
->expects($this->never())
69+
->method('generate')
70+
;
71+
72+
$listener = new ProfilerLinkLogListener($logger, $urlGenerator);
73+
$listener->onKernelResponse($event);
74+
}
75+
76+
public function testProfilerLinkLogShouldNotLogWhenNoUrlGenerator()
77+
{
78+
$response = new Response('I love Symfony', 200);
79+
$response->headers->set('Location', 'https://example.com/');
80+
$response->headers->set('X-Debug-Token', '04bb3f');
81+
82+
$event = new ResponseEvent($this->createMock(Kernel::class), new Request(), HttpKernelInterface::MAIN_REQUEST, $response);
83+
84+
$logger = $this->createMock(LoggerInterface::class);
85+
$logger
86+
->expects($this->never())
87+
->method('debug')
88+
;
89+
90+
$urlGenerator = null;
91+
92+
$listener = new ProfilerLinkLogListener($logger, $urlGenerator);
93+
$listener->onKernelResponse($event);
94+
}
95+
96+
public function testProfilerLinkLogShouldNotLogWhenNotMainRequest()
97+
{
98+
$response = new Response('I love Symfony', 200);
99+
$response->headers->set('Location', 'https://example.com/');
100+
$response->headers->set('X-Debug-Token', '04bb3f');
101+
102+
$event = new ResponseEvent($this->createMock(Kernel::class), new Request(), HttpKernelInterface::SUB_REQUEST, $response);
103+
104+
$logger = $this->createMock(LoggerInterface::class);
105+
$logger
106+
->expects($this->never())
107+
->method('debug')
108+
;
109+
110+
$urlGenerator = $this->createMock(UrlGeneratorInterface::class);
111+
$urlGenerator
112+
->expects($this->never())
113+
->method('generate')
114+
;
115+
116+
$listener = new ProfilerLinkLogListener($logger, $urlGenerator);
117+
$listener->onKernelResponse($event);
118+
}
119+
120+
public function testProfilerLinkLogShouldNotLogWhenNoToken()
121+
{
122+
$response = new Response('I love Symfony', 200);
123+
$response->headers->set('Location', 'https://example.com/');
124+
125+
$event = new ResponseEvent($this->createMock(Kernel::class), new Request(), HttpKernelInterface::MAIN_REQUEST, $response);
126+
127+
$logger = $this->createMock(LoggerInterface::class);
128+
$logger
129+
->expects($this->never())
130+
->method('debug')
131+
;
132+
133+
$urlGenerator = $this->createMock(UrlGeneratorInterface::class);
134+
$urlGenerator
135+
->expects($this->never())
136+
->method('generate')
137+
;
138+
139+
$listener = new ProfilerLinkLogListener($logger, $urlGenerator);
140+
$listener->onKernelResponse($event);
141+
}
142+
}

0 commit comments

Comments
 (0)