Added ability to search by time when using the profiler

This commit is contained in:
Florin Patan 2012-11-25 19:16:08 +02:00
parent f9297c103e
commit 3a0ed584df
13 changed files with 142 additions and 27 deletions

View File

@ -224,12 +224,16 @@ class ProfilerController
$ip =
$method =
$url =
$start =
$end =
$limit =
$token = null;
} else {
$ip = $session->get('_profiler_search_ip');
$method = $session->get('_profiler_search_method');
$url = $session->get('_profiler_search_url');
$start = $session->get('_profiler_search_start');
$end = $session->get('_profiler_search_end');
$limit = $session->get('_profiler_search_limit');
$token = $session->get('_profiler_search_token');
}
@ -239,6 +243,8 @@ class ProfilerController
'ip' => $ip,
'method' => $method,
'url' => $url,
'start' => $start,
'end' => $end,
'limit' => $limit,
)));
}
@ -260,17 +266,21 @@ class ProfilerController
$ip = $request->query->get('ip');
$method = $request->query->get('method');
$url = $request->query->get('url');
$start = $request->query->get('start');
$end = $request->query->get('end');
$limit = $request->query->get('limit');
return new Response($this->twig->render('@WebProfiler/Profiler/results.html.twig', array(
'token' => $token,
'profile' => $profile,
'tokens' => $this->profiler->find($ip, $url, $limit, $method),
'ip' => $ip,
'method' => $method,
'url' => $url,
'limit' => $limit,
'panel' => null,
'token' => $token,
'profile' => $profile,
'tokens' => $this->profiler->find($ip, $url, $start, $end, $limit, $method),
'ip' => $ip,
'method' => $method,
'url' => $url,
'start' => $start,
'end' => $end,
'limit' => $limit,
'panel' => null,
)));
}
@ -288,6 +298,8 @@ class ProfilerController
$ip = preg_replace('/[^:\d\.]/', '', $request->query->get('ip'));
$method = $request->query->get('method');
$url = $request->query->get('url');
$start = $request->query->get('start');
$end = $request->query->get('end');
$limit = $request->query->get('limit');
$token = $request->query->get('token');
@ -295,6 +307,8 @@ class ProfilerController
$session->set('_profiler_search_ip', $ip);
$session->set('_profiler_search_method', $method);
$session->set('_profiler_search_url', $url);
$session->set('_profiler_search_start', $start);
$session->set('_profiler_search_end', $end);
$session->set('_profiler_search_limit', $limit);
$session->set('_profiler_search_token', $token);
}
@ -303,13 +317,15 @@ class ProfilerController
return new RedirectResponse($this->generator->generate('_profiler', array('token' => $token)));
}
$tokens = $this->profiler->find($ip, $url, $limit, $method);
$tokens = $this->profiler->find($ip, $url, $start, $end, $limit, $method);
return new RedirectResponse($this->generator->generate('_profiler_search_results', array(
'token' => $tokens ? $tokens[0]['token'] : 'empty',
'ip' => $ip,
'method' => $method,
'url' => $url,
'start' => $start,
'end' => $end,
'limit' => $limit,
)));
}

View File

@ -20,6 +20,12 @@
<label for="token">Token</label>
<input type="text" name="token" id="token" value="{{ token }}" />
<div class="clear-fix"></div>
<label for="token">From</label>
<input type="text" name="start" id="start" value="{{ start }}" />
<div class="clear-fix"></div>
<label for="token">Until</label>
<input type="text" name="end" id="end" value="{{ end }}" />
<div class="clear-fix"></div>
<label for="limit">Limit</label>
<select name="limit" id="limit">
{% for l in [10, 50, 100] %}

View File

