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 b8df582

Browse filesBrowse files
author
jelte
committed
Extract the profiler to a new component
1 parent 59569c0 commit b8df582
Copy full SHA for b8df582

File tree

8 files changed

+179
-49
lines changed
Filter options

8 files changed

+179
-49
lines changed

‎components/index.rst

Copy file name to clipboardExpand all lines: components/index.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ The Components
2323
intl
2424
options_resolver
2525
process
26+
profiler/index
2627
property_access/index
2728
routing/index
2829
security/index

‎components/map.rst.inc

Copy file name to clipboardExpand all lines: components/map.rst.inc
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@
115115

116116
* :doc:`/components/process`
117117

118+
* :doc:`/components/profiler/index`
119+
120+
* :doc:`/components/profiler/introduction`
121+
118122
* :doc:`/components/property_access/index`
119123

120124
* :doc:`/components/property_access/introduction`

‎components/profiler/index.rst

Copy file name to clipboard
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Profiler
2+
========
3+
4+
.. toctree::
5+
:maxdepth: 2
6+
7+
introduction

‎components/profiler/introduction.rst

Copy file name to clipboard
+73Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
.. index::
2+
single: Profiler
3+
single: Components; Profiler
4+
5+
The Profiler Component
6+
======================
7+
8+
The Profiler component provides tools to collected and present a profile of executed code.
9+
10+
.. versionadded:: 2.8
11+
The Profiler component was introduced in Symfony 2.8. Previously, the classes
12+
were located in the HttpKernel component.
13+
14+
Installation
15+
------------
16+
17+
You can install the component in many different ways:
18+
19+
* :doc:`Install it via Composer </components/using_components>` (``symfony/profiler`` on `Packagist`_);
20+
* Use the official Git repository (https://github.com/symfony/Profiler).
21+
22+
Usage
23+
-----
24+
25+
The Profiler component provides several tools to help you debug PHP code.
26+
Enabling them all is as easy as it can get::
27+
28+
use Symfony\Component\Profiler\Profiler;
29+
use Symfony\Component\Profiler\Storage\FileProfilerStorage;
30+
31+
$storage = new FileProfilerStorage(__DIR__.'/cache/profiler');
32+
$profiler = new Profiler($storage);
33+
34+
// $profile is an implementation of ProfileInterface.
35+
$profile = $profiler->profile();
36+
37+
$profiler->save(
38+
$profile,
39+
array(
40+
'url' => http://localhost/',
41+
'ip' => '127.0.0.1',
42+
'method' => 'GET',
43+
'response_code' => 200,
44+
'profile_type' => 'http',
45+
)
46+
);
47+
48+
if your project makes use of the :doc:`EventDispatcher component </components/event_dispatcher/introduction>`, you can automate the profiling by using the corresponding
49+
EventListeners :class:`Symfony\\Component\\Profiler\\EventListener\\HttpProfilerListener`.
50+
51+
.. caution::
52+
53+
You should limit the profiler tools in a production environment to only profile on Exceptions as
54+
profile every request will generate a significant portion of data and increase the response time.
55+
56+
Collecting Data with DataCollectors
57+
-----------------------------------
58+
59+
The Profiler assembles a Profile with data it gets from DataCollectors.
60+
61+
A good deal of Components already provide usefull DataCollectors:
62+
63+
* :doc:`Debug component </components/debug/introduction>`: :class:`Symfony\\Component\\Debug\\Profiler\\ExceptionDataCollector`
64+
* :doc:`EventDispatcher component </components/event_dispatcher/introduction>`: :class:`Symfony\\Component\\EventDispatcher\\Profiler\\EventDataCollector`
65+
* :doc:`Form component </components/form/introduction>`: :class:`Symfony\\Component\\Form\\Extension\\Profiler\\FormDataCollector`
66+
* :doc:`HttpKernel component </components/http_kernel/introduction>`: :class:`Symfony\\Component\\HttpKernel\\Profiler\\RequestDataCollector` & :class:`Symfony\\Component\\HttpKernel\\Profiler\\RouteDataCollector`
67+
* :doc:`Security component </components/security/introduction>`: :class:`Symfony\\Component\\Security\\Core\\Profiler\\SecurityDataCollector`
68+
* :doc:`Translation component </components/translation/introduction>`: :class:`Symfony\\Component\\Translation\\Profiler\\TranslationDataCollector`
69+
* :doc:`VarDumper component </components/var_dumper/introduction>`: :class:`Symfony\\Component\\VarDumper\\Profiler\\DumpDataCollector`
70+
* `Monolog bridge`: :class:`Symfony\\Bridge\\Monolog\\Profiler\\LoggerDataCollector`
71+
* `Twig bridge`: :class:`Symfony\\Bridge\\Twig\\Profiler\\TwigDataCollector`
72+
73+
.. _Packagist: https://packagist.org/packages/symfony/profiler

‎cookbook/profiler/data_collector.rst

Copy file name to clipboardExpand all lines: cookbook/profiler/data_collector.rst
+81-28Lines changed: 81 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,73 +4,126 @@
44
How to Create a custom Data Collector
55
=====================================
66

7-
:doc:`The Symfony Profiler </cookbook/profiler/index>` delegates data collecting to
7+
:doc:`The Symfony Profiler </components/profiler/index>` delegates data collecting to
88
data collectors. Symfony comes bundled with a few of them, but you can easily
99
create your own.
1010

1111
Creating a custom Data Collector
1212
--------------------------------
1313

1414
Creating a custom data collector is as simple as implementing the
15-
:class:`Symfony\\Component\\HttpKernel\\DataCollector\\DataCollectorInterface`::
15+
:class:`Symfony\\Component\\Profiler\\DataCollector\\DataCollectorInterface`::
1616

1717
interface DataCollectorInterface
1818
{
1919
/**
20-
* Collects data for the given Request and Response.
20+
* Returns the collected data.
2121
*
22-
* @param Request $request A Request instance
23-
* @param Response $response A Response instance
24-
* @param \Exception $exception An Exception instance
25-
*/
26-
function collect(Request $request, Response $response, \Exception $exception = null);
27-
28-
/**
29-
* Returns the name of the collector.
22+
* @return ProfileDataInterface
3023
*
31-
* @return string The collector name
24+
* @todo introduce in 3.0
3225
*/
33-
function getName();
26+
public function getCollectedData();
27+
}
28+
29+
if the data should be collected just prior to the Profile being saved add the :class:`Symfony\\Component\\Profiler\\DataCollector\\LateDataCollectorInterface`::
30+
31+
interface LateDataCollectorInterface
32+
{
33+
}
34+
35+
The ``getCollectedData()`` method is responsible for storing the data it wants to give
36+
access to in a :class:`Symfony\\Component\\Profiler\\ProfileData\\ProfileDataInterface`::
37+
38+
interface ProfileDataInterface extends \Serializable
39+
{
40+
public function getName();
3441
}
3542

3643
The ``getName()`` method must return a unique name. This is used to access the
3744
information later on (see :doc:`/cookbook/testing/profiling` for
3845
instance).
3946

40-
The ``collect()`` method is responsible for storing the data it wants to give
41-
access to in local properties.
42-
4347
.. caution::
4448

45-
As the profiler serializes data collector instances, you should not
49+
As the profiler serializes ProfileData instances, you should not
4650
store objects that cannot be serialized (like PDO objects), or you need
4751
to provide your own ``serialize()`` method.
4852

49-
Most of the time, it is convenient to extend
50-
:class:`Symfony\\Component\\HttpKernel\\DataCollector\\DataCollector` and
51-
populate the ``$this->data`` property (it takes care of serializing the
52-
``$this->data`` property)::
53+
Example DataCollector::
5354

54-
class MemoryDataCollector extends DataCollector
55+
class MemoryDataCollector extends AbstractDataCollector implements LateDataCollectorInterface
5556
{
56-
public function collect(Request $request, Response $response, \Exception $exception = null)
57+
private $memoryLimit;
58+
59+
/**
60+
* Constructor.
61+
*/
62+
public function __construct()
5763
{
58-
$this->data = array(
59-
'memory' => memory_get_peak_usage(true),
60-
);
64+
$this->memoryLimit = ini_get('memory_limit');
6165
}
6266

63-
public function getMemory()
67+
/**
68+
* {@inheritdoc}
69+
*/
70+
public function lateCollect()
71+
{
72+
return new MemoryData(memory_get_peak_usage(true), $this->memoryLimit);
73+
}
74+
}
75+
76+
class MemoryData implements ProfileDataInterface
77+
{
78+
private $memory;
79+
private $memoryLimit;
80+
81+
/**
82+
* Constructor.
83+
*
84+
* @param int $memory The current used memory.
85+
* @param int $memoryLimit The memory limit.
86+
*/
87+
public function __construct($memory, $memoryLimit)
6488
{
65-
return $this->data['memory'];
89+
$this->memory = $memory;
90+
$this->memoryLimit = $this->convertToBytes($memoryLimit);
6691
}
6792

93+
/**
94+
* {@inheritdoc}
95+
*/
6896
public function getName()
6997
{
7098
return 'memory';
7199
}
100+
101+
/**
102+
* Returns the memory.
103+
*
104+
* @return int The memory
105+
*/
106+
public function getMemory()
107+
{
108+
return $this->memory;
109+
}
110+
111+
/**
112+
* Returns the PHP memory limit.
113+
*
114+
* @return int The memory limit
115+
*/
116+
public function getMemoryLimit()
117+
{
118+
return $this->memoryLimit;
119+
}
120+
121+
//...
72122
}
73123

124+
125+
126+
74127
.. _data_collector_tag:
75128

76129
Enabling custom Data Collectors

‎cookbook/profiler/profiling_data.rst

Copy file name to clipboardExpand all lines: cookbook/profiler/profiling_data.rst
+9-17Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,37 @@ How to Access Profiling Data Programmatically
66

77
Most of the times, the profiler information is accessed and analyzed using its
88
web-based visualizer. However, you can also retrieve profiling information
9-
programmatically thanks to the methods provided by the ``profiler`` service.
10-
11-
When the response object is available, use the
12-
:method:`Symfony\\Component\\HttpKernel\\Profiler\\Profiler::loadProfileFromResponse`
13-
method to access to its associated profile::
14-
15-
// ... $profiler is the 'profiler' service
16-
$profile = $profiler->loadProfileFromResponse($response);
9+
programmatically thanks to the methods provided by the ``profiler.storage`` service.
1710

1811
When the profiler stores data about a request, it also associates a token with it;
1912
this token is available in the ``X-Debug-Token`` HTTP header of the response.
2013
Using this token, you can access the profile of any past response thanks to the
21-
:method:`Symfony\\Component\\HttpKernel\\Profiler\\Profiler::loadProfile` method::
14+
:method:`Symfony\\Component\\Profiler\\Storage\\ProfilerStorageInterface::read` method::
2215

2316
$token = $response->headers->get('X-Debug-Token');
24-
$profile = $container->get('profiler')->loadProfile($token);
17+
$profile = $container->get('profiler.storage')->read($token);
2518

2619
.. tip::
2720

2821
When the profiler is enabled but not the web debug toolbar, inspect the page
2922
with your browser's developer tools to get the value of the ``X-Debug-Token``
3023
HTTP header.
3124

32-
The ``profiler`` service also provides the
33-
:method:`Symfony\\Component\\HttpKernel\\Profiler\\Profiler::find` method to
25+
The ``profiler.storage`` service also provides the
26+
:method:`Symfony\\Component\\Profiler\\Storage\\ProfilerStorageInterface::findBy` method to
3427
look for tokens based on some criteria::
3528

3629
// get the latest 10 tokens
37-
$tokens = $container->get('profiler')->find('', '', 10, '', '');
30+
$tokens = $container->get('profiler.storage')->findBy(array(), 10, '', '');
3831

3932
// get the latest 10 tokens for all URL containing /admin/
40-
$tokens = $container->get('profiler')->find('', '/admin/', 10, '', '');
33+
$tokens = $container->get('profiler.storage')->findBy(array('url' => '/admin/'), 10, '', '');
4134

4235
// get the latest 10 tokens for local requests
43-
$tokens = $container->get('profiler')->find('127.0.0.1', '', 10, '', '');
36+
$tokens = $container->get('profiler.storage')->findBy(array('ip' => '127.0.0.1'), 10, '', '');
4437

4538
// get the latest 10 tokens for requests that happened between 2 and 4 days ago
46-
$tokens = $container->get('profiler')
47-
->find('', '', 10, '4 days ago', '2 days ago');
39+
$tokens = $container->get('profiler.storage')->findBy(array(), 10, '4 days ago', '2 days ago');
4840

4941
Lastly, if you want to manipulate profiling data on a different machine than the
5042
one where the information was generated, use the ``profiler:export`` and

‎cookbook/profiler/storage.rst

Copy file name to clipboardExpand all lines: cookbook/profiler/storage.rst
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ uses MySQL as the storage for the profiler with a lifetime of one hour:
5757
),
5858
));
5959
60-
The :doc:`HttpKernel component </components/http_kernel/introduction>` currently
60+
The :doc:`Profiler component </components/profiler/introduction>` currently
6161
supports the following profiler storage drivers:
6262

6363
* file

‎cookbook/testing/profiling.rst

Copy file name to clipboardExpand all lines: cookbook/testing/profiling.rst
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ the ``test`` environment)::
3434
// check the number of requests
3535
$this->assertLessThan(
3636
10,
37-
$profile->getCollector('db')->getQueryCount()
37+
$profile->get('db')->getQueryCount()
3838
);
3939

4040
// check the time spent in the framework
4141
$this->assertLessThan(
4242
500,
43-
$profile->getCollector('time')->getDuration()
43+
$profile->get('time')->getDuration()
4444
);
4545
}
4646
}
@@ -52,7 +52,7 @@ finish. It's easy to achieve if you embed the token in the error message::
5252

5353
$this->assertLessThan(
5454
30,
55-
$profile->getCollector('db')->getQueryCount(),
55+
$profile->get('db')->getQueryCount(),
5656
sprintf(
5757
'Checks that query count is less than 30 (token %s)',
5858
$profile->getToken()

0 commit comments

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