Skip to content

Improve profiler to store sub request data #113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
1 commit merged into from
Mar 16, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 20 additions & 5 deletions src/Symfony/Bundle/FrameworkBundle/Profiler/ProfilerListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ public function __construct(ContainerInterface $container, RequestMatcherInterfa
$this->onlyException = $onlyException;
}

/**
* Handles the core.request event
*
* This method initialize the profiler to be able to get it as a scoped
* service when handleResponse() will collect the sub request
*
* @param EventInterface $event An EventInterface instance
*/
public function handleRequest(EventInterface $event)
{
$this->container->get('profiler');
}

/**
* Handles the core.exception event.
*
Expand All @@ -71,10 +84,6 @@ public function handleException(EventInterface $event)
*/
public function handleResponse(EventInterface $event, Response $response)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->get('request_type')) {
return $response;
}

if (null !== $this->matcher && !$this->matcher->matches($event->get('request'))) {
return $response;
}
Expand All @@ -83,7 +92,13 @@ public function handleResponse(EventInterface $event, Response $response)
return $response;
}

$this->container->get('profiler')->collect($event->get('request'), $response, $this->exception);
$profiler = $this->container->get('profiler');

if (($parent = $this->container->getCurrentScopedStack('request'))) {
$profiler->setParent($parent['request']['profiler']->getToken());
}

$profiler->collect($event->get('request'), $response, $this->exception);
$this->exception = null;

return $response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<service id="profiler_listener" class="%profiler_listener.class%">
<tag name="kernel.listener" event="core.response" method="handleResponse" />
<tag name="kernel.listener" event="core.exception" method="handleException" />
<tag name="kernel.listener" event="core.request" method="handleRequest" />
<argument type="service" id="service_container" />
<argument type="service" id="profiler.request_matcher" on-invalid="null" />
<argument>%profiler_listener.only_exceptions%</argument>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,21 @@ Request
{% else %}
<em>No request session attributes</em>
{% endif %}


{% if profiler.parent %}
<h2><a href="{{ path('_profiler', { 'token': profiler.parent }) }}">Parent request: {{ profiler.parent }}</a></h2>

{% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': profiler.parenttoken.get('request').requestattributes } only %}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be parentToken instead of parenttoken

{% endif %}

{% if profiler.children|length %}
<h2>Sub requests</h2>

{% for subrequest in profiler.children %}
<h3><a href="{{ path('_profiler', { 'token': subrequest.token }) }}">{{ subrequest.token }}</a></h3>
{% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': subrequest.get('request').requestattributes } only %}
{% endfor %}
{% endif %}

{% endblock %}
16 changes: 16 additions & 0 deletions src/Symfony/Component/DependencyInjection/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,22 @@ public function enterScope($name)
$this->scopedServices[$name] = array();
}


/**
* Returns the current stacked service scope for the given name
*
* @param string $name The service name
* @return array The service scope
*/
public function getCurrentScopedStack($name)
{
if (!isset($this->scopeStacks[$name]) || 0 === $this->scopeStacks[$name]->count()) {
return null;
}

return $this->scopeStacks[$name]->current();
}

/**
* This is called to leave the current scope, and move back to the parent
* scope.
Expand Down
45 changes: 43 additions & 2 deletions src/Symfony/Component/HttpKernel/Profiler/Profiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class Profiler
protected $url;
protected $time;
protected $empty;
protected $children;

/**
* Constructor.
Expand Down Expand Up @@ -142,7 +143,7 @@ public function setToken($token)
$this->token = $token;

if (false !== $items = $this->storage->read($token)) {
list($data, $this->ip, $this->url, $this->time) = $items;
list($data, $this->parent, $this->ip, $this->url, $this->time) = $items;
$this->set(unserialize(base64_decode($data)));

$this->empty = false;
Expand All @@ -151,6 +152,30 @@ public function setToken($token)
}
}

/**
* Sets the parent token
*
* @param string $parent The parent token
*/
public function setParent($parent)
{
$this->parent = $parent;
}

/**
* Returns an instance of the parent token
*
* @return Profiler
*/
public function getParentToken()
{
if (null !== $this->parent) {
return $this->loadFromToken($this->parent);
}

return null;
}

/**
* Gets the token.
*
Expand Down Expand Up @@ -229,6 +254,23 @@ public function find($ip, $url, $limit)
return $this->storage->find($ip, $url, $limit);
}

/**
* Finds children profilers.
*
* @return array An array of Profiler
*/
public function getChildren()
{
if (null === $this->children) {
$this->children = array();
foreach ($this->storage->findChildren($this->token) as $token) {
$this->children[] = $this->loadFromToken($token['token']);
}
}

return $this->children;
}

/**
* Collects data for the given Response.
*
Expand All @@ -248,7 +290,6 @@ public function collect(Request $request, Response $response, \Exception $except
$collector->collect($request, $response, $exception);
}

$this->parent = '';
$this->ip = $request->server->get('REMOTE_ADDR');
$this->url = $request->getUri();
$this->time = time();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ interface ProfilerStorageInterface
*/
function find($ip, $url, $limit);

/**
* Finds profiler tokens for the given parent token.
*
* @param string $token The parent token
*
* @return array An array of tokens
*/
function findChildren($token);

/**
* Reads data associated with the given token.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function find($ip, $url, $limit)
$criteria = $criteria ? 'WHERE '.implode(' AND ', $criteria) : '';

$db = $this->initDb();
$tokens = $this->fetch($db, 'SELECT token, ip, url, time FROM data '.$criteria.' ORDER BY time DESC LIMIT '.((integer) $limit), $args);
$tokens = $this->fetch($db, 'SELECT token, ip, url, time, parent FROM data '.$criteria.' ORDER BY time DESC LIMIT '.((integer) $limit), $args);
$this->close($db);

return $tokens;
Expand All @@ -69,15 +69,28 @@ public function read($token)
{
$db = $this->initDb();
$args = array(':token' => $token);
$data = $this->fetch($db, 'SELECT data, ip, url, time FROM data WHERE token = :token LIMIT 1', $args);
$data = $this->fetch($db, 'SELECT data, parent, ip, url, time FROM data WHERE token = :token LIMIT 1', $args);
$this->close($db);
if (isset($data[0]['data'])) {
return array($data[0]['data'], $data[0]['ip'], $data[0]['url'], $data[0]['time']);
return array($data[0]['data'], $data[0]['parent'], $data[0]['ip'], $data[0]['url'], $data[0]['time']);
} else {
return false;
}
}

/**
* {@inheritdoc}
*/
public function findChildren($token)
{
$db = $this->initDb();
$args = array(':token' => $token);
$tokens = $this->fetch($db, 'SELECT token FROM data WHERE parent = :token LIMIT 1', $args);
$this->close($db);

return $tokens;
}

/**
* {@inheritdoc}
*/
Expand Down