@ -40,7 +40,7 @@ abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface
/**
* {@inheritdoc}
*/
public function find($ip, $url, $limit, $method)
public function find($ip, $url, $limit, $method, $start = null, $end = null)
{
$indexName = $this->getIndexName();
@ -52,6 +52,14 @@ abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface
$profileList = explode("\n", $indexContent);
$result = array();
if (null === $start) {
$start = 0;
}
if (null === $end) {
$end = time();
}
foreach ($profileList as $item) {
if ($limit === 0) {
@ -64,7 +72,9 @@ abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface
list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = explode("\t", $item, 6);
if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) {
$itemTime = (int)$itemTime;
if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method) || $start > $itemTime || $end < $itemTime) {
continue;
}

View File

@ -46,7 +46,7 @@ class FileProfilerStorage implements ProfilerStorageInterface
/**
* {@inheritdoc}
*/
public function find($ip, $url, $limit, $method)
public function find($ip, $url, $limit, $method, $start = null, $end = null)
{
$file = $this->getIndexFilename();
@ -57,6 +57,14 @@ class FileProfilerStorage implements ProfilerStorageInterface
$file = fopen($file, 'r');
fseek($file, 0, SEEK_END);
if (null === $start) {
$start = 0;
}
if (null === $end) {
$end = time();
}
$result = array();
while ($limit > 0) {
@ -72,7 +80,9 @@ class FileProfilerStorage implements ProfilerStorageInterface
list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent) = str_getcsv($line);
if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method)) {
$csvTime = (int)$csvTime;
if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method) || $start > $csvTime || $end < $csvTime) {
continue;
}

View File

