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 eb59079

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

File tree

6 files changed

+183
-31
lines changed
Filter options

6 files changed

+183
-31
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/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($profile);
36+
37+
$profiler->save($profile);
38+
39+
Shortcuts are provided to profile HTTP Requests and Console Commands::
40+
41+
// Profile an HTTP Request & Repsonse
42+
$profiler->profileRequest($request, $response);
43+
44+
// Profile a Console Command
45+
$profiler->profileCommand($command, $input, $exitCode);
46+
47+
if your project makes use of the :doc:`EventDispatcher component </components/event_dispatcher/introduction>`, you can automate the profiling by using the corresponding
48+
EventListeners :class:`Symfony\\Component\\Profiler\\EventListener\\HttpProfilerListener` and
49+
:class:`Symfony\\Component\\Profiler\\EventListener\\ConsoleProfilerListener`.
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
+92-20Lines changed: 92 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,24 @@
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 </component/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+
* Set the Token of the active profile.
2121
*
22-
* @param Request $request A Request instance
23-
* @param Response $response A Response instance
24-
* @param \Exception $exception An Exception instance
22+
* @param $token
2523
*/
26-
function collect(Request $request, Response $response, \Exception $exception = null);
24+
public function setToken($token);
2725

2826
/**
2927
* Returns the name of the collector.
@@ -37,40 +35,114 @@ The ``getName()`` method must return a unique name. This is used to access the
3735
information later on (see :doc:`/cookbook/testing/profiling` for
3836
instance).
3937

40-
The ``collect()`` method is responsible for storing the data it wants to give
41-
access to in local properties.
38+
And implementing either the :class:`Symfony\\Component\\Profiler\\DataCollector\\RuntimeDataCollectorInterface`::
39+
40+
interface RuntimeDataCollectorInterface
41+
{
42+
/**
43+
* Collects data when profiler is triggered.
44+
*
45+
* @return ProfileDataInterface
46+
*/
47+
public function collect();
48+
}
49+
50+
or the :class:`Symfony\\Component\\Profiler\\DataCollector\\LateDataCollectorInterface`::
51+
52+
interface LateDataCollectorInterface
53+
{
54+
/**
55+
* Collects data as late as possible.
56+
*
57+
* @return ProfileDataInterface
58+
*/
59+
public function lateCollect();
60+
}
61+
62+
The ``collect()`` or ``lateCollect()`` method is responsible for storing the data it wants to give
63+
access to in a :class:`Symfony\\Component\\Profiler\\ProfileData\\ProfileDataInterface`.
4264

4365
.. caution::
4466

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

4971
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)::
72+
:class:`Symfony\\Component\\Profiler\\DataCollector\\AbstractDataCollector` which already implements
73+
:class:`Symfony\\Component\\Profiler\\DataCollector\\DataCollectorInterface` and `setToken($token)` the only thing
74+
left to do is to decide when the data is collected::
5375

54-
class MemoryDataCollector extends DataCollector
76+
class MemoryDataCollector extends AbstractDataCollector implements LateDataCollectorInterface
5577
{
56-
public function collect(Request $request, Response $response, \Exception $exception = null)
78+
private $memoryLimit;
79+
80+
/**
81+
* Constructor.
82+
*/
83+
public function __construct()
5784
{
58-
$this->data = array(
59-
'memory' => memory_get_peak_usage(true),
60-
);
85+
$this->memoryLimit = ini_get('memory_limit');
6186
}
6287

63-
public function getMemory()
88+
/**
89+
* {@inheritdoc}
90+
*/
91+
public function lateCollect()
6492
{
65-
return $this->data['memory'];
93+
return new MemoryData(memory_get_peak_usage(true), $this->memoryLimit);
6694
}
6795

96+
/**
97+
* {@inheritdoc}
98+
*/
6899
public function getName()
69100
{
70101
return 'memory';
71102
}
72103
}
73104

105+
class MemoryData implements ProfileDataInterface
106+
{
107+
private $memory;
108+
private $memoryLimit;
109+
110+
/**
111+
* Constructor.
112+
*
113+
* @param int $memory The current used memory.
114+
* @param int $memoryLimit The memory limit.
115+
*/
116+
public function __construct($memory, $memoryLimit)
117+
{
118+
$this->memory = $memory;
119+
$this->memoryLimit = $this->convertToBytes($memoryLimit);
120+
}
121+
122+
/**
123+
* Returns the memory.
124+
*
125+
* @return int The memory
126+
*/
127+
public function getMemory()
128+
{
129+
return $this->memory;
130+
}
131+
132+
/**
133+
* Returns the PHP memory limit.
134+
*
135+
* @return int The memory limit
136+
*/
137+
public function getMemoryLimit()
138+
{
139+
return $this->memoryLimit;
140+
}
141+
142+
//...
143+
}
144+
145+
74146
.. _data_collector_tag:
75147

76148
Enabling custom Data Collectors

‎cookbook/profiler/profiling_data.rst

Copy file name to clipboardExpand all lines: cookbook/profiler/profiling_data.rst
+9-10Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ web-based visualizer. However, you can also retrieve profiling information
99
programmatically thanks to the methods provided by the ``profiler`` service.
1010

1111
When the response object is available, use the
12-
:method:`Symfony\\Component\\HttpKernel\\Profiler\\Profiler::loadProfileFromResponse`
12+
:method:`Symfony\\Component\\Profiler\\Profiler::loadFromResponse`
1313
method to access to its associated profile::
1414

1515
// ... $profiler is the 'profiler' service
16-
$profile = $profiler->loadProfileFromResponse($response);
16+
$profile = $profiler->loadFromResponse($response);
1717

1818
When the profiler stores data about a request, it also associates a token with it;
1919
this token is available in the ``X-Debug-Token`` HTTP header of the response.
2020
Using this token, you can access the profile of any past response thanks to the
21-
:method:`Symfony\\Component\\HttpKernel\\Profiler\\Profiler::loadProfile` method::
21+
:method:`Symfony\\Component\\Profiler\\Profiler::load` method::
2222

2323
$token = $response->headers->get('X-Debug-Token');
24-
$profile = $container->get('profiler')->loadProfile($token);
24+
$profile = $container->get('profiler')->load($token);
2525

2626
.. tip::
2727

@@ -30,21 +30,20 @@ Using this token, you can access the profile of any past response thanks to the
3030
HTTP header.
3131

3232
The ``profiler`` service also provides the
33-
:method:`Symfony\\Component\\HttpKernel\\Profiler\\Profiler::find` method to
33+
:method:`Symfony\\Component\\Profiler\\Profiler::findBy` method to
3434
look for tokens based on some criteria::
3535

3636
// get the latest 10 tokens
37-
$tokens = $container->get('profiler')->find('', '', 10, '', '');
37+
$tokens = $container->get('profiler')->findBy(array(), 10, '', '');
3838

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

4242
// get the latest 10 tokens for local requests
43-
$tokens = $container->get('profiler')->find('127.0.0.1', '', 10, '', '');
43+
$tokens = $container->get('profiler')->findBy(array('ip' => '127.0.0.1'), 10, '', '');
4444

4545
// 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');
46+
$tokens = $container->get('profiler')->findBy(array(), 10, '4 days ago', '2 days ago');
4847

4948
Lastly, if you want to manipulate profiling data on a different machine than the
5049
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

0 commit comments

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