Index: database/database.mysql =================================================================== RCS file: /cvs/drupal/drupal/database/database.mysql,v retrieving revision 1.186 diff -u -r1.186 database.mysql --- database/database.mysql 10 May 2005 20:48:31 -0000 1.186 +++ database/database.mysql 11 May 2005 19:57:56 -0000 @@ -26,6 +26,7 @@ url varchar(255) default NULL, hostname varchar(128) default NULL, uid int(10) unsigned default '0', + timer int(10) unsigned NOT NULL default '0', timestamp int(11) unsigned NOT NULL default '0', KEY accesslog_timestamp (timestamp), PRIMARY KEY (aid) Index: database/database.pgsql =================================================================== RCS file: /cvs/drupal/drupal/database/database.pgsql,v retrieving revision 1.123 diff -u -r1.123 database.pgsql --- database/database.pgsql 10 May 2005 20:48:32 -0000 1.123 +++ database/database.pgsql 11 May 2005 19:57:56 -0000 @@ -25,6 +25,7 @@ url varchar(255) default NULL, hostname varchar(128) default NULL, uid integer default '0', + timer integer NOT NULL default '0', timestamp integer NOT NULL default '0', PRIMARY KEY (aid) ); Index: database/updates.inc =================================================================== RCS file: /cvs/drupal/drupal/database/updates.inc,v retrieving revision 1.117 diff -u -r1.117 updates.inc --- database/updates.inc 10 May 2005 20:48:32 -0000 1.117 +++ database/updates.inc 11 May 2005 19:57:59 -0000 @@ -114,7 +114,8 @@ "2005-05-06" => "update_135", "2005-05-08" => "update_136", "2005-05-09" => "update_137", - "2005-05-10" => "update_138" + "2005-05-10" => "update_138", + "2005-05-11" => "update_139" ); function update_32() { @@ -2482,6 +2483,12 @@ return $ret; } +function update_139() { + $ret = array(); + $ret[] = update_sql("ALTER TABLE {accesslog} ADD timer int(10) unsigned NOT NULL default '0'"); + return $ret; +} + function update_sql($sql) { $edit = $_POST["edit"]; $result = db_query($sql); Index: includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.46 diff -u -r1.46 bootstrap.inc --- includes/bootstrap.inc 12 Apr 2005 16:55:11 -0000 1.46 +++ includes/bootstrap.inc 11 May 2005 19:58:00 -0000 @@ -17,6 +17,63 @@ define('WATCHDOG_WARNING', 1); define('WATCHDOG_ERROR', 2); +/** + * Start the timer with the specified name. If you start and stop + * the same timer multiple times, the measured intervals will be + * accumulated. + * + * @param name + * The name of the timer. + */ +function timer_start($name) { + global $timers; + + list($usec, $sec) = explode(' ', microtime()); + $timers[$name]['start'] = (float)$usec + (float)$sec; + $timers[$name]['count']++; +} + +/** + * Read the current timer value without stopping the timer. + * + * @param name + * The name of the timer. + * @return + * The current timer value in ms. + */ +function timer_read($name) { + global $timers; + + list($usec, $sec) = explode(' ', microtime()); + $stop = (float)$usec + (float)$sec; + $diff = round(($stop - $timers[$name]['start']) * 1000, 2); + + return $timers[$name]['time'] + $diff; +} + +/** + * Stop the timer with the specified name. + * + * @param name + * The name of the timer. + * @return + * A timer array. The array contains the number of times the + * timer has been started and stopped (count) and the accumulated + * timer value in ms (time). + */ +function timer_stop($name) { + global $timers; + + list($usec, $sec) = explode(' ', microtime()); + $stop = (float)$usec + (float)$sec; + $diff = round(($stop - $timers[$name]['start']) * 1000, 2); + + $timers[$name]['time'] += $diff; + + unset($timers[$name]['start']); + + return $timers[$name]; +} /** * Locate the appropriate configuration file. @@ -171,8 +228,11 @@ function variable_set($name, $value) { global $conf; + db_query('LOCK TABLES {variable} WRITE'); db_query("DELETE FROM {variable} WHERE name = '%s'", $name); db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, serialize($value)); + db_query('UNLOCK TABLES'); + cache_clear_all('variables'); $conf[$name] = $value; @@ -255,10 +315,12 @@ function cache_set($cid, $data, $expire = CACHE_PERMANENT, $headers = NULL) { $data = db_encode_blob($data); + db_query('LOCK TABLES {cache} WRITE'); db_query("UPDATE {cache} SET data = '%s', created = %d, expire = %d, headers = '%s' WHERE cid = '%s'", $data, time(), $expire, $headers, $cid); if (!db_affected_rows()) { @db_query("INSERT INTO {cache} (cid, data, created, expire, headers) VALUES ('%s', '%s', %d, %d, '%s')", $cid, $data, time(), $expire, $headers); } + db_query('UNLOCK TABLES'); } /** @@ -471,9 +533,7 @@ * Set HTTP headers in preparation for a page response. */ function drupal_page_header() { - if (variable_get('dev_timer', 0)) { - timer_start(); - } + timer_start('page'); if (variable_get('cache', 0)) { if ($cache = page_get_cache()) { @@ -626,15 +686,6 @@ } /** - * Begin a global timer, for benchmarking of page execution time. - */ -function timer_start() { - global $timer; - list($usec, $sec) = explode(' ', microtime()); - $timer = (float)$usec + (float)$sec; -} - -/** * Log a system message. * * @param $type Index: modules/statistics.module =================================================================== RCS file: /cvs/drupal/drupal/modules/statistics.module,v retrieving revision 1.190 diff -u -r1.190 statistics.module --- modules/statistics.module 7 May 2005 21:53:20 -0000 1.190 +++ modules/statistics.module 11 May 2005 19:58:32 -0000 @@ -71,12 +71,8 @@ } } if ((variable_get('statistics_enable_access_log', 0)) && (module_invoke('throttle', 'status') == 0)) { - // Statistical logs are enabled. - $referrer = referer_uri(); - $hostname = $_SERVER['REMOTE_ADDR']; - // Log this page access. - db_query("INSERT INTO {accesslog} (title, path, url, hostname, uid, timestamp) values('%s', '%s', '%s', '%s', %d, %d)", drupal_get_title(), $_GET['q'], $referrer, $hostname, $user->uid, time()); + db_query("INSERT INTO {accesslog} (title, path, url, hostname, uid, timer, timestamp) values('%s', '%s', '%s', '%s', %d, %d, %d)", drupal_get_title(), $_GET['q'], referer_uri(), $_SERVER['REMOTE_ADDR'], $user->uid, timer_read('page'), time()); } } @@ -220,7 +216,7 @@ } /** - * Menu callback; presents the "Recent hits" page. + * Menu callback; presents the "recent hits" page. */ function statistics_recent_hits($type = 'all', $id = 0) { $header = array( @@ -249,24 +245,27 @@ } /** - * Menu callback; presents the "Top pages" page. + * Menu callback; presents the "top pages" page. */ function statistics_top_pages() { - $sql = "SELECT COUNT(path) AS hits, path, title FROM {accesslog} GROUP BY path, title"; + $sql = "SELECT COUNT(path) AS hits, path, title, AVG(timer) AS average_time, SUM(timer) AS total_time FROM {accesslog} GROUP BY path, title"; $sql_cnt = "SELECT COUNT(DISTINCT(path)) FROM {accesslog}"; $header = array( array('data' => t('Hits'), 'field' => 'hits', 'sort' => 'desc'), - array('data' => t('Page'), 'field' => 'path') + array('data' => t('Page'), 'field' => 'path'), + array('data' => t('Average time'), 'field' => 'average_time'), + array('data' => t('Total time'), 'field' => 'total_time') ); $sql .= tablesort_sql($header); $result = pager_query($sql, 30, 0, $sql_cnt); while ($page = db_fetch_object($result)) { - $rows[] = array($page->hits, _statistics_format_item($page->title, $page->path)); + $rows[] = array($page->hits, _statistics_format_item($page->title, $page->path), t('%time ms', array('%time' => round($page->average_time))), format_interval(round($page->total_time / 1000))); } + if ($pager = theme('pager', NULL, 30, 0, tablesort_pager())) { - $rows[] = array(array('data' => $pager, 'colspan' => '2')); + $rows[] = array(array('data' => $pager, 'colspan' => '4')); } drupal_set_title(t('Top pages in the past %interval', array('%interval' => format_interval(variable_get('statistics_flush_accesslog_timer', 259200))))); @@ -274,7 +273,7 @@ } /** - * Menu callback; presents the "Top users" page. + * Menu callback; presents the "top users" page. */ function statistics_top_users() { @@ -300,7 +299,7 @@ } /** - * Menu callback; presents the "Top referrers" page. + * Menu callback; presents the "referrer" page. */ function statistics_top_referrers() { $query = "SELECT url, COUNT(url) AS hits, MAX(timestamp) AS last FROM {accesslog} WHERE url NOT LIKE '%%%s%%' AND url <> '' GROUP BY url";