Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commit5dbaef8

Browse files
committed
Add session profiling
1 parent6aecad7 commit5dbaef8

File tree

10 files changed

+198
-6
lines changed

10 files changed

+198
-6
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,16 @@
2929
->tag('data_collector', ['template' =>'@WebProfiler/Collector/config.html.twig','id' =>'config','priority' => -255])
3030

3131
->set('data_collector.request', RequestDataCollector::class)
32+
->args([
33+
service('request_stack')->ignoreOnInvalid(),
34+
])
3235
->tag('kernel.event_subscriber')
3336
->tag('data_collector', ['template' =>'@WebProfiler/Collector/request.html.twig','id' =>'request','priority' =>335])
3437

38+
->set('data_collector.request.session_collector', \Closure::class)
39+
->factory([\Closure::class,'fromCallable'])
40+
->args([[service('data_collector.request'),'collectSessionUsage']])
41+
3542
->set('data_collector.ajax', AjaxDataCollector::class)
3643
->tag('data_collector', ['template' =>'@WebProfiler/Collector/ajax.html.twig','id' =>'ajax','priority' =>315])
3744

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/session.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
'session' =>service('session')->ignoreOnInvalid(),
9898
'initialized_session' =>service('session')->ignoreOnUninitialized(),
9999
'logger' =>service('logger')->ignoreOnInvalid(),
100+
'session_collector' =>service('data_collector.request.session_collector')->ignoreOnInvalid(),
100101
]),
101102
param('kernel.debug'),
102103
])

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ public function testNullSessionHandler()
504504
$this->assertNull($container->getDefinition('session.storage.native')->getArgument(1));
505505
$this->assertNull($container->getDefinition('session.storage.php_bridge')->getArgument(0));
506506

507-
$expected = ['session','initialized_session','logger'];
507+
$expected = ['session','initialized_session','logger','session_collector'];
508508
$this->assertEquals($expected,array_keys($container->getDefinition('session_listener')->getArgument(0)->getValues()));
509509
}
510510

@@ -1312,7 +1312,7 @@ public function testSessionCookieSecureAuto()
13121312
{
13131313
$container =$this->createContainerFromFile('session_cookie_secure_auto');
13141314

1315-
$expected = ['session','initialized_session','logger','session_storage','request_stack'];
1315+
$expected = ['session','initialized_session','logger','session_collector','session_storage','request_stack'];
13161316
$this->assertEquals($expected,array_keys($container->getDefinition('session_listener')->getArgument(0)->getValues()));
13171317
}
13181318

‎src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md‎

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

4+
5.2.0
5+
-----
6+
7+
* added session usage
8+
49
5.0.0
510
-----
611

‎src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig‎

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@
5959
<b>Has session</b>
6060
<span>{%ifcollector.sessionmetadata|length %}yes{%else %}no{%endif %}</span>
6161
</div>
62+
63+
<divclass="sf-toolbar-info-piece">
64+
<b>Stateless Check</b>
65+
<span>{%ifcollector.statelesscheck %}yes{%else %}no{%endif %}</span>
66+
</div>
6267
</div>
6368

6469
{%ifredirect_handlerisdefined -%}
@@ -228,7 +233,7 @@
228233
</div>
229234

230235
<divclass="tab {{collector.sessionmetadataisempty?'disabled' }}">
231-
<h3class="tab-title">Session</h3>
236+
<h3class="tab-title">Session{%ifcollector.sessionusagesis notempty %} <spanclass="badge">{{collector.sessionusages|length }}</span>{%endif %}</h3>
232237

