Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f13280c
Implement Feature #31087: Add SQL queries profiler in Debug zone with…
beat Jun 4, 2013
77ad11c
Fixed CSS styling of hovers
beat Jun 4, 2013
699b2eb
Made hover on query instead of timing so that both query and EXPLAIN …
beat Jun 5, 2013
0426c38
Added within-query profiling hover, removed need to reopen database b…
beat Jun 5, 2013
e5fab16
Applied patch from nonumber for Bootstrap-styling, before review
beat Jun 12, 2013
853de5a
Improved bootstrap-styling to show time-line instead of vu-meter, and…
beat Jun 12, 2013
112f35b
Generated links using xdebug.file_link_format (Thanks @elkuku for thi…
beat Jun 12, 2013
0b3544d
Changed bar graph to show entire timeline and arrow.
Jun 13, 2013
3ce3e7f
Fixed some syntax
Jun 13, 2013
08a8707
Spaces and non-spaces code-styling fixes (Thanks @nonumber)
beat Jun 13, 2013
04bbeb6
Putting @nonumber latest one into nonumber-debug temporary branch
beat Jun 14, 2013
0157ecb
Moved link for config link format into popover and clarified instruct…
beat Jun 14, 2013
d7327f0
Switched to accordions for Explain and call stacks, added helpful too…
beat Jun 14, 2013
90ed84a
Changed layout of accordions.
Jun 15, 2013
342a01c
Merge pull request #2 from nonumber/debug
beat Jun 15, 2013
962a831
Changed query bars.
Jun 16, 2013
3c101fe
Fixed some code styling
Jun 16, 2013
601aff2
Added duplicate query check.
Jun 16, 2013
e1a93f9
Added coloring to total query time labels.
Jun 16, 2013
7da51e5
Fixed diff in total render time calculation (used for coloring total …
Jun 16, 2013
e3c4037
Added duplicates message and overview to top of Queries list.
Jun 16, 2013
49fa229
Oops, forgot language strings
Jun 16, 2013
e4ead02
Merge pull request #3 from nonumber/debug
beat Jun 16, 2013
e806b6c
Updated branch with latest joomla/joomla-cms master
beat Jun 26, 2013
fb3a471
Updating branch with latest joomla/joomla-cms master: Fixed indents t…
beat Jun 26, 2013
148d6d9
Updating branch with latest joomla/joomla-cms master: Re-merged alrea…
beat Jun 26, 2013
921471a
Fixed language issue with double translations, added an untranslated …
beat Jun 26, 2013
ffe751c
Merge remote-tracking branch 'upstream/master' into mysqlprofiling
beat Jun 26, 2013
cb4b044
Cosmetic Spacing fix
beat Jun 26, 2013
d2937a9
Changed tooltip text to use tooltipText method
Jun 26, 2013
0997231
Merge pull request #4 from nonumber/mysqlprofiling
beat Jun 26, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions administrator/language/en-GB/en-GB.plg_system_debug.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
; Note : All ini files need to be saved as UTF-8 - No BOM

PLG_DEBUG_BYTES="Bytes"
PLG_DEBUG_CALL_STACK="Call Stack"
PLG_DEBUG_ERRORS="Errors"
PLG_DEBUG_EXPLAIN="Explain"
PLG_DEBUG_FIELD_ALLOWED_GROUPS_DESC="Optionally restrict users that can see debug information to those in the selected user groups. If none selected, all users see the debug information."
PLG_DEBUG_FIELD_ALLOWED_GROUPS_LABEL="Allowed Groups"
PLG_DEBUG_FIELD_LANGUAGE_ERRORFILES_DESC="Display a list of the language files that are in error according to the Joomla ini specification."
Expand All @@ -12,6 +15,8 @@ PLG_DEBUG_FIELD_LANGUAGE_FILES_DESC="Display a list of the language files that J
PLG_DEBUG_FIELD_LANGUAGE_FILES_LABEL="Show Language Files"
PLG_DEBUG_FIELD_LANGUAGE_STRING_DESC="Display a list of the untranslated language strings."
PLG_DEBUG_FIELD_LANGUAGE_STRING_LABEL="Show Language String"
PLG_DEBUG_FIELD_LOGS_DESC="Display a list of logged messages."
PLG_DEBUG_FIELD_LOGS_LABEL="Show Log Entries"
PLG_DEBUG_FIELD_LOG_CATEGORIES_DESC="A comma separated list of log categories to include. Common log categories include but are not limited to: database, databasequery, deprecated, and jerror. If empty, all categories will be shown."
PLG_DEBUG_FIELD_LOG_CATEGORIES_LABEL="Log Categories"
PLG_DEBUG_FIELD_LOG_CATEGORY_MODE_DESC="Select whether the listed categories should be included or excluded."
Expand All @@ -31,8 +36,6 @@ PLG_DEBUG_FIELD_LOG_PRIORITIES_INFO="Info"
PLG_DEBUG_FIELD_LOG_PRIORITIES_LABEL="Log Priorities"
PLG_DEBUG_FIELD_LOG_PRIORITIES_NOTICE="Notice"
PLG_DEBUG_FIELD_LOG_PRIORITIES_WARNING="Warning"
PLG_DEBUG_FIELD_LOGS_DESC="Display a list of logged messages."
PLG_DEBUG_FIELD_LOGS_LABEL="Show Log Entries"
PLG_DEBUG_FIELD_MEMORY_DESC="Display the total memory usage."
PLG_DEBUG_FIELD_MEMORY_LABEL="Show Memory Usage"
PLG_DEBUG_FIELD_PROFILING_DESC="Display the profiling waypoints."
Expand All @@ -47,24 +50,43 @@ PLG_DEBUG_FIELD_STRIP_PREFIX_DESC="Strip words from the beginning of the string.
PLG_DEBUG_FIELD_STRIP_PREFIX_LABEL="Strip From Start"
PLG_DEBUG_FIELD_STRIP_SUFFIX_DESC="Strip words from the end of the string. For multiple words, use the format: (word1|word2)"
PLG_DEBUG_FIELD_STRIP_SUFFIX_LABEL="Strip From End"
PLG_DEBUG_LANG_LOADED="Loaded"
PLG_DEBUG_LANG_NOT_LOADED="Not loaded"
PLG_DEBUG_LANGUAGE_FIELDSET_LABEL="Language Options"
PLG_DEBUG_LANGUAGE_FILES_IN_ERROR="Parsing errors in language files"
PLG_DEBUG_LANGUAGE_FILES_LOADED="Language Files Loaded"
PLG_DEBUG_LANG_LOADED="Loaded"
PLG_DEBUG_LANG_NOT_LOADED="Not loaded"
PLG_DEBUG_LINK_FORMAT="Add xdebug.file_link_format directive to your php.ini file to have links for files"
PLG_DEBUG_LOGGING_FIELDSET_LABEL="Logging"
PLG_DEBUG_LOGS="Log Messages"
PLG_DEBUG_MEMORY="Memory"
PLG_DEBUG_MEMORY_USED_FOR_QUERY="Query memory: %s Memory before query: %s"
PLG_DEBUG_MEMORY_USAGE="Memory Usage"
PLG_DEBUG_NO_PROFILE="No SHOW PROFILE (maybe because there are more than 100 queries)"
PLG_DEBUG_OTHER_QUERIES="OTHER Tables:"
PLG_DEBUG_PROFILE="Profile"
PLG_DEBUG_PROFILE_INFORMATION="Profile Information"
PLG_DEBUG_QUERIES="Database Queries"
PLG_DEBUG_QUERIES_LOGGED="%d Queries Logged"
PLG_DEBUG_QUERIES_TIME="Database queries total: %s"
PLG_DEBUG_QUERY_AFTER_LAST="After last query: %s"
PLG_DEBUG_QUERY_DUPLICATES="Duplicate queries"
PLG_DEBUG_QUERY_DUPLICATES_FOUND="Duplicate found!"
PLG_DEBUG_QUERY_DUPLICATES_NUMBER="%s duplicates"
PLG_DEBUG_QUERY_DUPLICATES_TOTAL_NUMBER="%s duplicate found!"
PLG_DEBUG_QUERY_EXPLAIN_NOT_POSSIBLE="EXPLAIN not possible on query: %s"
PLG_DEBUG_QUERY_TIME="Query Time: %s"
PLG_DEBUG_QUERY_TYPES_LOGGED="%d Query Types Logged, Sorted by Occurrences."
PLG_DEBUG_QUERY_TYPE_AND_OCCURRENCES="%2$d × %1$s"
PLG_DEBUG_ROWS_RETURNED_BY_QUERY="Rows returned: %s"
PLG_DEBUG_SELECT_QUERIES="SELECT Tables:"
PLG_DEBUG_SESSION="Session"
PLG_DEBUG_TIME="Time"
PLG_DEBUG_TITLE="Joomla! Debug Console"
PLG_DEBUG_UNKNOWN_FILE="Unknown file"
PLG_DEBUG_UNTRANSLATED_STRINGS="Untranslated Strings"
PLG_DEBUG_WARNING_NO_INDEX="NO INDEX KEY COULD BE USED"
PLG_DEBUG_WARNING_NO_INDEX_DESC="This table has probably a missing index on WHERE equalities and/or JOIN ON column(s) or is written in a way that no index can be used, causing a time-consuming full table scan"
PLG_DEBUG_WARNING_USING_FILESORT="Using filesort"
PLG_DEBUG_WARNING_USING_FILESORT_DESC="This table has probably a missing index on WHERE/ON equality column(s) ending by the ORDER BY column(s) or is written in a way that no index can be used, causing a time-consuming filesort."
PLG_DEBUG_XML_DESCRIPTION="This plugin provides a variety of system information as well as assistance for the creation of translation files."
PLG_SYSTEM_DEBUG="System - Debug"
56 changes: 56 additions & 0 deletions libraries/joomla/database/driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,19 @@ abstract class JDatabaseDriver extends JDatabase implements JDatabaseInterface
*/
protected $log = array();

/**
* @var array The log of executed SQL statements timings (start and stop microtimes) by the database driver.
* @since CMS 3.1.2
*/
protected $timings = array();


/**
* @var array The log of executed SQL statements timings (start and stop microtimes) by the database driver.
* @since CMS 3.1.2
*/
protected $callStacks = array();

/**
* @var string The character(s) used to quote SQL statement names such as table names or field names,
* etc. The child classes should define this as necessary. If a single character string the
Expand Down Expand Up @@ -170,6 +183,12 @@ abstract class JDatabaseDriver extends JDatabase implements JDatabaseInterface
*/
protected $transactionDepth = 0;

/**
* @var callable[] List of callables to call just before disconnecting database
* @since CMS 3.1.2
*/
protected $disconnectHandlers = array();

/**
* Get a list of available database connectors. The list will only be populated with connectors that both
* the class exists and the static test method returns true. This gives us the ability to have a multitude
Expand Down Expand Up @@ -464,6 +483,19 @@ public function createDatabase($options, $utf = true)
*/
abstract public function disconnect();

/**
* Adds a function callable just before disconnecting the database. Parameter of the callable is $this JDatabaseDriver
*
* @param callable $callable Function to call in disconnect() method just before disconnecting from database
* @return void
*
* @since CMS 3.1.2
*/
public function addDisconnectHandler($callable)
{
$this->disconnectHandlers[] = $callable;
}

/**
* Drops a table from the database.
*
Expand Down Expand Up @@ -648,6 +680,30 @@ public function getLog()
return $this->log;
}

/**
* Get the database driver SQL statement log.
*
* @return array SQL statements executed by the database driver.
*
* @since CMS 3.1.2
*/
public function getTimings()
{
return $this->timings;
}

/**
* Get the database driver SQL statement log.
*
* @return array SQL statements executed by the database driver.
*
* @since CMS 3.1.2
*/
public function getCallStacks()
{
return $this->callStacks;
}

/**
* Get the minimum supported database version.
*
Expand Down
37 changes: 28 additions & 9 deletions libraries/joomla/database/driver/mysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ public function __construct($options)
*/
public function __destruct()
{
if (is_resource($this->connection))
{
mysql_close($this->connection);
}
$this->disconnect();
}

/**
Expand Down Expand Up @@ -98,6 +95,12 @@ public function connect()

// Set charactersets (needed for MySQL 4.1.2+).
$this->setUTF();

// Turn MySQL profiling ON in debug mode:
if ($this->debug)
{
mysqli_query($this->connection, "SET profiling = 1;");
}
}

/**
Expand All @@ -110,7 +113,15 @@ public function connect()
public function disconnect()
{
// Close the connection.
mysql_close($this->connection);
if (is_resource($this->connection))
{
foreach ($this->disconnectHandlers as $h)
{
call_user_func_array($h, array( &$this));
}

mysql_close($this->connection);
}

$this->connection = null;
}
Expand Down Expand Up @@ -254,22 +265,30 @@ public function execute()
// Increment the query counter.
$this->count++;

// Reset the error values.
$this->errorNum = 0;
$this->errorMsg = '';

// If debugging is enabled then let's log the query.
if ($this->debug)
{
// Add the query to the object queue.
$this->log[] = $query;

JLog::add($query, JLog::DEBUG, 'databasequery');
}

// Reset the error values.
$this->errorNum = 0;
$this->errorMsg = '';
$this->timings[] = microtime(true);
}

// Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost.
$this->cursor = @mysql_query($query, $this->connection);

if ($this->debug)
{
$this->timings[] = microtime(true);
$this->callStacks[] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
}

// If an error occurred handle it.
if (!$this->cursor)
{
Expand Down
47 changes: 38 additions & 9 deletions libraries/joomla/database/driver/mysqli.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,7 @@ public function __construct($options)
*/
public function __destruct()
{
if (is_callable(array($this->connection, 'close')))
{
mysqli_close($this->connection);
}
$this->disconnect();
}

/**
Expand Down Expand Up @@ -157,6 +154,13 @@ public function connect()

// Set charactersets (needed for MySQL 4.1.2+).
$this->setUTF();

// Turn MySQL profiling ON in debug mode:
if ($this->debug)
{
mysqli_query($this->connection, "SET profiling_history_size = 100;");
mysqli_query($this->connection, "SET profiling = 1;");
}
}

/**
Expand All @@ -169,8 +173,13 @@ public function connect()
public function disconnect()
{
// Close the connection.
if (is_callable($this->connection, 'close'))
if ($this->connection)
{
foreach ($this->disconnectHandlers as $h)
{
call_user_func_array($h, array( &$this));
}

mysqli_close($this->connection);
}

Expand Down Expand Up @@ -496,22 +505,38 @@ public function execute()
// Increment the query counter.
$this->count++;

// Reset the error values.
$this->errorNum = 0;
$this->errorMsg = '';
$memoryBefore = null;

// If debugging is enabled then let's log the query.
if ($this->debug)
{
// Add the query to the object queue.
$this->log[] = $query;

JLog::add($query, JLog::DEBUG, 'databasequery');
}

// Reset the error values.
$this->errorNum = 0;
$this->errorMsg = '';
$this->timings[] = microtime(true);

if (is_object($this->cursor))
{
$this->freeResult();
}
$memoryBefore = memory_get_usage();
}

// Execute the query. Error suppression is used here to prevent warnings/notices that the connection has been lost.
$this->cursor = @mysqli_query($this->connection, $query);

if ($this->debug)
{
$this->timings[] = microtime(true);
$this->callStacks[] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$this->callStacks[count($this->callStacks) - 1][0]['memory'] = array($memoryBefore, memory_get_usage(), is_object($this->cursor) ? $this->getNumRows() : null);
}

// If an error occurred handle it.
if (!$this->cursor)
{
Expand Down Expand Up @@ -757,6 +782,10 @@ protected function fetchObject($cursor = null, $class = 'stdClass')
protected function freeResult($cursor = null)
{
mysqli_free_result($cursor ? $cursor : $this->cursor);
if ((! $cursor) || ($cursor === $this->cursor))
{
$this->cursor = null;
}
}

/**
Expand Down
24 changes: 18 additions & 6 deletions libraries/joomla/database/driver/pdo.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ public function __construct($options)
*/
public function __destruct()
{
$this->freeResult();
unset($this->connection);
$this->disconnect();
}

/**
Expand Down Expand Up @@ -307,6 +306,11 @@ public function connect()
*/
public function disconnect()
{
foreach ($this->disconnectHandlers as $h)
{
call_user_func_array($h, array( &$this));
}

$this->freeResult();
unset($this->connection);
}
Expand Down Expand Up @@ -374,18 +378,20 @@ public function execute()
// Increment the query counter.
$this->count++;

// Reset the error values.
$this->errorNum = 0;
$this->errorMsg = '';

// If debugging is enabled then let's log the query.
if ($this->debug)
{
// Add the query to the object queue.
$this->log[] = $query;

JLog::add($query, JLog::DEBUG, 'databasequery');
}

// Reset the error values.
$this->errorNum = 0;
$this->errorMsg = '';
$this->timings[] = microtime(true);
}

// Execute the query.
$this->executed = false;
Expand All @@ -404,6 +410,12 @@ public function execute()
$this->executed = $this->prepared->execute();
}

if ($this->debug)
{
$this->timings[] = microtime(true);
$this->callStacks[] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
}

// If an error occurred handle it.
if (!$this->executed)
{
Expand Down
Loading