Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b8df582

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

File tree

8 files changed

+179
-49
lines changed

8 files changed

+179
-49
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/map.rst.inc

Lines 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

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();
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

Lines 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

Lines 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

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

cookbook/testing/profiling.rst

Lines 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)