233238
<divclass="tab-content">
234239
<h3>Session Metadata</h3>
@@ -250,6 +255,54 @@
250255
{%else %}
251256
{{include('@WebProfiler/Profiler/table.html.twig', {data:collector.sessionattributes,labels: ['Attribute','Value'] },with_context =false) }}
252257
{%endif %}
258+
259+
<h3>Session Usage</h3>
260+
261+
<divclass="metrics">
262+
<divclass="metric">
263+
<spanclass="value">{{collector.sessionusages|length }}</span>
264+
<spanclass="label">Usages</span>
265+
</div>
266+
267+
<divclass="metric">
268+
<spanclass="value">{{include('@WebProfiler/Icon/' ~ (collector.statelesscheck ?'yes' :'no')~'.svg') }}</span>
269+
<spanclass="label">Stateless check enabled</span>
270+
</div>
271+
</div>
272+
273+
{%ifcollector.sessionusagesisempty %}
274+
<divclass="empty">
275+
<p>Session not used.</p>
276+
</div>
277+
{%else %}
278+
<tableclass="session_usages">
279+
<thead>
280+
<tr>
281+
<thclass="full-width">Usage</th>
282+
</tr>
283+
</thead>
284+
285+
<tbody>
286+
{%forkey,usageincollector.sessionusages %}
287+
<tr>
288+
<tdclass="font-normal">
289+
{%-setlink=usage.file|file_link(usage.line) %}
290+
{%-iflink %}<ahref="{{link }}"title="{{usage.name }}">{%else %}<spantitle="{{usage.name }}">{%endif %}
291+
{{usage.name }}
292+
{%-iflink %}</a>{%else %}</span>{%endif %}
293+
<divclass="text-small font-normal">
294+
{%setusage_id='session-usage-trace-'~key %}
295+
<aclass="btn btn-link text-small sf-toggle"data-toggle-selector="#{{usage_id }}"data-toggle-alt-content="Hide trace">Show trace</a>
296+
</div>
297+
<divid="{{usage_id }}"class="context sf-toggle-content sf-toggle-hidden">
298+
{{ profiler_dump(usage.trace, maxDepth=2) }}
299+
</div>
300+
</td>
301+
</tr>
302+
{%endfor %}
303+
</tbody>
304+
</table>
305+
{%endif %}
253306
</div>
254307
</div>
255308

‎src/Symfony/Component/HttpKernel/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
5.2.0
55
-----
66

7+
* added session usage
78
* made the public`http_cache` service handle requests when available
89
* allowed enabling trusted hosts and proxies using new`kernel.trusted_hosts`,
910
`kernel.trusted_proxies` and`kernel.trusted_headers` parameters

