Merge branch '0.9.x' of git@gitorious.org:statusnet/mainline into 0.9.x

This commit is contained in:
Sarven Capadisli 2010-03-31 11:00:22 +02:00
commit 89bb053116
4 changed files with 82 additions and 10 deletions

View File

@ -330,6 +330,10 @@ class Memcached_DataObject extends Safe_DataObject
*/ */
function _query($string) function _query($string)
{ {
if (common_config('db', 'annotate_queries')) {
$string = $this->annotateQuery($string);
}
$start = microtime(true); $start = microtime(true);
$result = parent::_query($string); $result = parent::_query($string);
$delta = microtime(true) - $start; $delta = microtime(true) - $start;
@ -342,6 +346,70 @@ class Memcached_DataObject extends Safe_DataObject
return $result; return $result;
} }
/**
* Find the first caller in the stack trace that's not a
* low-level database function and add a comment to the
* query string. This should then be visible in process lists
* and slow query logs, to help identify problem areas.
*
* Also marks whether this was a web GET/POST or which daemon
* was running it.
*
* @param string $string SQL query string
* @return string SQL query string, with a comment in it
*/
function annotateQuery($string)
{
$ignore = array('annotateQuery',
'_query',
'query',
'get',
'insert',
'delete',
'update',
'find');
$ignoreStatic = array('staticGet',
'pkeyGet',
'cachedQuery');
$here = get_class($this); // if we get confused
$bt = debug_backtrace();
// Find the first caller that's not us?
foreach ($bt as $frame) {
$func = $frame['function'];
if (isset($frame['type']) && $frame['type'] == '::') {
if (in_array($func, $ignoreStatic)) {
continue;
}
$here = $frame['class'] . '::' . $func;
break;
} else if (isset($frame['type']) && $frame['type'] == '->') {
if ($frame['object'] === $this && in_array($func, $ignore)) {
continue;
}
if (in_array($func, $ignoreStatic)) {
continue; // @fixme this shouldn't be needed?
}
$here = get_class($frame['object']) . '->' . $func;
break;
}
$here = $func;
break;
}
if (php_sapi_name() == 'cli') {
$context = basename($_SERVER['PHP_SELF']);
} else {
$context = $_SERVER['REQUEST_METHOD'];
}
// Slip the comment in after the first command,
// or DB_DataObject gets confused about handling inserts and such.
$parts = explode(' ', $string, 2);
$parts[0] .= " /* $context $here */";
return implode(' ', $parts);
}
// Sanitize a query for logging // Sanitize a query for logging
// @fixme don't trim spaces in string literals // @fixme don't trim spaces in string literals
function sanitizeQuery($string) function sanitizeQuery($string)

View File

@ -72,6 +72,7 @@ $default =
'quote_identifiers' => false, 'quote_identifiers' => false,
'type' => 'mysql', 'type' => 'mysql',
'schemacheck' => 'runtime', // 'runtime' or 'script' 'schemacheck' => 'runtime', // 'runtime' or 'script'
'annotate_queries' => false, // true to add caller comments to queries, eg /* POST Notice::saveNew */
'log_queries' => false, // true to log all DB queries 'log_queries' => false, // true to log all DB queries
'log_slow_queries' => 0), // if set, log queries taking over N seconds 'log_slow_queries' => 0), // if set, log queries taking over N seconds
'syslog' => 'syslog' =>

View File

