8000 Extract the profiler to a new component · symfony/symfony-docs@ae02f08 · GitHub
[go: up one dir, main page]

Skip to content

Commit ae02f08

Browse files
author
jelte
committed
Extract the profiler to a new component
1 parent 59569c0 commit ae02f08

File tree

6 files changed

+183
-31
lines changed

6 files changed

+183
-31
lines changed

components/index.rst

Lines 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

Lines 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

Lines 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

Lines 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 </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+
* 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

Lines 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

Lines 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