‎src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php‎

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
useSymfony\Component\HttpFoundation\Cookie;
1616
useSymfony\Component\HttpFoundation\ParameterBag;
1717
useSymfony\Component\HttpFoundation\Request;
18+
useSymfony\Component\HttpFoundation\RequestStack;
1819
useSymfony\Component\HttpFoundation\Response;
20+
useSymfony\Component\HttpFoundation\Session\SessionBagInterface;
21+
useSymfony\Component\HttpFoundation\Session\SessionInterface;
1922
useSymfony\Component\HttpKernel\Event\ControllerEvent;
2023
useSymfony\Component\HttpKernel\Event\ResponseEvent;
2124
useSymfony\Component\HttpKernel\KernelEvents;
@@ -28,10 +31,13 @@
2831
class RequestDataCollectorextends DataCollectorimplements EventSubscriberInterface, LateDataCollectorInterface
2932
{
3033
protected$controllers;
34+
private$sessionUsages = [];
35+
private$requestStack;
3136

32-
publicfunction__construct()
37+
publicfunction__construct(?RequestStack$requestStack =null)
3338
{
3439
$this->controllers =new \SplObjectStorage();
40+
$this->requestStack =$requestStack;
3541
}
3642

3743
/**
@@ -105,6 +111,8 @@ public function collect(Request $request, Response $response, \Throwable $except
105111
'response_cookies' =>$responseCookies,
106112
'session_metadata' =>$sessionMetadata,
107113
'session_attributes' =>$sessionAttributes,
114+
'session_usages' =>array_values($this->sessionUsages),
115+
'stateless_check' =>$this->requestStack &&$this->requestStack->getMasterRequest()->attributes->get('_stateless',false),
108116
'flashes' =>$flashes,
109117
'path_info' =>$request->getPathInfo(),
110118
'controller' =>'n/a',
@@ -175,6 +183,7 @@ public function reset()
175183
{
176184
$this->data = [];
177185
$this->controllers =new \SplObjectStorage();
186+
$this->sessionUsages = [];
178187
}
179188

180189
publicfunctiongetMethod()
@@ -242,6 +251,16 @@ public function getSessionAttributes()
242251
return$this->data['session_attributes']->getValue();
243252
}
244253

254+
publicfunctiongetStatelessCheck()
255+
{
256+
return$this->data['stateless_check'];
257+
}
258+
259+
publicfunctiongetSessionUsages()
260+
{
261+
return$this->data['session_usages'];
262+
}
263+
245264
publicfunctiongetFlashes()
246265
{
247266
return$this->data['flashes']->getValue();
@@ -382,6 +401,37 @@ public function getName()
382401
return'request';
383402
}
384403

404+
publicfunctioncollectSessionUsage():void
405+
{
406+
$trace =debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
407+
408+
$traceEndIndex =\count($trace) -1;
409+
for ($i =$traceEndIndex;$i >0; --$i) {
410+
if (null !== ($class =$trace[$i]['class'] ??null) && (is_subclass_of($class, SessionInterface::class) ||is_subclass_of($class, SessionBagInterface::class))) {
411+
$traceEndIndex =$i;
412+
break;
413+
}
414+
}
415+
416+
if ((\count($trace) -1) ===$traceEndIndex) {
417+
return;
418+
}
419+
420+
// Remove part of the backtrace that belongs to session only
421+
array_splice($trace,0,$traceEndIndex);
422+
423+
// Merge identical backtraces generated by internal call reports
424+
$name =sprintf('%s:%s',$trace[1]['class'] ??$trace[0]['file'],$trace[0]['line']);
425+
if (!\array_key_exists($name,$this->sessionUsages)) {
426+
$this->sessionUsages[$name] = [
427+
'name' =>$name,
428+
'file' =>$trace[0]['file'],
429+
'line' =>$trace[0]['line'],
430+
'trace' =>$trace,
431+
];
432+
}
433+
}
434+
385435
/**
386436
* Parse a controller.
387437
*

‎src/Symfony/Component/HttpKernel/EventListener/AbstractSessionListener.php‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ public function onSessionUsage(): void
152152
return;
153153
}
154154

155+
if ($this->container &&$this->container->has('session_collector')) {
156+
$this->container->get('session_collector')();
157+
}
158+
155159
if (!$requestStack =$this->container &&$this->container->has('request_stack') ?$this->container->get('request_stack') :null) {
156160
return;
157161
}

‎src/Symfony/Component/HttpKernel/Tests/DataCollector/RequestDataCollectorTest.php‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
useSymfony\Component\HttpFoundation\ParameterBag;
1818
useSymfony\Component\HttpFoundation\RedirectResponse;
1919
useSymfony\Component\HttpFoundation\Request;
20+
useSymfony\Component\HttpFoundation\RequestStack;
2021
useSymfony\Component\HttpFoundation\Response;
2122
useSymfony\Component\HttpFoundation\Session\Session;
23+
useSymfony\Component\HttpFoundation\Session\SessionBagInterface;
24+
useSymfony\Component\HttpFoundation\Session\SessionInterface;
2225
useSymfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
2326
useSymfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
2427
useSymfony\Component\HttpKernel\DataCollector\RequestDataCollector;
@@ -248,6 +251,65 @@ public function testItCollectsTheRedirectionAndClearTheCookie()
248251
$this->assertNull($cookie->getValue());
249252
}
250253

254+
publicfunctiontestItCollectsTheSessionTraceProperly()
255+
{
256+
$collector =newRequestDataCollector();
257+
$request =$this->createRequest();
258+
259+
// RequestDataCollectorTest doesn't implement SessionInterface or SessionBagInterface, therefore should do nothing.
260+
$collector->collectSessionUsage();
261+
262+
$collector->collect($request,$this->createResponse());
263+
$this->assertSame([],$collector->getSessionUsages());
264+
265+
$collector->reset();
266+
267+
$session =$this->createMock(SessionInterface::class);
268+
$session->method('getMetadataBag')->willReturnCallback(staticfunction ()use ($collector) {
269+
$collector->collectSessionUsage();
270+
});
271+
$session->getMetadataBag();
272+
273+
$collector->collect($request,$this->createResponse());
274+
$collector->lateCollect();
275+
276+
$usages =$collector->getSessionUsages();
277+
278+
$this->assertCount(1,$usages);
279+
$this->assertSame(__FILE__,$usages[0]['file']);
280+
$this->assertSame(__LINE__ -9,$line =$usages[0]['line']);
281+
282+
$trace =$usages[0]['trace'];
283+
$this->assertSame('getMetadataBag',$trace[0]['function']);
284+
$this->assertSame(self::class,$class =$trace[1]['class']);
285+
286+
$this->assertSame(sprintf('%s:%s',$class,$line),$usages[0]['name']);
287+
}
288+
289+
publicfunctiontestStatelessCheck()
290+
{
291+
$requestStack =newRequestStack();
292+
$request =$this->createRequest();
293+
$requestStack->push($request);
294+
295+
$collector =newRequestDataCollector($requestStack);
296+
$collector->collect($request,$response =$this->createResponse());
297+
$collector->lateCollect();
298+
299+
$this->assertFalse($collector->getStatelessCheck());
300+
301+
$requestStack =newRequestStack();
302+
$request =$this->createRequest();
303+
$request->attributes->set('_stateless',true);
304+
$requestStack->push($request);
305+
306+
$collector =newRequestDataCollector($requestStack);
307+
$collector->collect($request,$response =$this->createResponse());
308+
$collector->lateCollect();
309+
310+
$this->assertTrue($collector->getStatelessCheck());
311+
}
312+
251313
protectedfunctioncreateRequest($routeParams = ['name' =>'foo'])
252314
{
253315
$request = Request::create('http://test.com/foo?bar=baz');

‎src/Symfony/Component/HttpKernel/Tests/EventListener/SessionListenerTest.php‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
useSymfony\Component\HttpFoundation\Response;
2121
useSymfony\Component\HttpFoundation\Session\Session;
2222
useSymfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
23+
useSymfony\Component\HttpKernel\DataCollector\RequestDataCollector;
2324
useSymfony\Component\HttpKernel\Event\FinishRequestEvent;
2425
useSymfony\Component\HttpKernel\Event\RequestEvent;
2526
useSymfony\Component\HttpKernel\Event\ResponseEvent;
@@ -260,9 +261,13 @@ public function testSessionUsageCallbackWhenDebugAndStateless()
260261
$requestStack->push($request);
261262
$requestStack->push(newRequest());
262263

264+
$collector =$this->createMock(RequestDataCollector::class);
265+
$collector->expects($this->once())->method('collectSessionUsage');
266+
263267
$container =newContainer();
264268
$container->set('initialized_session',$session);
265269
$container->set('request_stack',$requestStack);
270+
$container->set('session_collector', \Closure::fromCallable([$collector,'collectSessionUsage']));
266271

267272
$this->expectException(UnexpectedSessionUsageException::class);
268273
(newSessionListener($container,true))->onSessionUsage();
@@ -277,12 +282,16 @@ public function testSessionUsageCallbackWhenNoDebug()
277282
$request =newRequest();
278283
$request->attributes->set('_stateless',true);
279284

280-
$requestStack =$this->getMockBuilder(RequestStack::class)->getMock();
281-
$requestStack->expects($this->never())->method('getMasterRequest')->willReturn($request);
285+
$requestStack =newRequestStack();
286+
$requestStack->push($request);
287+
288+
$collector =$this->createMock(RequestDataCollector::class);
289+
$collector->expects($this->never())->method('collectSessionUsage');
282290

283291
$container =newContainer();
284292
$container->set('initialized_session',$session);
285293
$container->set('request_stack',$requestStack);
294+
$container->set('session_collector',$collector);
286295

287296
(newSessionListener($container))->onSessionUsage();
288297
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp