├── 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('

mysqli

', '', $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 | ![Screenshot](https://f.cloud.github.com/assets/44364/296136/37bad942-94dd-11e2-9eb6-bfc538b071f9.png) 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 | mysqlnd 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 | 42 | {%endif %} 43 | {% endfor %} 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {% for key, value in collector.statistics %} 54 | 55 | {% endfor %} 56 | 57 |
KeyValue
{{ key }}{{ value }}
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 | 73 | 74 | 75 | {% for key, value in collector.MysqlndQCTrace %} 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | {% endfor %} 85 | 86 |
No.Run timeStore TimeCachable
{{ value['query'] }}
#{{ key+1 }}{{ value['run_time'] }} ms{{ value['store_time'] }} ms{% if value['eligible_for_caching'] %}Cachable{% else %}Not cachable{% endif %}Stacktrace
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 | --------------------------------------------------------------------------------