2010-06-16 09:38:41 +01:00
|
|
|
<?php
|
|
|
|
|
2010-08-20 22:09:55 +01:00
|
|
|
namespace Symfony\Component\HttpKernel\Profiler;
|
2010-06-16 09:38:41 +01:00
|
|
|
|
2010-08-28 14:23:21 +01:00
|
|
|
use Symfony\Component\HttpFoundation\Request;
|
2010-08-20 22:09:55 +01:00
|
|
|
use Symfony\Component\HttpFoundation\Response;
|
2010-08-28 14:23:21 +01:00
|
|
|
use Symfony\Component\HttpKernel\Profiler\ProfilerStorageInterface;
|
|
|
|
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
|
2010-08-20 22:09:55 +01:00
|
|
|
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
2010-06-16 09:38:41 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This file is part of the Symfony framework.
|
|
|
|
*
|
|
|
|
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
|
|
|
*
|
|
|
|
* This source file is subject to the MIT license that is bundled
|
|
|
|
* with this source code in the file LICENSE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Profiler.
|
|
|
|
*
|
2010-10-17 12:45:15 +01:00
|
|
|
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
2010-06-16 09:38:41 +01:00
|
|
|
*/
|
2010-08-28 14:23:21 +01:00
|
|
|
class Profiler
|
2010-06-16 09:38:41 +01:00
|
|
|
{
|
2010-08-28 14:23:21 +01:00
|
|
|
protected $storage;
|
2010-06-16 09:38:41 +01:00
|
|
|
protected $collectors;
|
|
|
|
protected $logger;
|
2010-08-22 21:35:44 +01:00
|
|
|
protected $enabled;
|
2010-08-28 14:23:21 +01:00
|
|
|
protected $token;
|
|
|
|
protected $data;
|
|
|
|
protected $ip;
|
|
|
|
protected $url;
|
|
|
|
protected $time;
|
|
|
|
protected $empty;
|
2010-06-16 09:38:41 +01:00
|
|
|
|
2010-08-28 14:23:21 +01:00
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*
|
|
|
|
* @param ProfilerStorageInterface $storage A ProfilerStorageInterface instance
|
|
|
|
* @param LoggerInterface $logger A LoggerInterface instance
|
|
|
|
*/
|
|
|
|
public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null)
|
2010-06-16 09:38:41 +01:00
|
|
|
{
|
2010-08-28 14:23:21 +01:00
|
|
|
$this->storage = $storage;
|
2010-06-16 09:38:41 +01:00
|
|
|
$this->logger = $logger;
|
2010-06-16 13:19:46 +01:00
|
|
|
$this->collectors = array();
|
2010-08-22 21:35:44 +01:00
|
|
|
$this->enabled = true;
|
2010-08-28 14:23:21 +01:00
|
|
|
$this->empty = true;
|
2010-06-16 09:38:41 +01:00
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
2010-08-28 14:23:21 +01:00
|
|
|
* Disables the profiler.
|
2010-06-16 14:45:20 +01:00
|
|
|
*/
|
2010-08-28 14:23:21 +01:00
|
|
|
public function disable()
|
2010-06-16 09:38:41 +01:00
|
|
|
{
|
2010-08-28 14:23:21 +01:00
|
|
|
$this->enabled = false;
|
2010-06-16 09:38:41 +01:00
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
2010-08-28 14:23:21 +01:00
|
|
|
* Loads a Profiler for the given Response.
|
2010-06-16 14:45:20 +01:00
|
|
|
*
|
2010-07-27 14:33:28 +01:00
|
|
|
* @param Response $response A Response instance
|
2010-06-16 14:45:20 +01:00
|
|
|
*
|
2010-07-27 14:33:28 +01:00
|
|
|
* @return Profiler A new Profiler instance
|
2010-06-16 14:45:20 +01:00
|
|
|
*/
|
2010-08-28 14:23:21 +01:00
|
|
|
public function loadFromResponse(Response $response)
|
2010-06-16 09:38:41 +01:00
|
|
|
{
|
2010-06-16 14:45:20 +01:00
|
|
|
if (!$token = $response->headers->get('X-Debug-Token')) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2010-08-28 14:23:21 +01:00
|
|
|
return $this->loadFromToken($token);
|
2010-06-16 09:38:41 +01:00
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
2010-08-28 14:23:21 +01:00
|
|
|
* Loads a Profiler for the given token.
|
2010-06-16 14:45:20 +01:00
|
|
|
*
|
|
|
|
* @param string $token A token
|
|
|
|
*
|
2010-07-27 14:33:28 +01:00
|
|
|
* @return Profiler A new Profiler instance
|
2010-06-16 14:45:20 +01:00
|
|
|
*/
|
2010-08-28 14:23:21 +01:00
|
|
|
public function loadFromToken($token)
|
2010-06-16 09:38:41 +01:00
|
|
|
{
|
2010-08-28 14:23:21 +01:00
|
|
|
$profiler = new self($this->storage, $this->logger);
|
|
|
|
$profiler->setToken($token);
|
2010-06-16 09:38:41 +01:00
|
|
|
|
|
|
|
return $profiler;
|
|
|
|
}
|
|
|
|
|
2010-09-01 07:21:38 +01:00
|
|
|
/**
|
|
|
|
* Purges all data from the storage.
|
|
|
|
*/
|
|
|
|
public function purge()
|
|
|
|
{
|
|
|
|
$this->storage->purge();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Exports the current profiler data.
|
|
|
|
*
|
|
|
|
* @return string The exported data
|
|
|
|
*/
|
2010-08-30 15:04:50 +01:00
|
|
|
public function export()
|
|
|
|
{
|
|
|
|
$unpack = unpack('H*', serialize(array($this->token, $this->collectors, $this->ip, $this->url, $this->time)));
|
|
|
|
|
|
|
|
return $unpack[1];
|
|
|
|
}
|
|
|
|
|
2010-09-01 07:21:38 +01:00
|
|
|
/**
|
|
|
|
* Imports data into the profiler storage.
|
|
|
|
*
|
|
|
|
* @param string $data A data string as exported by the export() method
|
|
|
|
*
|
|
|
|
* @return string The token associated with the imported data
|
|
|
|
*/
|
2010-08-30 15:04:50 +01:00
|
|
|
public function import($data)
|
|
|
|
{
|
|
|
|
list($token, $collectors, $ip, $url, $time) = unserialize(pack('H*', $data));
|
|
|
|
|
|
|
|
if (false !== $this->storage->read($token)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-01-06 18:28:19 +00:00
|
|
|
$unpack = unpack('H*', serialize($collectors));
|
2010-08-30 15:04:50 +01:00
|
|
|
|
|
|
|
$this->storage->write($token, $unpack[1], $ip, $url, $time);
|
|
|
|
|
|
|
|
return $token;
|
|
|
|
}
|
|
|
|
|
2010-08-28 14:23:21 +01:00
|
|
|
/**
|
|
|
|
* Sets the token.
|
|
|
|
*
|
|
|
|
* @param string $token The token
|
|
|
|
*/
|
|
|
|
public function setToken($token)
|
2010-08-22 21:35:44 +01:00
|
|
|
{
|
2010-08-28 14:23:21 +01:00
|
|
|
$this->token = $token;
|
|
|
|
|
|
|
|
if (false !== $items = $this->storage->read($token)) {
|
2010-08-30 15:04:50 +01:00
|
|
|
list($data, $this->ip, $this->url, $this->time) = $items;
|
2010-09-01 15:53:28 +01:00
|
|
|
$this->set(unserialize(pack('H*', $data)));
|
2010-08-28 14:23:21 +01:00
|
|
|
|
|
|
|
$this->empty = false;
|
|
|
|
} else {
|
|
|
|
$this->empty = true;
|
|
|
|
}
|
2010-08-22 21:35:44 +01:00
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
2010-08-28 14:23:21 +01:00
|
|
|
* Gets the token.
|
2010-06-16 14:45:20 +01:00
|
|
|
*
|
2010-08-28 14:23:21 +01:00
|
|
|
* @return string The token
|
2010-06-16 14:45:20 +01:00
|
|
|
*/
|
2010-08-28 14:23:21 +01:00
|
|
|
public function getToken()
|
2010-06-16 09:38:41 +01:00
|
|
|
{
|
2010-08-28 14:23:21 +01:00
|
|
|
if (null === $this->token) {
|
|
|
|
$this->token = uniqid();
|
2010-08-22 21:35:44 +01:00
|
|
|
}
|
|
|
|
|
2010-08-28 14:23:21 +01:00
|
|
|
return $this->token;
|
|
|
|
}
|
2010-06-16 09:38:41 +01:00
|
|
|
|
2010-08-28 14:23:21 +01:00
|
|
|
/**
|
|
|
|
* Checks if the profiler is empty.
|
|
|
|
*
|
|
|
|
* @return Boolean Whether the profiler is empty or not
|
|
|
|
*/
|
|
|
|
public function isEmpty()
|
|
|
|
{
|
|
|
|
return $this->empty;
|
|
|
|
}
|
2010-06-16 09:38:41 +01:00
|
|
|
|
2010-08-28 14:23:21 +01:00
|
|
|
/**
|
|
|
|
* Returns the IP.
|
|
|
|
*
|
|
|
|
* @return string The IP
|
|
|
|
*/
|
|
|
|
public function getIp()
|
|
|
|
{
|
|
|
|
return $this->ip;
|
|
|
|
}
|
2010-06-16 09:38:41 +01:00
|
|
|
|
2010-08-28 14:23:21 +01:00
|
|
|
/**
|
|
|
|
* Returns the URL.
|
|
|
|
*
|
|
|
|
* @return string The URL
|
|
|
|
*/
|
|
|
|
public function getUrl()
|
|
|
|
{
|
|
|
|
return $this->url;
|
2010-06-16 09:38:41 +01:00
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
2010-08-28 14:23:21 +01:00
|
|
|
* Returns the time.
|
|
|
|
*
|
|
|
|
* @return string The time
|
2010-06-16 14:45:20 +01:00
|
|
|
*/
|
2010-08-28 14:23:21 +01:00
|
|
|
public function getTime()
|
2010-06-16 09:38:41 +01:00
|
|
|
{
|
2010-08-28 14:23:21 +01:00
|
|
|
return $this->time;
|
2010-06-16 09:38:41 +01:00
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
2010-08-28 14:23:21 +01:00
|
|
|
* Finds profiler tokens for the given criteria.
|
2010-06-16 14:45:20 +01:00
|
|
|
*
|
2010-08-28 14:23:21 +01:00
|
|
|
* @param string $ip The IP
|
|
|
|
* @param string $url The URL
|
|
|
|
* @param string $limit The maximum number of tokens to return
|
|
|
|
*
|
|
|
|
* @return array An array of tokens
|
2010-06-16 14:45:20 +01:00
|
|
|
*/
|
2010-08-28 14:23:21 +01:00
|
|
|
public function find($ip, $url, $limit)
|
2010-06-16 13:19:46 +01:00
|
|
|
{
|
2010-08-28 14:23:21 +01:00
|
|
|
return $this->storage->find($ip, $url, $limit);
|
2010-06-16 13:19:46 +01:00
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
2010-08-28 14:23:21 +01:00
|
|
|
* Collects data for the given Response.
|
2010-06-16 14:45:20 +01:00
|
|
|
*
|
2010-08-28 14:23:21 +01:00
|
|
|
* @param Request $request A Request instance
|
|
|
|
* @param Response $response A Response instance
|
|
|
|
* @param \Exception $exception An exception instance if the request threw one
|
2010-06-16 14:45:20 +01:00
|
|
|
*/
|
2010-08-28 14:23:21 +01:00
|
|
|
public function collect(Request $request, Response $response, \Exception $exception = null)
|
2010-06-16 13:19:46 +01:00
|
|
|
{
|
2010-08-28 14:23:21 +01:00
|
|
|
if (false === $this->enabled) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$response = $response;
|
|
|
|
$response->headers->set('X-Debug-Token', $this->getToken());
|
|
|
|
|
|
|
|
foreach ($this->collectors as $collector) {
|
|
|
|
$collector->collect($request, $response, $exception);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->ip = $request->server->get('REMOTE_ADDR');
|
|
|
|
$this->url = $request->getUri();
|
|
|
|
$this->time = time();
|
|
|
|
|
2010-08-30 15:04:50 +01:00
|
|
|
$unpack = unpack('H*', serialize($this->collectors));
|
2010-08-28 14:23:21 +01:00
|
|
|
try {
|
2010-08-30 15:04:50 +01:00
|
|
|
$this->storage->write($this->token, $unpack[1], $this->ip, $this->url, $this->time);
|
2010-08-28 14:23:21 +01:00
|
|
|
$this->empty = false;
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
if (null !== $this->logger) {
|
|
|
|
$this->logger->err(sprintf('Unable to store the profiler information (%s).', $e->getMessage()));
|
|
|
|
}
|
|
|
|
}
|
2010-06-16 13:19:46 +01:00
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
|
|
|
* Gets the Collectors associated with this profiler.
|
|
|
|
*
|
|
|
|
* @return array An array of collectors
|
|
|
|
*/
|
2010-09-01 15:53:28 +01:00
|
|
|
public function all()
|
2010-06-16 09:38:41 +01:00
|
|
|
{
|
|
|
|
return $this->collectors;
|
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
|
|
|
* Sets the Collectors associated with this profiler.
|
|
|
|
*
|
|
|
|
* @param array $collectors An array of collectors
|
|
|
|
*/
|
2010-09-01 15:53:28 +01:00
|
|
|
public function set(array $collectors = array())
|
2010-06-16 13:19:46 +01:00
|
|
|
{
|
|
|
|
$this->collectors = array();
|
2010-11-06 15:47:49 +00:00
|
|
|
foreach ($collectors as $collector) {
|
2010-09-01 15:53:28 +01:00
|
|
|
$this->add($collector);
|
2010-06-16 13:19:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
|
|
|
* Adds a Collector.
|
|
|
|
*
|
2010-07-27 14:33:28 +01:00
|
|
|
* @param DataCollectorInterface $collector A DataCollectorInterface instance
|
2010-06-16 14:45:20 +01:00
|
|
|
*/
|
2010-09-01 15:53:28 +01:00
|
|
|
public function add(DataCollectorInterface $collector)
|
2010-06-16 13:19:46 +01:00
|
|
|
{
|
2010-06-16 14:45:20 +01:00
|
|
|
$this->collectors[$collector->getName()] = $collector;
|
2010-06-16 13:19:46 +01:00
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
|
|
|
* Returns true if a Collector for the given name exists.
|
|
|
|
*
|
|
|
|
* @param string $name A collector name
|
|
|
|
*/
|
2010-09-01 15:53:28 +01:00
|
|
|
public function has($name)
|
2010-06-16 09:38:41 +01:00
|
|
|
{
|
|
|
|
return isset($this->collectors[$name]);
|
|
|
|
}
|
|
|
|
|
2010-06-16 14:45:20 +01:00
|
|
|
/**
|
|
|
|
* Gets a Collector by name.
|
|
|
|
*
|
|
|
|
* @param string $name A collector name
|
|
|
|
*
|
2010-07-27 14:33:28 +01:00
|
|
|
* @return DataCollectorInterface A DataCollectorInterface instance
|
2010-06-16 14:45:20 +01:00
|
|
|
*
|
|
|
|
* @throws \InvalidArgumentException if the collector does not exist
|
|
|
|
*/
|
2010-09-01 15:53:28 +01:00
|
|
|
public function get($name)
|
2010-06-16 09:38:41 +01:00
|
|
|
{
|
|
|
|
if (!isset($this->collectors[$name])) {
|
|
|
|
throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->collectors[$name];
|
|
|
|
}
|
|
|
|
}
|