TimelinePanel.php 5.8 KB

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