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 e823e85

Browse filesBrowse files
committed
feature #21065 Added cache data collector and profiler page (Nyholm)
This PR was squashed before being merged into the 3.3-dev branch (closes #21065). Discussion ---------- Added cache data collector and profiler page | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #19297 | License | MIT | Doc PR | n/a Adding a first version of cache profiler page. Most things are taken from PHP-cache. FYI: @aequasi ### What is included? A collector, recording adapter and a profiler page. ![screen shot 2016-12-27 at 16 07 35](https://cloud.githubusercontent.com/assets/1275206/21502325/4bee2ed4-cc4f-11e6-89fc-37ed16aca864.png) ![screen shot 2016-12-27 at 16 07 45](https://cloud.githubusercontent.com/assets/1275206/21502326/4bee9450-cc4f-11e6-904d-527b7b0ce85b.png) ### What is not included? * A good logo * Nice design on the profiler page This PR aims to pass as the minimum requirement for a cache page. Im happy to do fancy extra features but those should be a different PR. Commits ------- 7497f1c Added cache data collector and profiler page
2 parents 71f8f15 + 7497f1c commit e823e85
Copy full SHA for e823e85

File tree

7 files changed

+400
-0
lines changed
Filter options

7 files changed

+400
-0
lines changed
+50Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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\Bundle\FrameworkBundle\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\Cache\Adapter\TraceableAdapter;
15+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
use Symfony\Component\DependencyInjection\Reference;
18+
19+
/**
20+
* Inject a data collector to all the cache services to be able to get detailed statistics.
21+
*
22+
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
23+
*/
24+
class CacheCollectorPass implements CompilerPassInterface
25+
{
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
public function process(ContainerBuilder $container)
30+
{
31+
if (!$container->hasDefinition('data_collector.cache')) {
32+
return;
33+
}
34+
35+
$collectorDefinition = $container->getDefinition('data_collector.cache');
36+
foreach ($container->findTaggedServiceIds('cache.pool') as $id => $attributes) {
37+
if ($container->getDefinition($id)->isAbstract()) {
38+
continue;
39+
}
40+
41+
$container->register($id.'.recorder', TraceableAdapter::class)
42+
->setDecoratedService($id)
43+
->addArgument(new Reference($id.'.recorder.inner'))
44+
->setPublic(false);
45+
46+
// Tell the collector to add the new instance
47+
$collectorDefinition->addMethodCall('addInstance', array($id, new Reference($id)));
48+
}
49+
}
50+
}

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $
356356

357357
$loader->load('profiling.xml');
358358
$loader->load('collectors.xml');
359+
$loader->load('cache_debug.xml');
359360

360361
if ($this->formConfigEnabled) {
361362
$loader->load('form_debug.xml');

‎src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass;
1515
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddDebugLogProcessorPass;
1616
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass;
17+
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CacheCollectorPass;
1718
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolPass;
1819
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CachePoolClearerPass;
1920
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ControllerArgumentValueResolverPass;
@@ -105,6 +106,7 @@ public function build(ContainerBuilder $container)
105106
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);
106107
$container->addCompilerPass(new CompilerDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);
107108
$container->addCompilerPass(new ConfigCachePass());
109+
$container->addCompilerPass(new CacheCollectorPass());
108110
}
109111
}
110112
}
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
<!-- DataCollector -->
9+
<service id="data_collector.cache" class="Symfony\Component\Cache\DataCollector\CacheDataCollector">
10+
<tag name="data_collector" template="@WebProfiler/Collector/cache.html.twig" id="cache" priority="275" />
11+
</service>
12+
</services>
13+
</container>
+146Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %}
2+
3+
{% block toolbar %}
4+
{% if collector.totals.calls > 0 %}
5+
{% set icon %}
6+
{{ include('@WebProfiler/Icon/cache.svg') }}
7+
<span class="sf-toolbar-value">{{ collector.totals.calls }}</span>
8+
<span class="sf-toolbar-info-piece-additional-detail">
9+
<span class="sf-toolbar-label">in</span>
10+
<span class="sf-toolbar-value">{{ '%0.2f'|format(collector.totals.time * 1000) }}</span>
11+
<span class="sf-toolbar-label">ms</span>
12+
</span>
13+
{% endset %}
14+
{% set text %}
15+
<div class="sf-toolbar-info-piece">
16+
<b>Cache Calls</b>
17+
<span>{{ collector.totals.calls }}</span>
18+
</div>
19+
<div class="sf-toolbar-info-piece">
20+
<b>Total time</b>
21+
<span>{{ '%0.2f'|format(collector.totals.time * 1000) }} ms</span>
22+
</div>
23+
<div class="sf-toolbar-info-piece">
24+
<b>Cache hits</b>
25+
<span>{{ collector.totals.hits }}/{{ collector.totals.reads }} ({{ collector.totals['hits/reads'] }})</span>
26+
</div>
27+
<div class="sf-toolbar-info-piece">
28+
<b>Cache writes</b>
29+
<span>{{ collector.totals.writes }}</span>
30+
</div>
31+
{% endset %}
32+
{% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %}
33+
{% endif %}
34+
{% endblock %}
35+
36+
{% block menu %}
37+
<span class="label {{ collector.totals.calls == 0 ? 'disabled' }}">
38+
<span class="icon">
39+
{{ include('@WebProfiler/Icon/cache.svg') }}
40+
</span>
41+
<strong>Cache</strong>
42+
<span class="count">
43+
<span>{{ collector.totals.calls }}</span>
44+
<span>{{ '%0.2f'|format(collector.totals.time * 1000) }} ms</span>
45+
</span>
46+
</span>
47+
{% endblock %}
48+
49+
{% block panel %}
50+
<h2>Cache</h2>
51+
<div class="metrics">
52+
<div class="metric">
53+
<span class="value">{{ collector.totals.calls }}</span>
54+
<span class="label">Total calls</span>
55+
</div>
56+
<div class="metric">
57+
<span class="value">{{ '%0.2f'|format(collector.totals.time * 1000) }} ms</span>
58+
<span class="label">Total time</span>
59+
</div>
60+
<div class="metric">
61+
<span class="value">{{ collector.totals.reads }}</span>
62+
<span class="label">Total reads</span>
63+
</div>
64+
<div class="metric">
65+
<span class="value">{{ collector.totals.hits }}</span>
66+
<span class="label">Total hits</span>
67+
</div>
68+
<div class="metric">
69+
<span class="value">{{ collector.totals.misses }}</span>
70+
<span class="label">Total misses</span>
71+
</div>
72+
<div class="metric">
73+
<span class="value">{{ collector.totals.writes }}</span>
74+
<span class="label">Total writes</span>
75+
</div>
76+
<div class="metric">
77+
<span class="value">{{ collector.totals.deletes }}</span>
78+
<span class="label">Total deletes</span>
79+
</div>
80+
<div class="metric">
81+
<span class="value">{{ collector.totals['hits/reads'] }}</span>
82+
<span class="label">Hits/reads</span>
83+
</div>
84+
</div>
85+
86+
{% for name, calls in collector.calls %}
87+
<h3>Statistics for '{{ name }}'</h3>
88+
<div class="metrics">
89+
{% for key, value in collector.statistics[name] %}
90+
<div class="metric">
91+
<span class="value">
92+
{% if key == 'time' %}
93+
{{ '%0.2f'|format(1000*value) }} ms
94+
{% else %}
95+
{{ value }}
96+
{% endif %}
97+
</span>
98+
<span class="label">{{ key|capitalize }}</span>
99+
</div>
100+
{% endfor %}
101+
</div>
102+
<h4>Calls for '{{ name }}'</h4>
103+
104+
{% if not collector.totals.calls %}
105+
<p>
106+
<em>No calls.</em>
107+
</p>
108+
{% else %}
109+
<table>
110+
<thead>
111+
<tr>
112+
<th style="width: 5rem;">Key</th>
113+
<th>Value</th>
114+
</tr>
115+
</thead>
116+
<tbody>
117+
{% for i, call in calls %}
118+
<tr>
119+
<th style="padding-top:2rem">#{{ i }}</th>
120+
<th style="padding-top:2rem">Pool::{{ call.name }}</th>
121+
</tr>
122+
<tr>
123+
<th>Argument</th>
124+
<td>{{ profiler_dump(call.argument, maxDepth=2) }}</td>
125+
</tr>
126+
<tr>
127+
<th>Results</th>
128+
<td>
129+
{% if call.result != false %}
130+
{{ profiler_dump(call.result, maxDepth=1) }}
131+
{% endif %}
132+
</td>
133+
</tr>
134+
<tr>
135+
<th>Time</th>
136+
<td>{{ '%0.2f'|format((call.end - call.start) * 1000) }} ms</td>
137+
</tr>
138+
139+
{% endfor %}
140+
</tbody>
141+
142+
</table>
143+
{% endif %}
144+
{% endfor %}
145+
146+
{% endblock %}
+3Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

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