|
| 1 | +.. index:: |
| 2 | + single: Profiling; Data Collector |
| 3 | + |
| 4 | +How to create a custom Data Collector |
| 5 | +===================================== |
| 6 | + |
| 7 | +The Symfony2 :doc:`Profiler </guides/internals/profiler>` delegates data |
| 8 | +collecting to data collectors. Symfony2 comes bundles with a few of them, but |
| 9 | +you can easily create your own. |
| 10 | + |
| 11 | +Creating a Custom Data Collector |
| 12 | +-------------------------------- |
| 13 | + |
| 14 | +Creating a custom data collector is as simple as implementing the |
| 15 | +:class:`Symfony\\Component\\HttpKernel\\DataCollector\\DataCollectorInterface`:: |
| 16 | + |
| 17 | + interface DataCollectorInterface |
| 18 | + { |
| 19 | + /** |
| 20 | + * Collects data for the given Request and Response. |
| 21 | + * |
| 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. |
| 30 | + * |
| 31 | + * @return string The collector name |
| 32 | + */ |
| 33 | + function getName(); |
| 34 | + } |
| 35 | + |
| 36 | +The ``getName()`` method must return a unique name. This is used to access the |
| 37 | +information later on (see the section about functional tests above for |
| 38 | +instance). |
| 39 | + |
| 40 | +The ``collect()`` method is responsible for storing the data it wants to give |
| 41 | +access to in local properties. |
| 42 | + |
| 43 | +.. caution:: |
| 44 | + |
| 45 | + As the profiler serializes data collector instances, you should not |
| 46 | + store objects that cannot be serialized (like PDO objects), or you need |
| 47 | + to provide your own ``serialize()`` method. |
| 48 | + |
| 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 | + |
| 54 | + class MemoryDataCollector extends DataCollector |
| 55 | + { |
| 56 | + public function collect(Request $request, Response $response, \Exception $exception = null) |
| 57 | + { |
| 58 | + $this->data = array( |
| 59 | + 'memory' => memory_get_peak_usage(true), |
| 60 | + ); |
| 61 | + } |
| 62 | + |
| 63 | + public function getMemory() |
| 64 | + { |
| 65 | + return $this->data['memory']; |
| 66 | + } |
| 67 | + |
| 68 | + public function getName() |
| 69 | + { |
| 70 | + return 'memory'; |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | +.. _data_collector_tag: |
| 75 | + |
| 76 | +Enabling Custom Data Collectors |
| 77 | +------------------------------- |
| 78 | + |
| 79 | +To enable a data collector, add it as a regular service in one of your |
| 80 | +configuration, and tag it with ``data_collector``: |
| 81 | + |
| 82 | +.. configuration-block:: |
| 83 | + |
| 84 | + .. code-block:: yaml |
| 85 | +
|
| 86 | + services: |
| 87 | + data_collector.your_collector_name: |
| 88 | + class: Fully\Qualified\Collector\Class\Name |
| 89 | + tags: |
| 90 | + - { name: data_collector } |
| 91 | +
|
| 92 | + .. code-block:: xml |
| 93 | +
|
| 94 | + <service id="data_collector.your_collector_name" class="Fully\Qualified\Collector\Class\Name"> |
| 95 | + <tag name="data_collector" /> |
| 96 | + </service> |
| 97 | +
|
| 98 | + .. code-block:: php |
| 99 | +
|
| 100 | + $container |
| 101 | + ->register('data_collector.your_collector_name', 'Fully\Qualified\Collector\Class\Name') |
| 102 | + ->addTag('data_collector') |
| 103 | + ; |
| 104 | +
|
| 105 | +Adding Web Profiler Templates |
| 106 | +----------------------------- |
| 107 | + |
| 108 | +When you want to display the data collected by your Data Collector in the web |
| 109 | +debug toolbar or the web profiler, create a Twig template following this |
| 110 | +skeleton: |
| 111 | + |
| 112 | +.. code-block:: jinja |
| 113 | +
|
| 114 | + {% extends 'WebProfilerBundle:Profiler:layout.html.twig' %} |
| 115 | +
|
| 116 | + {% block toolbar %} |
| 117 | + {# the web debug toolbar content #} |
| 118 | + {% endblock %} |
| 119 | +
|
| 120 | + {% block head %} |
| 121 | + {# if the web profiler panel needs some specific JS or CSS files #} |
| 122 | + {% endblock %} |
| 123 | +
|
| 124 | + {% block menu %} |
| 125 | + {# the menu content #} |
| 126 | + {% endblock %} |
| 127 | +
|
| 128 | + {% block panel %} |
| 129 | + {# the panel content #} |
| 130 | + {% endblock %} |
| 131 | +
|
| 132 | +Each block is optional. The ``toolbar`` block is used for the web debug |
| 133 | +toolbar and ``menu`` and ``panel`` are used to add a panel to the web |
| 134 | +profiler. |
| 135 | + |
| 136 | +All blocks have access to the ``collector`` object. |
| 137 | + |
| 138 | +.. tip:: |
| 139 | + |
| 140 | + Built-in templates use a base64 encoded image for the toolbar (``<img |
| 141 | + src="src="data:image/png;base64,..."``). You can easily calculate the |
| 142 | + base64 value for an image with this little script: ``echo |
| 143 | + base64_encode(file_get_contents($_SERVER['argv'][1]));``. |
| 144 | + |
| 145 | +To enable the template, add a ``template`` attribute to the ``data_collector`` |
| 146 | +tag in your configuration: |
| 147 | + |
| 148 | +.. configuration-block:: |
| 149 | + |
| 150 | + .. code-block:: yaml |
| 151 | +
|
| 152 | + services: |
| 153 | + data_collector.your_collector_name: |
| 154 | + class: Fully\Qualified\Collector\Class\Name |
| 155 | + tags: |
| 156 | + - { name: data_collector, template: "YourBundle:Collector:templatename" } |
| 157 | +
|
| 158 | + .. code-block:: xml |
| 159 | +
|
| 160 | + <service id="data_collector.your_collector_name" class="Fully\Qualified\Collector\Class\Name"> |
| 161 | + <tag name="data_collector" template="YourBundle:Collector:templatename" /> |
| 162 | + </service> |
| 163 | +
|
| 164 | + .. code-block:: php |
| 165 | +
|
| 166 | + $container |
| 167 | + ->register('data_collector.your_collector_name', 'Fully\Qualified\Collector\Class\Name') |
| 168 | + ->addTag('data_collector', array('template' => 'YourBundle:Collector:templatename')) |
| 169 | + ; |
| 170 | +
|
| 171 | +.. _data collectors: http://api.symfony-reloaded.org/PR4/index.html?q=DataCollector |
0 commit comments