├── DataCollector
└── MysqlndDataCollector.php
├── DependencyInjection
└── JSMysqlndExtension.php
├── JSMysqlndBundle.php
├── LICENSE
├── README.markdown
├── Resources
├── config
│ └── services.xml
├── public
│ └── images
│ │ └── mysqlnd.png
└── views
│ └── Collector
│ └── mysqlnd.html.twig
└── composer.json
/DataCollector/MysqlndDataCollector.php:
--------------------------------------------------------------------------------
1 | analyticsCollector = new Collector();
27 | if (Collector::canCollect()) {
28 | $this->analyticsCollector->start();
29 | }
30 | }
31 |
32 | public function __construct()
33 | {
34 | $this->startCollector();
35 | }
36 |
37 | public function onEarlyKernelRequest(GetResponseEvent $event)
38 | {
39 | if (!$this->analyticsCollector) {
40 | $this->startCollector();
41 | }
42 | }
43 |
44 | /**
45 | * {@inheritdoc}
46 | */
47 | public function collect(Request $request, Response $response, \Exception $exception = null)
48 | {
49 | if ($this->analyticsCollector) {
50 | $this->data['stats'] = $this->analyticsCollector->collect();
51 | } else {
52 | $this->data['stats'] = false;
53 | }
54 |
55 | if (function_exists('mysqlnd_qc_get_query_trace_log') && ini_get('mysqlnd_qc.collect_query_trace')) {
56 | $this->data['mysqlnd_qc_trace'] = mysqlnd_qc_get_query_trace_log();
57 | } else {
58 | $this->data['mysqlnd_qc_trace'] = false;
59 | }
60 | }
61 |
62 | /**
63 | * {@inheritdoc}
64 | */
65 | public function getName()
66 | {
67 | return 'mysqlnd';
68 | }
69 |
70 | /**
71 | * Returns the collected data to be used by the view.
72 | *
73 | * @return array
74 | */
75 | public function getStatistics()
76 | {
77 | return $this->data['stats'];
78 | }
79 |
80 | public function getMysqlndQCTrace()
81 | {
82 | return $this->data['mysqlnd_qc_trace'];
83 | }
84 |
85 | /**
86 | * Dump information about mysqli.
87 | *
88 | * This is used by the view in case no statistics were collected to
89 | * ease the debugging
90 | *
91 | * @return string
92 | */
93 | public function getMysqlInfo()
94 | {
95 | if (!extension_loaded("mysqli")) {
96 | return "The mysqli extension is not available at all.";
97 | }
98 |
99 | ob_start();
100 | $re = new \ReflectionExtension("mysqli");
101 | $re->info();
102 | $info = ob_get_contents();
103 | ob_end_clean();
104 |
105 | return str_replace('
', '', $info);
106 | }
107 |
108 | public function getAnalytics()
109 | {
110 | return new Engine(new DefaultRuleProvider(), new Calculator($this->getStatistics()));
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/DependencyInjection/JSMysqlndExtension.php:
--------------------------------------------------------------------------------
1 | load('services.xml');
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/JSMysqlndBundle.php:
--------------------------------------------------------------------------------
1 |
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice,
8 | this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 | * Neither the name JSMysqlndBundle nor the names of its contributors may be
13 | used to endorse or promote products derived from this software without
14 | specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | JSMysqlndBundle
2 | ===============
3 |
4 | The JSMysqlndBundle is an extension to th Symfony2 profiling toolbar. It
5 | extends the data collection with information gathered from PHP's mysqlnd
6 | database driver, giving more insight on the performance.
7 |
8 | 
9 |
10 | Requirements
11 | -----------
12 |
13 | For making use of this bundle you need Symfony2 running on a PHP setup
14 | where the mysqli extension is activated and mysqlnd is being used. The mysqli
15 | extension is only used to retrieve data. It is no requirement for your
16 | application to use to use mysqli. Applications using Doctrine and PDO are
17 | fully supported.
18 |
19 | Installation
20 | ------------
21 |
22 | Installation is a quick process:
23 |
24 | 1. Download JSMysqlndBundle or install it via Composer
25 | 2. Configure the Autoloader
26 | 3. Enable the Bundle
27 |
28 | ### Step 1: Download JSMysqlndBundle
29 |
30 | Ultimately, the JSMysqlndBundle files should be downloaded to the
31 | `vendor/bundles/JS/MysqlndBundle` directory.
32 |
33 | This can be done in several ways, depending on your preference. The first
34 | method is the standard method for Symfony 2.1+.
35 |
36 | **Using Composer**
37 |
38 | ``` bash
39 | $ php composer.phar require "js/mysqlnd-bundle=v1.1.3"
40 | ```
41 |
42 | Take a look at [the page on Packagist web site](https://packagist.org/packages/js/mysqlnd-bundle) for more details and up-to-date version numbers.
43 |
44 | **Using the vendors script**
45 |
46 | This method is the standard method for Symfony 2.0
47 | Add the following lines in your `deps` file:
48 |
49 | ```
50 | [JSMysqlndBundle]
51 | git=git://github.com/johannes/JSMysqlndBundle.git
52 | target=bundles/JS/MysqlndBundle
53 | ```
54 |
55 | Now, run the vendors script to download the bundle:
56 |
57 | ``` bash
58 | $ php bin/vendors install
59 | ```
60 |
61 | **Using submodules**
62 |
63 | If you prefer instead to use git submodules, the run the following:
64 |
65 | ``` bash
66 | $ git submodule add git://github.com/johannes/JSMysqlndBundle.git vendor/bundles/JS/MysqlndBundle
67 | $ git submodule update --init
68 | ```
69 |
70 | ### Step 2: Configure the Autoloader
71 |
72 | This step should be omitted if you used Composer to install this Bundle.
73 |
74 | Add the `JS` namespace to your autoloader:
75 |
76 | ``` php
77 | registerNamespaces(array(
81 | // ...
82 | 'JS' => __DIR__.'/../vendor/bundles',
83 | ));
84 | ```
85 |
86 | ### Step 3: Enable the bundle
87 |
88 | Finally, enable the bundle in the kernel. Note: You probably want to do this
89 | for development and test systems only.
90 |
91 | ``` php
92 | getEnvironment(), array('dev', 'test'))) {
102 | // ...
103 | $bundles[] = new \JS\MysqlndBundle\JSMysqlndBundle();
104 | }
105 | }
106 | ```
107 |
--------------------------------------------------------------------------------
/Resources/config/services.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | JS\MysqlndBundle\DataCollector\MysqlndDataCollector
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Resources/public/images/mysqlnd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johannes/JSMysqlndBundle/f658cfdfa42b362fc709f6deba0667838dc3c290/Resources/public/images/mysqlnd.png
--------------------------------------------------------------------------------
/Resources/views/Collector/mysqlnd.html.twig:
--------------------------------------------------------------------------------
1 | {% extends 'WebProfilerBundle:Profiler:layout.html.twig' %}
2 |
3 | {% block toolbar %}
4 | {% if collector.statistics %}
5 | {% set icon %}
6 |
7 | {% endset %}
8 | {% set text %}
9 | mysqlnd
10 | {% endset %}
11 | {% include 'WebProfilerBundle:Profiler:toolbar_item.html.twig' with { 'link': profiler_url } %}
12 | {% endif %}
13 | {% endblock %}
14 |
15 |
16 | {% block menu %}
17 |
18 |
19 | mysqlnd
20 |
21 | {% endblock %}
22 |
23 | {% block panel %}
24 |
25 |
mysqlnd Statistics
26 |
27 | {% if collector.statistics %}
28 | {% set show_all = app.request.query.get('show_all', 0) %}
29 |
30 | {% for key, value in collector.analytics %}
31 | {% if show_all or value.matched %}
32 |
33 | {% if value.matched %}
34 | -
35 | {% else %}
36 |
-
37 | {%endif %}
38 | {{ value.name }}
39 | - {{ value.guidance }}
40 | - Failed test: {{ value.leftFormula }} {{ value.operator }} {{ value.rightFormula }}
41 |
42 | {%endif %}
43 | {% endfor %}
44 |
45 |
46 |
47 |
48 | Key |
49 | Value |
50 |
51 |
52 |
53 | {% for key, value in collector.statistics %}
54 | {{ key }} | {{ value }} |
55 | {% endfor %}
56 |
57 |
58 |
Documentation on the individual statistics can be found on http://php.net/mysqlnd.stats.
59 | {% else %}
60 |
No statistics collected for this request.
61 |
For collecting data PHP requires the mysqli extension and must use mysqlnd as Client API Library.
62 | {{ collector.mysqlInfo|raw }}
63 | {%endif %}
64 |
65 |
66 |
67 |
mysqlnd_qc Query Tracing
68 |
69 | {% if collector.MysqlndQCTrace %}
70 |
71 |
72 | No. | Run time | Store Time | Cachable |
73 |
74 |
75 | {% for key, value in collector.MysqlndQCTrace %}
76 | {{ value['query'] }} |
77 | #{{ key+1 }} |
78 | {{ value['run_time'] }} ms |
79 | {{ value['store_time'] }} ms |
80 | {% if value['eligible_for_caching'] %}Cachable{% else %}Not cachable{% endif %} |
81 | Stacktrace |
82 |
83 | {{ value['origin'] }} |
84 | {% endfor %}
85 |
86 |
87 | {% else %}
88 |
No myslqnd_qc traces collected for this request.
89 |
For collecting trace data PHP requires the mysqlnd_qc extension and mysqlnd_qc.collect_query_trace has to be enabled in php.ini.
90 | {% endif %}
91 |
92 | {% endblock %}
93 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "js/mysqlnd-bundle",
3 | "type": "symfony-bundle",
4 | "description": "The JSMysqlndBundle is an extension to the Symfony2 profiling toolbar. It extends the data collection with information gathered from PHP's mysqlnd database driver, giving more insight on the performance.",
5 | "keywords": ["database", "mysql", "mysqlnd", "profiler"],
6 | "homepage": "https://github.com/johannes/JSMysqlndBundle",
7 | "license": "BSD-3-Clause",
8 | "authors": [
9 | {
10 | "name": "Johannes Schlüter",
11 | "homepage": "http://schlueters.de"
12 | },
13 | {
14 | "name": "Max Romanovsky",
15 | "homepage": "http://maxromanovsky.com"
16 | },
17 | {
18 | "name": "JSMysqlndBundle Community",
19 | "homepage": "https://github.com/johannes/JSMysqlndBundle/contributors"
20 | }
21 | ],
22 | "minimum-stability": "dev",
23 | "require": {
24 | "php": ">=5.3.2",
25 | "ext-mysqli": "*",
26 | "ext-mysqlnd": "*",
27 | "symfony/framework-bundle": "~2.0",
28 | "js/mysqlnd-analytics": "v1.1.*"
29 | },
30 | "suggest": {
31 | "ext-mysqlnd_qc": "Required for Query Tracing"
32 | },
33 | "autoload": {
34 | "psr-0": {
35 | "JS\\MysqlndBundle": ""
36 | }
37 | },
38 | "target-dir": "JS/MysqlndBundle"
39 | }
40 |
--------------------------------------------------------------------------------