@ -44,6 +44,9 @@ require_once 'HTTP/Request2/Response.php';
* This extends the HTTP_Request2_Response class with methods to get info * This extends the HTTP_Request2_Response class with methods to get info
* about any followed redirects. * about any followed redirects.
* *
* Originally used the name 'HTTPResponse' to match earlier code, but
* this conflicts with a class in in the PECL HTTP extension.
*
* @category HTTP * @category HTTP
* @package StatusNet * @package StatusNet
* @author Evan Prodromou <evan@status.net> * @author Evan Prodromou <evan@status.net>
@ -51,7 +54,7 @@ require_once 'HTTP/Request2/Response.php';
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class HTTPResponse extends HTTP_Request2_Response class StatusNet_HTTPResponse extends HTTP_Request2_Response
{ {
function __construct(HTTP_Request2_Response $response, $url, $redirects=0) function __construct(HTTP_Request2_Response $response, $url, $redirects=0)
{ {
@ -146,7 +149,7 @@ class HTTPClient extends HTTP_Request2
/** /**
* Convenience function to run a GET request. * Convenience function to run a GET request.
* *
* @return HTTPResponse * @return StatusNet_HTTPResponse
* @throws HTTP_Request2_Exception * @throws HTTP_Request2_Exception
*/ */
public function get($url, $headers=array()) public function get($url, $headers=array())
@ -157,7 +160,7 @@ class HTTPClient extends HTTP_Request2
/** /**
* Convenience function to run a HEAD request. * Convenience function to run a HEAD request.
* *
* @return HTTPResponse * @return StatusNet_HTTPResponse
* @throws HTTP_Request2_Exception * @throws HTTP_Request2_Exception
*/ */
public function head($url, $headers=array()) public function head($url, $headers=array())
@ -171,7 +174,7 @@ class HTTPClient extends HTTP_Request2
* @param string $url * @param string $url
* @param array $headers optional associative array of HTTP headers * @param array $headers optional associative array of HTTP headers
* @param array $data optional associative array or blob of form data to submit * @param array $data optional associative array or blob of form data to submit
* @return HTTPResponse * @return StatusNet_HTTPResponse
* @throws HTTP_Request2_Exception * @throws HTTP_Request2_Exception
*/ */
public function post($url, $headers=array(), $data=array()) public function post($url, $headers=array(), $data=array())
@ -183,7 +186,7 @@ class HTTPClient extends HTTP_Request2
} }
/** /**
* @return HTTPResponse * @return StatusNet_HTTPResponse
* @throws HTTP_Request2_Exception * @throws HTTP_Request2_Exception
*/ */
protected function doRequest($url, $method, $headers) protected function doRequest($url, $method, $headers)
@ -217,12 +220,12 @@ class HTTPClient extends HTTP_Request2
} }
/** /**
* Actually performs the HTTP request and returns an HTTPResponse object * Actually performs the HTTP request and returns a
* with response body and header info. * StatusNet_HTTPResponse object with response body and header info.
* *
* Wraps around parent send() to add logging and redirection processing. * Wraps around parent send() to add logging and redirection processing.
* *
* @return HTTPResponse * @return StatusNet_HTTPResponse
* @throw HTTP_Request2_Exception * @throw HTTP_Request2_Exception
*/ */
public function send() public function send()
@ -265,6 +268,6 @@ class HTTPClient extends HTTP_Request2
} }
break; break;
} while ($maxRedirs); } while ($maxRedirs);
return new HTTPResponse($response, $this->getUrl(), $redirs); return new StatusNet_HTTPResponse($response, $this->getUrl(), $redirs);
} }
} }

View File

@ -130,7 +130,7 @@ RealtimeUpdate = {
user = data['user']; user = data['user'];
html = data['html'].replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&quot;/g,'"').replace(/&amp;/g,'&'); html = data['html'].replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&quot;/g,'"').replace(/&amp;/g,'&');
source = data['source'].replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&quot;/g,'"').replace(/&amp;/g,'&'); source = data['source'].replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&quot;/g,'"').replace(/&amp;/g,'&');
console.log(data);
ni = "<li class=\"hentry notice\" id=\"notice-"+unique+"\">"+ ni = "<li class=\"hentry notice\" id=\"notice-"+unique+"\">"+
"<div class=\"entry-title\">"+ "<div class=\"entry-title\">"+
"<span class=\"vcard author\">"+ "<span class=\"vcard author\">"+