diff options
-rw-r--r-- | core/FrontController.php | 13 | ||||
-rw-r--r-- | core/Log/MessageScreenFormatter.php | 4 | ||||
-rw-r--r-- | core/Piwik.php | 202 | ||||
-rw-r--r-- | core/Profiler.php | 183 | ||||
-rw-r--r-- | core/Tracker.php | 2 | ||||
-rw-r--r-- | core/Tracker/Db.php | 2 | ||||
-rw-r--r-- | core/View.php | 11 | ||||
-rw-r--r-- | plugins/API/Controller.php | 1 |
8 files changed, 198 insertions, 220 deletions
diff --git a/core/FrontController.php b/core/FrontController.php index 88ddad8cf8..79a57b5e93 100644 --- a/core/FrontController.php +++ b/core/FrontController.php @@ -10,15 +10,12 @@ */ namespace Piwik; -use Piwik\NoAccessException; use Exception; use Piwik\API\Request; use Piwik\API\ResponseBuilder; -use Piwik\Session; -use Piwik\Timer; -use Piwik\Url; use Piwik\Log; -use Piwik\PluginsManager; +use Piwik\Session; +use Piwik\Profiler; use Zend_Registry; /** @@ -170,9 +167,9 @@ class FrontController public function __destruct() { try { - Piwik::printSqlProfilingReportZend(); - Piwik::printQueryCount(); - Piwik::printTimer(); + Profiler::displayDbProfileReport(); + Profiler::printQueryCount(); + Piwik::log(Zend_Registry::get('timer')); } catch (Exception $e) { } } diff --git a/core/Log/MessageScreenFormatter.php b/core/Log/MessageScreenFormatter.php index 36a6d4318b..7b9ac48cdf 100644 --- a/core/Log/MessageScreenFormatter.php +++ b/core/Log/MessageScreenFormatter.php @@ -9,8 +9,8 @@ * @package Piwik */ namespace Piwik\Log; -use Piwik\Piwik; use Piwik\Common; +use Piwik\Profiler; /** * Format a standard message event to be displayed on the screen. @@ -42,7 +42,7 @@ class MessageScreenFormatter extends ScreenFormatter $memory = ''; // Hacky: let's hide the memory usage in CLI to hide from the archive.php output if (!Common::isPhpCliMode()) { - $memory = '[' . Piwik::getMemoryUsage() . '] '; + $memory = '[' . Profiler::getMemoryUsage() . '] '; } $message = '[' . $event['timestamp'] . '] [' . $event['requestKey'] . '] ' . $memory . $message; return parent::format($message); diff --git a/core/Piwik.php b/core/Piwik.php index 96d5b6a15c..a96e0122b8 100644 --- a/core/Piwik.php +++ b/core/Piwik.php @@ -11,23 +11,16 @@ namespace Piwik; use Exception; -use Piwik\Access; -use Piwik\NoAccessException; -use Piwik\AssetManager; -use Piwik\Common; -use Piwik\Config; -use Piwik\Plugin; -use Piwik\Site; use Piwik\Db\Adapter; use Piwik\Db\Schema; +use Piwik\Log\ScreenFormatter; +use Piwik\Plugin; +use Piwik\Plugins\UsersManager\API; use Piwik\Session; -use Piwik\Tracker; use Piwik\Tracker\Cache; +use Piwik\Tracker; use Piwik\Tracker\GoalManager; -use Piwik\Url; -use Piwik\Plugins\UsersManager\API; use Piwik\View; -use Piwik\Log\ScreenFormatter; use Zend_Registry; /** @@ -1049,191 +1042,6 @@ class Piwik } /* - * Profiling - */ - - /** - * Get total number of queries - * - * @return int number of queries - */ - static public function getQueryCount() - { - $profiler = \Zend_Registry::get('db')->getProfiler(); - return $profiler->getTotalNumQueries(); - } - - /** - * Get total elapsed time (in seconds) - * - * @return int elapsed time - */ - static public function getDbElapsedSecs() - { - $profiler = \Zend_Registry::get('db')->getProfiler(); - return $profiler->getTotalElapsedSecs(); - } - - /** - * Print number of queries and elapsed time - */ - static public function printQueryCount() - { - $totalTime = self::getDbElapsedSecs(); - $queryCount = self::getQueryCount(); - Piwik::log(sprintf("Total queries = %d (total sql time = %.2fs)", $queryCount, $totalTime)); - } - - - static function maxSumMsFirst($a, $b) - { - return $a['sum_time_ms'] < $b['sum_time_ms']; - } - - /** - * Print profiling report for the tracker - * - * @param Db $db Tracker database object (or null) - */ - static public function printSqlProfilingReportTracker($db = null) - { - if (is_null($db)) { - $db = Tracker::getDatabase(); - } - $tableName = Common::prefixTable('log_profiling'); - - $all = $db->fetchAll('SELECT * FROM ' . $tableName); - if ($all === false) { - return; - } - uasort($all, 'self::maxSumMsFirst'); - - $infoIndexedByQuery = array(); - foreach ($all as $infoQuery) { - $query = $infoQuery['query']; - $count = $infoQuery['count']; - $sum_time_ms = $infoQuery['sum_time_ms']; - $infoIndexedByQuery[$query] = array('count' => $count, 'sumTimeMs' => $sum_time_ms); - } - Piwik::getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery); - } - - static private function sortTimeDesc($a, $b) - { - return $a['sumTimeMs'] < $b['sumTimeMs']; - } - - /** - * Outputs SQL Profiling reports - * It is automatically called when enabling the SQL profiling in the config file enable_sql_profiler - * - * @throws Exception - */ - static function printSqlProfilingReportZend() - { - $profiler = \Zend_Registry::get('db')->getProfiler(); - - if (!$profiler->getEnabled()) { - throw new Exception("To display the profiler you should enable enable_sql_profiler on your config/config.ini.php file"); - } - - $infoIndexedByQuery = array(); - foreach ($profiler->getQueryProfiles() as $query) { - if (isset($infoIndexedByQuery[$query->getQuery()])) { - $existing = $infoIndexedByQuery[$query->getQuery()]; - } else { - $existing = array('count' => 0, 'sumTimeMs' => 0); - } - $new = array('count' => $existing['count'] + 1, - 'sumTimeMs' => $existing['count'] + $query->getElapsedSecs() * 1000); - $infoIndexedByQuery[$query->getQuery()] = $new; - } - - uasort($infoIndexedByQuery, 'self::sortTimeDesc'); - - $str = '<hr /><strong>SQL Profiler</strong><hr /><strong>Summary</strong><br/>'; - $totalTime = $profiler->getTotalElapsedSecs(); - $queryCount = $profiler->getTotalNumQueries(); - $longestTime = 0; - $longestQuery = null; - foreach ($profiler->getQueryProfiles() as $query) { - if ($query->getElapsedSecs() > $longestTime) { - $longestTime = $query->getElapsedSecs(); - $longestQuery = $query->getQuery(); - } - } - $str .= 'Executed ' . $queryCount . ' queries in ' . round($totalTime, 3) . ' seconds'; - $str .= '(Average query length: ' . round($totalTime / $queryCount, 3) . ' seconds)'; - $str .= '<br />Queries per second: ' . round($queryCount / $totalTime, 1); - $str .= '<br />Longest query length: ' . round($longestTime, 3) . " seconds (<code>$longestQuery</code>)"; - Piwik::log($str); - Piwik::getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery); - } - - /** - * Log a breakdown by query - * - * @param array $infoIndexedByQuery - */ - static private function getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery) - { - $output = '<hr /><strong>Breakdown by query</strong><br/>'; - foreach ($infoIndexedByQuery as $query => $queryInfo) { - $timeMs = round($queryInfo['sumTimeMs'], 1); - $count = $queryInfo['count']; - $avgTimeString = ''; - if ($count > 1) { - $avgTimeMs = $timeMs / $count; - $avgTimeString = " (average = <b>" . round($avgTimeMs, 1) . "ms</b>)"; - } - $query = preg_replace('/([\t\n\r ]+)/', ' ', $query); - $output .= "Executed <b>$count</b> time" . ($count == 1 ? '' : 's') . " in <b>" . $timeMs . "ms</b> $avgTimeString <pre>\t$query</pre>"; - } - Piwik::log($output); - } - - /** - * Print timer - */ - static public function printTimer() - { - Piwik::log(Zend_Registry::get('timer')); - } - - /** - * Print memory leak - * - * @param string $prefix - * @param string $suffix - */ - static public function printMemoryLeak($prefix = '', $suffix = '<br />') - { - echo $prefix; - echo \Zend_Registry::get('timer')->getMemoryLeak(); - echo $suffix; - } - - /** - * Print memory usage - * - * @return string - */ - static public function getMemoryUsage() - { - $memory = false; - if (function_exists('xdebug_memory_usage')) { - $memory = xdebug_memory_usage(); - } elseif (function_exists('memory_get_usage')) { - $memory = memory_get_usage(); - } - if ($memory === false) { - return "Memory usage function not found."; - } - $usage = number_format(round($memory / 1024 / 1024, 2), 2); - return "$usage Mb"; - } - - /* * Amounts, Percentages, Currency, Time, Math Operations, and Pretty Printing */ @@ -1926,7 +1734,7 @@ class Piwik static public function disconnectDatabase() { \Zend_Registry::get('db')->closeConnection(); - } +} /** * Checks the database server version against the required minimum diff --git a/core/Profiler.php b/core/Profiler.php new file mode 100644 index 0000000000..fda2682782 --- /dev/null +++ b/core/Profiler.php @@ -0,0 +1,183 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + * @category Piwik + * @package Piwik + */ +namespace Piwik; + +/** + * Class Profiler helps with measuring memory, and profiling the database. + * To enable set in your config.ini.php + * [Debug] + * enable_sql_profiler = 1 + * + * [log] + * logger_message[]="screen" + * + * @package Piwik + */ +class Profiler +{ + /** + * Returns memory usage + * + * @return string + */ + public static function getMemoryUsage() + { + $memory = false; + if (function_exists('xdebug_memory_usage')) { + $memory = xdebug_memory_usage(); + } elseif (function_exists('memory_get_usage')) { + $memory = memory_get_usage(); + } + if ($memory === false) { + return "Memory usage function not found."; + } + $usage = number_format(round($memory / 1024 / 1024, 2), 2); + return "$usage Mb"; + } + + /** + * Outputs SQL Profiling reports from Zend + * + * @throws Exception + */ + public static function displayDbProfileReport() + { + $profiler = \Zend_Registry::get('db')->getProfiler(); + + if (!$profiler->getEnabled()) { + throw new Exception("To display the profiler you should enable enable_sql_profiler on your config/config.ini.php file"); + } + + $infoIndexedByQuery = array(); + foreach ($profiler->getQueryProfiles() as $query) { + if (isset($infoIndexedByQuery[$query->getQuery()])) { + $existing = $infoIndexedByQuery[$query->getQuery()]; + } else { + $existing = array('count' => 0, 'sumTimeMs' => 0); + } + $new = array('count' => $existing['count'] + 1, + 'sumTimeMs' => $existing['count'] + $query->getElapsedSecs() * 1000); + $infoIndexedByQuery[$query->getQuery()] = $new; + } + + uasort($infoIndexedByQuery, 'self::sortTimeDesc'); + + $str = '<hr /><strong>SQL Profiler</strong><hr /><strong>Summary</strong><br/>'; + $totalTime = $profiler->getTotalElapsedSecs(); + $queryCount = $profiler->getTotalNumQueries(); + $longestTime = 0; + $longestQuery = null; + foreach ($profiler->getQueryProfiles() as $query) { + if ($query->getElapsedSecs() > $longestTime) { + $longestTime = $query->getElapsedSecs(); + $longestQuery = $query->getQuery(); + } + } + $str .= 'Executed ' . $queryCount . ' queries in ' . round($totalTime, 3) . ' seconds'; + $str .= '(Average query length: ' . round($totalTime / $queryCount, 3) . ' seconds)'; + $str .= '<br />Queries per second: ' . round($queryCount / $totalTime, 1); + $str .= '<br />Longest query length: ' . round($longestTime, 3) . " seconds (<code>$longestQuery</code>)"; + Piwik::log($str); + self::getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery); + } + + private static function maxSumMsFirst($a, $b) + { + return $a['sum_time_ms'] < $b['sum_time_ms']; + } + + static private function sortTimeDesc($a, $b) + { + return $a['sumTimeMs'] < $b['sumTimeMs']; + } + + /** + * Print profiling report for the tracker + * + * @param \Piwik\Db $db Tracker database object (or null) + */ + public static function displayDbTrackerProfile($db = null) + { + if (is_null($db)) { + $db = Tracker::getDatabase(); + } + $tableName = Common::prefixTable('log_profiling'); + + $all = $db->fetchAll('SELECT * FROM ' . $tableName); + if ($all === false) { + return; + } + uasort($all, 'self::maxSumMsFirst'); + + $infoIndexedByQuery = array(); + foreach ($all as $infoQuery) { + $query = $infoQuery['query']; + $count = $infoQuery['count']; + $sum_time_ms = $infoQuery['sum_time_ms']; + $infoIndexedByQuery[$query] = array('count' => $count, 'sumTimeMs' => $sum_time_ms); + } + self::getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery); + } + + /** + * Print number of queries and elapsed time + */ + public static function printQueryCount() + { + $totalTime = self::getDbElapsedSecs(); + $queryCount = Profiler::getQueryCount(); + Piwik::log(sprintf("Total queries = %d (total sql time = %.2fs)", $queryCount, $totalTime)); + } + + /** + * Get total elapsed time (in seconds) + * + * @return int elapsed time + */ + public static function getDbElapsedSecs() + { + $profiler = \Zend_Registry::get('db')->getProfiler(); + return $profiler->getTotalElapsedSecs(); + } + + /** + * Get total number of queries + * + * @return int number of queries + */ + public static function getQueryCount() + { + $profiler = \Zend_Registry::get('db')->getProfiler(); + return $profiler->getTotalNumQueries(); + } + + /** + * Log a breakdown by query + * + * @param array $infoIndexedByQuery + */ + static private function getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery) + { + $output = '<hr /><strong>Breakdown by query</strong><br/>'; + foreach ($infoIndexedByQuery as $query => $queryInfo) { + $timeMs = round($queryInfo['sumTimeMs'], 1); + $count = $queryInfo['count']; + $avgTimeString = ''; + if ($count > 1) { + $avgTimeMs = $timeMs / $count; + $avgTimeString = " (average = <b>" . round($avgTimeMs, 1) . "ms</b>)"; + } + $query = preg_replace('/([\t\n\r ]+)/', ' ', $query); + $output .= "Executed <b>$count</b> time" . ($count == 1 ? '' : 's') . " in <b>" . $timeMs . "ms</b> $avgTimeString <pre>\t$query</pre>"; + } + Piwik::log($output); + } +}
\ No newline at end of file diff --git a/core/Tracker.php b/core/Tracker.php index a606627a0c..aafa2b9368 100644 --- a/core/Tracker.php +++ b/core/Tracker.php @@ -485,7 +485,7 @@ class Tracker if ($GLOBALS['PIWIK_TRACKER_DEBUG'] === true) { if (isset(self::$db)) { self::$db->recordProfiling(); - Piwik::printSqlProfilingReportTracker(self::$db); + Profiler::displayDbTrackerProfile(self::$db); } } diff --git a/core/Tracker/Db.php b/core/Tracker/Db.php index bfb92f34b5..6ba7737005 100644 --- a/core/Tracker/Db.php +++ b/core/Tracker/Db.php @@ -36,7 +36,7 @@ abstract class Db * Enables the SQL profiling. * For each query, saves in the DB the time spent on this query. * Very useful to see the slow query under heavy load. - * You can then use Piwik::printSqlProfilingReportTracker(); + * You can then use Piwik::displayDbTrackerProfile(); * to display the SQLProfiling report and see which queries take time, etc. */ public static function enableProfiling() diff --git a/core/View.php b/core/View.php index f4eca77395..fea23de6ac 100644 --- a/core/View.php +++ b/core/View.php @@ -11,15 +11,6 @@ namespace Piwik; use Exception; -use Piwik\Config; -use Piwik\Piwik; -use Piwik\Common; -use Piwik\AssetManager; -use Piwik\Version; -use Piwik\Url; -use Piwik\UpdateCheck; -use Piwik\Twig; -use Piwik\QuickForm2; use Piwik\Plugins\SitesManager\API as SitesManagerAPI; use Piwik\Plugins\UsersManager\API as UsersManagerAPI; use Piwik\View\ViewInterface; @@ -138,7 +129,7 @@ class View implements ViewInterface try { $this->totalTimeGeneration = \Zend_Registry::get('timer')->getTime(); - $this->totalNumberOfQueries = Piwik::getQueryCount(); + $this->totalNumberOfQueries = Profiler::getQueryCount(); } catch (Exception $e) { $this->totalNumberOfQueries = 0; } diff --git a/plugins/API/Controller.php b/plugins/API/Controller.php index 5c391425aa..c5793174ac 100644 --- a/plugins/API/Controller.php +++ b/plugins/API/Controller.php @@ -15,7 +15,6 @@ use Piwik\API\Request; use Piwik\API\Proxy; use Piwik\Config; use Piwik\Common; -use Piwik\Plugins\API\API; use Piwik\View; /** |