TimelinePanel.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\debug\panels;
  8. use Yii;
  9. use yii\base\InvalidConfigException;
  10. use yii\debug\models\timeline\Search;
  11. use yii\debug\models\timeline\Svg;
  12. use yii\debug\Panel;
  13. /**
  14. * Debugger panel that collects and displays timeline data.
  15. *
  16. * @property array $colors Color indicators item profile
  17. * @property float $duration Request duration, milliseconds. This property is read-only.
  18. * @property int $memory Memory peak in request, bytes. (obtained by memory_get_peak_usage()). This property is read-only.
  19. * @property \yii\base\Model[] $models Returns an array of models that represents logs of the current request. This property is read-only.
  20. * @property float $start Start request, timestamp (obtained by microtime(true)). This property is read-only.
  21. * @property array $svgOptions
  22. *
  23. * @author Dmitriy Bashkarev <dmitriy@bashkarev.com>
  24. * @since 2.0.7
  25. */
  26. class TimelinePanel extends Panel
  27. {
  28. /**
  29. * @var array Color indicators item profile.
  30. *
  31. * - keys: percentages of time request
  32. * - values: hex color
  33. */
  34. private $_colors = [
  35. 20 => '#1e6823',
  36. 10 => '#44a340',
  37. 1 => '#8cc665'
  38. ];
  39. /**
  40. * @var array log messages extracted to array as models, to use with data provider.
  41. */
  42. private $_models;
  43. /**
  44. * @var float Start request, timestamp (obtained by microtime(true))
  45. */
  46. private $_start;
  47. /**
  48. * @var float End request, timestamp (obtained by microtime(true))
  49. */
  50. private $_end;
  51. /**
  52. * @var float Request duration, milliseconds
  53. */
  54. private $_duration;
  55. /**
  56. * @var Svg|null
  57. */
  58. private $_svg;
  59. /**
  60. * @var array
  61. */
  62. private $_svgOptions = [
  63. 'class' => 'yii\debug\models\timeline\Svg'
  64. ];
  65. /**
  66. * @var int Used memory in request
  67. */
  68. private $_memory;
  69. /**
  70. * {@inheritdoc}
  71. * @throws InvalidConfigException
  72. */
  73. public function init()
  74. {
  75. if (!isset($this->module->panels['profiling'])) {
  76. throw new InvalidConfigException('Unable to determine the profiling panel');
  77. }
  78. parent::init();
  79. }
  80. /**
  81. * {@inheritdoc}
  82. */
  83. public function getName()
  84. {
  85. return 'Timeline';
  86. }
  87. /**
  88. * {@inheritdoc}
  89. */
  90. public function getDetail()
  91. {
  92. $searchModel = new Search();
  93. $dataProvider = $searchModel->search(Yii::$app->request->getQueryParams(), $this);
  94. return Yii::$app->view->render('panels/timeline/detail', [
  95. 'panel' => $this,
  96. 'dataProvider' => $dataProvider,
  97. 'searchModel' => $searchModel,
  98. ]);
  99. }
  100. /**
  101. * {@inheritdoc}
  102. */
  103. public function load($data)
  104. {
  105. if (!isset($data['start']) || empty($data['start'])) {
  106. throw new \RuntimeException('Unable to determine request start time');
  107. }
  108. $this->_start = $data['start'] * 1000;
  109. if (!isset($data['end']) || empty($data['end'])) {
  110. throw new \RuntimeException('Unable to determine request end time');
  111. }
  112. $this->_end = $data['end'] * 1000;
  113. if (isset($this->module->panels['profiling']->data['time'])) {
  114. $this->_duration = $this->module->panels['profiling']->data['time'] * 1000;
  115. } else {
  116. $this->_duration = $this->_end - $this->_start;
  117. }
  118. if ($this->_duration <= 0) {
  119. throw new \RuntimeException('Duration cannot be zero');
  120. }
  121. if (!isset($data['memory']) || empty($data['memory'])) {
  122. throw new \RuntimeException('Unable to determine used memory in request');
  123. }
  124. $this->_memory = $data['memory'];
  125. }
  126. /**
  127. * {@inheritdoc}
  128. */
  129. public function save()
  130. {
  131. return [
  132. 'start' => YII_BEGIN_TIME,
  133. 'end' => microtime(true),
  134. 'memory' => memory_get_peak_usage(),
  135. ];
  136. }
  137. /**
  138. * Sets color indicators.
  139. * key: percentages of time request, value: hex color
  140. * @param array $colors
  141. */
  142. public function setColors($colors)
  143. {
  144. krsort($colors);
  145. $this->_colors = $colors;
  146. }
  147. /**
  148. * Color indicators item profile,
  149. * key: percentages of time request, value: hex color
  150. * @return array
  151. */
  152. public function getColors()
  153. {
  154. return $this->_colors;
  155. }
  156. /**
  157. * @param array $options
  158. */
  159. public function setSvgOptions($options)
  160. {
  161. if ($this->_svg !== null) {
  162. $this->_svg = null;
  163. }
  164. $this->_svgOptions = array_merge($this->_svgOptions, $options);
  165. }
  166. /**
  167. * @return array
  168. */
  169. public function getSvgOptions()
  170. {
  171. return $this->_svgOptions;
  172. }
  173. /**
  174. * Start request, timestamp (obtained by microtime(true))
  175. * @return float
  176. */
  177. public function getStart()
  178. {
  179. return $this->_start;
  180. }
  181. /**
  182. * Request duration, milliseconds
  183. * @return float
  184. */
  185. public function getDuration()
  186. {
  187. return $this->_duration;
  188. }
  189. /**
  190. * Memory peak in request, bytes. (obtained by memory_get_peak_usage())
  191. * @return int
  192. * @since 2.0.8
  193. */
  194. public function getMemory()
  195. {
  196. return $this->_memory;
  197. }
  198. /**
  199. * @return Svg
  200. * @since 2.0.8
  201. * @throws InvalidConfigException
  202. */
  203. public function getSvg()
  204. {
  205. if ($this->_svg === null) {
  206. $this->_svg = Yii::createObject($this->_svgOptions, [$this]);
  207. }
  208. return $this->_svg;
  209. }
  210. /**
  211. * Returns an array of models that represents logs of the current request.
  212. * Can be used with data providers, such as \yii\data\ArrayDataProvider.
  213. *
  214. * @param bool $refresh if need to build models from log messages and refresh them.
  215. * @return array models
  216. */
  217. protected function getModels($refresh = false)
  218. {
  219. if ($this->_models === null || $refresh) {
  220. $this->_models = [];
  221. if (isset($this->module->panels['profiling']->data['messages'])) {
  222. $this->_models = Yii::getLogger()->calculateTimings($this->module->panels['profiling']->data['messages']);
  223. }
  224. }
  225. return $this->_models;
  226. }
  227. }