diff --git a/panels/arangodb/ArangoDbPanel.php b/panels/arangodb/ArangoDbPanel.php new file mode 100644 index 0000000..52954ea --- /dev/null +++ b/panels/arangodb/ArangoDbPanel.php @@ -0,0 +1,138 @@ +module->logTarget; + + return $target->filterMessages( + $target->messages, + Logger::LEVEL_PROFILE, + [ + 'devgroup\arangodb\Query::query', + 'devgroup\arangodb\Query::execute', + ] + ); + } + + /** + * Calculates given request profile timings. + * + * @return array timings [token, category, timestamp, traces, nesting level, elapsed time] + */ + protected function calculateTimings() + { + if ($this->_timings === null) { + $this->_timings = Yii::getLogger()->calculateTimings($this->data['arango-messages']); + } + + return $this->_timings; + } + + /** + * Returns total query time. + * + * @param array $timings + * @return integer total time + */ + protected function getTotalQueryTime($timings) + { + $queryTime = 0; + + foreach ($timings as $timing) { + $queryTime += $timing['duration']; + } + + return $queryTime; + } + + public function getName() + { + return 'Arango'; + } + + public function getSummary() + { + $timings = $this->calculateTimings(); + $queryCount = count($timings); + $queryTime = number_format($this->getTotalQueryTime($timings) * 1000) . ' ms'; + + return \Yii::$app->view->render( + '@devgroup/arangodb/panels/arangodb/views/summary', + [ + 'timings' => $this->calculateTimings(), + 'queryCount' => $queryCount, + 'queryTime' => $queryTime, + 'panel' => $this, + ] + ); + } + + /** + * @inheritdoc + */ + public function getDetail() + { + $searchModel = new ArangoDb(); + $dataProvider = $searchModel->search(Yii::$app->request->getQueryParams(), $this->getModels()); + + return Yii::$app->view->render('@devgroup/arangodb/panels/arangodb/views/detail', [ + 'panel' => $this, + 'dataProvider' => $dataProvider, + 'searchModel' => $searchModel, + ]); + } + + /** + * Returns an array of models that represents logs of the current request. + * Can be used with data providers such as \yii\data\ArrayDataProvider. + * @return array models + */ + protected function getModels() + { + if ($this->_models === null) { + $this->_models = []; + $timings = $this->calculateTimings(); + + foreach ($timings as $seq => $dbTiming) { + $this->_models[] = [ + 'query' => $dbTiming['info'], + 'duration' => ($dbTiming['duration'] * 1000), // in milliseconds + 'trace' => $dbTiming['trace'], + 'timestamp' => ($dbTiming['timestamp'] * 1000), // in milliseconds + 'seq' => $seq, + ]; + } + } + + return $this->_models; + } + + public function save() + { + return ['arango-messages' => $this->getProfileLogs()]; + } +} \ No newline at end of file diff --git a/panels/arangodb/models/ArangoDb.php b/panels/arangodb/models/ArangoDb.php new file mode 100644 index 0000000..e7747f8 --- /dev/null +++ b/panels/arangodb/models/ArangoDb.php @@ -0,0 +1,67 @@ + 'Query', + ]; + } + + /** + * Returns data provider with filled models. Filter applied if needed. + * + * @param array $params an array of parameter values indexed by parameter names + * @param array $models data to return provider for + * @return \yii\data\ArrayDataProvider + */ + public function search($params, $models) + { + $dataProvider = new ArrayDataProvider([ + 'allModels' => $models, + 'pagination' => false, + 'sort' => [ + 'attributes' => ['duration', 'seq', 'query'], + 'defaultOrder' => [ + 'duration' => SORT_DESC, + ], + ], + ]); + + if (!($this->load($params) && $this->validate())) { + return $dataProvider; + } + + $filter = new Filter(); + $this->addCondition($filter, 'query', true); + $dataProvider->allModels = $filter->filter($models); + + return $dataProvider; + } +} diff --git a/panels/arangodb/views/detail.php b/panels/arangodb/views/detail.php new file mode 100644 index 0000000..c70a83b --- /dev/null +++ b/panels/arangodb/views/detail.php @@ -0,0 +1,69 @@ + +