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

Skip to content
  • Pricing
  • 8000

    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 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+
    -----
    < 802E /td>
    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.
    802E 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 : B72 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