Просмотр файла vendor/symfony/http-kernel/Profiler/Profiler.php

Размер файла: 6.97Kb
  1. <?php
  2.  
  3. /*
  4. * This file is part of the Symfony package.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11.  
  12. namespace Symfony\Component\HttpKernel\Profiler;
  13.  
  14. use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
  18. use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
  19. use Psr\Log\LoggerInterface;
  20.  
  21. /**
  22. * Profiler.
  23. *
  24. * @author Fabien Potencier <fabien@symfony.com>
  25. */
  26. class Profiler
  27. {
  28. /**
  29. * @var ProfilerStorageInterface
  30. */
  31. private $storage;
  32.  
  33. /**
  34. * @var DataCollectorInterface[]
  35. */
  36. private $collectors = array();
  37.  
  38. /**
  39. * @var LoggerInterface
  40. */
  41. private $logger;
  42.  
  43. /**
  44. * @var bool
  45. */
  46. private $enabled = true;
  47.  
  48. /**
  49. * Constructor.
  50. *
  51. * @param ProfilerStorageInterface $storage A ProfilerStorageInterface instance
  52. * @param LoggerInterface $logger A LoggerInterface instance
  53. */
  54. public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null)
  55. {
  56. $this->storage = $storage;
  57. $this->logger = $logger;
  58. }
  59.  
  60. /**
  61. * Disables the profiler.
  62. */
  63. public function disable()
  64. {
  65. $this->enabled = false;
  66. }
  67.  
  68. /**
  69. * Enables the profiler.
  70. */
  71. public function enable()
  72. {
  73. $this->enabled = true;
  74. }
  75.  
  76. /**
  77. * Loads the Profile for the given Response.
  78. *
  79. * @param Response $response A Response instance
  80. *
  81. * @return Profile|false A Profile instance
  82. */
  83. public function loadProfileFromResponse(Response $response)
  84. {
  85. if (!$token = $response->headers->get('X-Debug-Token')) {
  86. return false;
  87. }
  88.  
  89. return $this->loadProfile($token);
  90. }
  91.  
  92. /**
  93. * Loads the Profile for the given token.
  94. *
  95. * @param string $token A token
  96. *
  97. * @return Profile A Profile instance
  98. */
  99. public function loadProfile($token)
  100. {
  101. return $this->storage->read($token);
  102. }
  103.  
  104. /**
  105. * Saves a Profile.
  106. *
  107. * @param Profile $profile A Profile instance
  108. *
  109. * @return bool
  110. */
  111. public function saveProfile(Profile $profile)
  112. {
  113. // late collect
  114. foreach ($profile->getCollectors() as $collector) {
  115. if ($collector instanceof LateDataCollectorInterface) {
  116. $collector->lateCollect();
  117. }
  118. }
  119.  
  120. if (!($ret = $this->storage->write($profile)) && null !== $this->logger) {
  121. $this->logger->warning('Unable to store the profiler information.', array('configured_storage' => get_class($this->storage)));
  122. }
  123.  
  124. return $ret;
  125. }
  126.  
  127. /**
  128. * Purges all data from the storage.
  129. */
  130. public function purge()
  131. {
  132. $this->storage->purge();
  133. }
  134.  
  135. /**
  136. * Finds profiler tokens for the given criteria.
  137. *
  138. * @param string $ip The IP
  139. * @param string $url The URL
  140. * @param string $limit The maximum number of tokens to return
  141. * @param string $method The request method
  142. * @param string $start The start date to search from
  143. * @param string $end The end date to search to
  144. * @param string $statusCode The request status code
  145. *
  146. * @return array An array of tokens
  147. *
  148. * @see http://php.net/manual/en/datetime.formats.php for the supported date/time formats
  149. */
  150. public function find($ip, $url, $limit, $method, $start, $end, $statusCode = null)
  151. {
  152. return $this->storage->find($ip, $url, $limit, $method, $this->getTimestamp($start), $this->getTimestamp($end), $statusCode);
  153. }
  154.  
  155. /**
  156. * Collects data for the given Response.
  157. *
  158. * @param Request $request A Request instance
  159. * @param Response $response A Response instance
  160. * @param \Exception $exception An exception instance if the request threw one
  161. *
  162. * @return Profile|null A Profile instance or null if the profiler is disabled
  163. */
  164. public function collect(Request $request, Response $response, \Exception $exception = null)
  165. {
  166. if (false === $this->enabled) {
  167. return;
  168. }
  169.  
  170. $profile = new Profile(substr(hash('sha256', uniqid(mt_rand(), true)), 0, 6));
  171. $profile->setTime(time());
  172. $profile->setUrl($request->getUri());
  173. $profile->setMethod($request->getMethod());
  174. $profile->setStatusCode($response->getStatusCode());
  175. try {
  176. $profile->setIp($request->getClientIp());
  177. } catch (ConflictingHeadersException $e) {
  178. $profile->setIp('Unknown');
  179. }
  180.  
  181. $response->headers->set('X-Debug-Token', $profile->getToken());
  182.  
  183. foreach ($this->collectors as $collector) {
  184. $collector->collect($request, $response, $exception);
  185.  
  186. // we need to clone for sub-requests
  187. $profile->addCollector(clone $collector);
  188. }
  189.  
  190. return $profile;
  191. }
  192.  
  193. /**
  194. * Gets the Collectors associated with this profiler.
  195. *
  196. * @return array An array of collectors
  197. */
  198. public function all()
  199. {
  200. return $this->collectors;
  201. }
  202.  
  203. /**
  204. * Sets the Collectors associated with this profiler.
  205. *
  206. * @param DataCollectorInterface[] $collectors An array of collectors
  207. */
  208. public function set(array $collectors = array())
  209. {
  210. $this->collectors = array();
  211. foreach ($collectors as $collector) {
  212. $this->add($collector);
  213. }
  214. }
  215.  
  216. /**
  217. * Adds a Collector.
  218. *
  219. * @param DataCollectorInterface $collector A DataCollectorInterface instance
  220. */
  221. public function add(DataCollectorInterface $collector)
  222. {
  223. $this->collectors[$collector->getName()] = $collector;
  224. }
  225.  
  226. /**
  227. * Returns true if a Collector for the given name exists.
  228. *
  229. * @param string $name A collector name
  230. *
  231. * @return bool
  232. */
  233. public function has($name)
  234. {
  235. return isset($this->collectors[$name]);
  236. }
  237.  
  238. /**
  239. * Gets a Collector by name.
  240. *
  241. * @param string $name A collector name
  242. *
  243. * @return DataCollectorInterface A DataCollectorInterface instance
  244. *
  245. * @throws \InvalidArgumentException if the collector does not exist
  246. */
  247. public function get($name)
  248. {
  249. if (!isset($this->collectors[$name])) {
  250. throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name));
  251. }
  252.  
  253. return $this->collectors[$name];
  254. }
  255.  
  256. private function getTimestamp($value)
  257. {
  258. if (null === $value || '' == $value) {
  259. return;
  260. }
  261.  
  262. try {
  263. $value = new \DateTime(is_numeric($value) ? '@'.$value : $value);
  264. } catch (\Exception $e) {
  265. return;
  266. }
  267.  
  268. return $value->getTimestamp();
  269. }
  270. }