@ -34,9 +34,17 @@ class MongoDbProfilerStorage implements ProfilerStorageInterface
/**
* {@inheritdoc}
*/
public function find($ip, $url, $limit, $method)
public function find($ip, $url, $limit, $method, $start = null, $end = null)
{
$cursor = $this->getMongo()->find($this->buildQuery($ip, $url, $method), array('_id', 'parent', 'ip', 'method', 'url', 'time'))->sort(array('time' => -1))->limit($limit);
if (null === $start) {
$start = 0;
}
if (null === $end) {
$end = time();
}
$cursor = $this->getMongo()->find($this->buildQuery($ip, $url, $method, $start, $end), array('_id', 'parent', 'ip', 'method', 'url', 'time'))->sort(array('time' => -1))->limit($limit);
$tokens = array();
foreach ($cursor as $profile) {
@ -161,10 +169,12 @@ class MongoDbProfilerStorage implements ProfilerStorageInterface
* @param string $ip
* @param string $url
* @param string $method
* @param int $start
* @param int $end
*
* @return array
*/
private function buildQuery($ip, $url, $method)
private function buildQuery($ip, $url, $method, $start, $end)
{
$query = array();

View File

@ -44,7 +44,7 @@ class MysqlProfilerStorage extends PdoProfilerStorage
/**
* {@inheritdoc}
*/
protected function buildCriteria($ip, $url, $limit, $method)
protected function buildCriteria($ip, $url, $start, $end, $limit, $method)
{
$criteria = array();
$args = array();
@ -64,6 +64,12 @@ class MysqlProfilerStorage extends PdoProfilerStorage
$args[':method'] = $method;
}
$criteria[] = 'time >= :start';
$args[':start'] = $start;
$criteria[] = 'time <= :end';
$args[':end'] = $end;
return array($criteria, $args);
}
}

View File

@ -44,9 +44,17 @@ abstract class PdoProfilerStorage implements ProfilerStorageInterface
/**
* {@inheritdoc}
*/
public function find($ip, $url, $limit, $method)
public function find($ip, $url, $limit, $method, $start = null, $end = null)
{
list($criteria, $args) = $this->buildCriteria($ip, $url, $limit, $method);
if (null === $start) {
$start = 0;
}
if (null === $end) {
$end = time();
}
list($criteria, $args) = $this->buildCriteria($ip, $url, $start, $end, $limit, $method);
$criteria = $criteria ? 'WHERE '.implode(' AND ', $criteria) : '';
@ -122,12 +130,14 @@ abstract class PdoProfilerStorage implements ProfilerStorageInterface
*
* @param string $ip The IP
* @param string $url The URL
* @param string $start The start period to search from
* @param string $end The end period to search to
* @param string $limit The maximum number of tokens to return
* @param string $method The request method
*
* @return array An array with (criteria, args)
*/
abstract protected function buildCriteria($ip, $url, $limit, $method);
abstract protected function buildCriteria($ip, $url, $start, $end, $limit, $method);
/**
* Initializes the database

View File

@ -159,6 +159,10 @@ class Profile
*/
public function getTime()
{
if (null === $this->time) {
return 0;
}
return $this->time;
}

View File

@ -163,12 +163,34 @@ class Profiler
* @param string $url The URL
* @param string $limit The maximum number of tokens to return
* @param string $method The request method
* @param int $start The start period to search from
* @param int $end The end period to search to
*
* @return array An array of tokens
*/
public function find($ip, $url, $limit, $method)
public function find($ip, $url, $limit, $method, $start, $end)
{
return $this->storage->find($ip, $url, $limit, $method);
if ($start != '' && null !== $start) {
if (is_integer($start)) {
$start = '@' . $start;
}
} else {
$start = '@0';
}
$start = new \DateTime($start);
$start = $start->getTimestamp();
if ($end != '' && null !== $end) {
if (is_integer($end)) {
$end = '@' . $end;
}
} else {
$end = 'now';
}
$end = new \DateTime($end);
$end = $end->getTimestamp();
return $this->storage->find($ip, $url, $limit, $method, $start, $end);
}
/**

View File

@ -25,10 +25,12 @@ interface ProfilerStorageInterface
* @param string $url The URL
* @param string $limit The maximum number of tokens to return
* @param string $method The request method
* @param int $start The start period to search from
* @param int $end The end period to search to
*
* @return array An array of tokens
*/
public function find($ip, $url, $limit, $method);
public function find($ip, $url, $limit, $method, $start = null, $end = null);
/**
* Reads data associated with the given token.

View File

@ -52,7 +52,7 @@ class RedisProfilerStorage implements ProfilerStorageInterface
/**
* {@inheritdoc}
*/
public function find($ip, $url, $limit, $method)
public function find($ip, $url, $limit, $method, $start = null, $end = null)
{
$indexName = $this->getIndexName();
@ -63,6 +63,14 @@ class RedisProfilerStorage implements ProfilerStorageInterface
$profileList = explode("\n", $indexContent);
$result = array();
if (null === $start) {
$start = 0;
}
if (null === $end) {
$end = time();
}
foreach ($profileList as $item) {
if ($limit === 0) {
break;
@ -74,7 +82,9 @@ class RedisProfilerStorage implements ProfilerStorageInterface
list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = explode("\t", $item, 6);
if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method)) {
$itemTime = (int)$itemTime;
if ($ip && false === strpos($itemIp, $ip) || $url && false === strpos($itemUrl, $url) || $method && false === strpos($itemMethod, $method) || $start > $itemTime || $end < $itemTime) {
continue;
}

View File

@ -97,7 +97,7 @@ class SqliteProfilerStorage extends PdoProfilerStorage
/**
* {@inheritdoc}
*/
protected function buildCriteria($ip, $url, $limit, $method)
protected function buildCriteria($ip, $url, $start, $end, $limit, $method)
{
$criteria = array();
$args = array();
@ -117,6 +117,12 @@ class SqliteProfilerStorage extends PdoProfilerStorage
$args[':method'] = $method;
}
$criteria[] = 'time >= :start';
$args[':start'] = $start;
$criteria[] = 'time <= :end';
$args[':end'] = $end;
return array($criteria, $args);
}

View File

@ -156,6 +156,8 @@ abstract class AbstractProfilerStorageTest extends \PHPUnit_Framework_TestCase
public function testStoreTime()
{
$dt = new \DateTime('now');
$start = $dt->getTimestamp();
for ($i = 0; $i < 3; $i++) {
$dt->modify('+1 minute');
$profile = new Profile('time_'.$i);
@ -165,7 +167,8 @@ abstract class AbstractProfilerStorageTest extends \PHPUnit_Framework_TestCase
$profile->setMethod('GET');
$this->getStorage()->write($profile);
}
$records = $this->getStorage()->find('', '', 3, 'GET');
$records = $this->getStorage()->find('', '', 3, 'GET', $start, time() + 3 * 60);
$this->assertCount(3, $records, '->find() returns all previously added records');
$this->assertEquals($records[0]['token'], 'time_2', '->find() returns records ordered by time in descendant order');
$this->assertEquals($records[1]['token'], 'time_1', '->find() returns records ordered by time in descendant order');