diff --git a/extensions/debug/Module.php b/extensions/debug/Module.php index 8a20021..6c1e6e0 100644 --- a/extensions/debug/Module.php +++ b/extensions/debug/Module.php @@ -61,7 +61,8 @@ class Module extends \yii\base\Module Yii::$app->getView()->on(View::EVENT_END_BODY, [$this, 'renderToolbar']); }); - foreach (array_merge($this->corePanels(), $this->panels) as $id => $config) { + $this->panels = array_merge($this->corePanels(), $this->panels); + foreach ($this->panels as $id => $config) { $config['module'] = $this; $config['id'] = $id; $this->panels[$id] = Yii::createObject($config); diff --git a/extensions/debug/Panel.php b/extensions/debug/Panel.php index 055dbba..ebfa8b3 100644 --- a/extensions/debug/Panel.php +++ b/extensions/debug/Panel.php @@ -31,6 +31,12 @@ class Panel extends Component */ public $module; public $data; + /** + * @var array array of actions to add to the debug modules default controller. + * This array will be merged with all other panels actions property. + * See [[yii\base\Controller::actions()]] for the format. + */ + public $actions = []; /** * @return string name of the panel diff --git a/extensions/debug/controllers/DefaultController.php b/extensions/debug/controllers/DefaultController.php index 6694d26..0c8d6e9 100644 --- a/extensions/debug/controllers/DefaultController.php +++ b/extensions/debug/controllers/DefaultController.php @@ -27,6 +27,15 @@ class DefaultController extends Controller */ public $summary; + public function actions() + { + $actions = []; + foreach($this->module->panels as $panel) { + $actions = array_merge($actions, $panel->actions); + } + return $actions; + } + public function actionIndex() { return $this->render('index', ['manifest' => $this->getManifest()]); @@ -82,7 +91,7 @@ class DefaultController extends Controller return $this->_manifest; } - protected function loadData($tag) + public function loadData($tag) { $manifest = $this->getManifest(); if (isset($manifest[$tag])) { diff --git a/extensions/elasticsearch/Command.php b/extensions/elasticsearch/Command.php index 916d597..4b7b0a7 100644 --- a/extensions/elasticsearch/Command.php +++ b/extensions/elasticsearch/Command.php @@ -94,7 +94,7 @@ class Command extends Component */ public function get($index, $type, $id, $options = []) { - return $this->db->get([$index, $type, $id], $options, null, [200, 404]); + return $this->db->get([$index, $type, $id], $options, null); } /** diff --git a/extensions/elasticsearch/Connection.php b/extensions/elasticsearch/Connection.php index 098d6ee..75de7a3 100644 --- a/extensions/elasticsearch/Connection.php +++ b/extensions/elasticsearch/Connection.php @@ -177,10 +177,10 @@ class Connection extends Component return new QueryBuilder($this); } - public function get($url, $options = [], $body = null) + public function get($url, $options = [], $body = null, $raw = false) { $this->open(); - return $this->httpRequest('GET', $this->createUrl($url, $options), $body); + return $this->httpRequest('GET', $this->createUrl($url, $options), $body, $raw); } public function head($url, $options = [], $body = null) @@ -189,37 +189,43 @@ class Connection extends Component return $this->httpRequest('HEAD', $this->createUrl($url, $options), $body); } - public function post($url, $options = [], $body = null) + public function post($url, $options = [], $body = null, $raw = false) { $this->open(); - return $this->httpRequest('POST', $this->createUrl($url, $options), $body); + return $this->httpRequest('POST', $this->createUrl($url, $options), $body, $raw); } - public function put($url, $options = [], $body = null) + public function put($url, $options = [], $body = null, $raw = false) { $this->open(); - return $this->httpRequest('PUT', $this->createUrl($url, $options), $body); + return $this->httpRequest('PUT', $this->createUrl($url, $options), $body, $raw); } - public function delete($url, $options = [], $body = null) + public function delete($url, $options = [], $body = null, $raw = false) { $this->open(); - return $this->httpRequest('DELETE', $this->createUrl($url, $options), $body); + return $this->httpRequest('DELETE', $this->createUrl($url, $options), $body, $raw); } private function createUrl($path, $options = []) { - $url = implode('/', array_map(function($a) { - return urlencode(is_array($a) ? implode(',', $a) : $a); - }, $path)); - - if (!empty($options)) { - $url .= '?' . http_build_query($options); + if (!is_string($path)) { + $url = implode('/', array_map(function($a) { + return urlencode(is_array($a) ? implode(',', $a) : $a); + }, $path)); + if (!empty($options)) { + $url .= '?' . http_build_query($options); + } + } else { + $url = $path; + if (!empty($options)) { + $url .= (strpos($url, '?') === false ? '?' : '&') . http_build_query($options); + } } return [$this->nodes[$this->activeNode]['http_address'], $url]; } - protected function httpRequest($method, $url, $requestBody = null) + protected function httpRequest($method, $url, $requestBody = null, $raw = false) { $method = strtoupper($method); @@ -228,7 +234,7 @@ class Connection extends Component $body = ''; $options = [ - CURLOPT_USERAGENT => 'Yii2 Framework ' . __CLASS__, + CURLOPT_USERAGENT => 'Yii Framework 2 ' . __CLASS__, CURLOPT_RETURNTRANSFER => false, CURLOPT_HEADER => false, // http://www.php.net/manual/en/function.curl-setopt.php#82418 @@ -264,8 +270,11 @@ class Connection extends Component if (is_array($url)) { list($host, $q) = $url; - if (strncmp($host, 'inet[/', 6) == 0) { - $host = substr($host, 6, -1); + if (strncmp($host, 'inet[', 5) == 0) { + $host = substr($host, 5, -1); + if (($pos = strpos($host, '/')) !== false) { + $host = substr($host, $pos + 1); + } } $profile = $method . ' ' . $q . '#' . $requestBody; $url = 'http://' . $host . '/' . $q; @@ -312,7 +321,7 @@ class Connection extends Component ]); } if (isset($headers['content-type']) && !strncmp($headers['content-type'], 'application/json', 16)) { - return Json::decode($body); + return $raw ? $body : Json::decode($body); } throw new Exception('Unsupported data received from elasticsearch: ' . $headers['content-type'], [ 'requestMethod' => $method, diff --git a/extensions/elasticsearch/DebugAction.php b/extensions/elasticsearch/DebugAction.php new file mode 100644 index 0000000..d4ddd41 --- /dev/null +++ b/extensions/elasticsearch/DebugAction.php @@ -0,0 +1,76 @@ + + */ + +namespace yii\elasticsearch; + + +use yii\base\Action; +use yii\base\NotSupportedException; +use yii\debug\Panel; +use yii\helpers\ArrayHelper; +use yii\web\HttpException; +use Yii; +use yii\web\Response; + +class DebugAction extends Action +{ + /** + * @var string the connection id to use + */ + public $db; + /** + * @var Panel + */ + public $panel; + + public function run($logId, $tag) + { + $this->controller->loadData($tag); + + $timings = $this->panel->calculateTimings(); + ArrayHelper::multisort($timings, 3, SORT_DESC); + if (!isset($timings[$logId])) { + throw new HttpException(404, 'Log message not found.'); + } + $message = $timings[$logId][1]; + if (($pos = mb_strpos($message, "#")) !== false) { + $url = mb_substr($message, 0, $pos); + $body = mb_substr($message, $pos + 1); + } else { + $url = $message; + $body = null; + } + $method = mb_substr($url, 0, $pos = mb_strpos($url, ' ')); + $url = mb_substr($url, $pos + 1); + + $options = ['pretty' => true]; + + /** @var Connection $db */ + $db = \Yii::$app->getComponent($this->db); + $time = microtime(true); + switch($method) { + case 'GET': $result = $db->get($url, $options, $body, true); break; + case 'POST': $result = $db->post($url, $options, $body, true); break; + case 'PUT': $result = $db->put($url, $options, $body, true); break; + case 'DELETE': $result = $db->delete($url, $options, $body, true); break; + case 'HEAD': $result = $db->head($url, $options, $body); break; + default: + throw new NotSupportedException("Request method '$method' is not supported by elasticsearch."); + } + $time = microtime(true) - $time; + + if ($result === true) { + $result = 'success'; + } elseif ($result === false) { + $result = 'no success'; + } + + Yii::$app->response->format = Response::FORMAT_JSON; + return [ + 'time' => sprintf('%.1f ms', $time * 1000), + 'result' => $result, + ]; + } +} \ No newline at end of file diff --git a/extensions/elasticsearch/DebugPanel.php b/extensions/elasticsearch/DebugPanel.php index da5a824..1782b8d 100644 --- a/extensions/elasticsearch/DebugPanel.php +++ b/extensions/elasticsearch/DebugPanel.php @@ -8,6 +8,7 @@ namespace yii\elasticsearch; use yii\debug\Panel; +use yii\helpers\ArrayHelper; use yii\log\Logger; use yii\helpers\Html; use yii\web\View; @@ -20,6 +21,17 @@ use yii\web\View; */ class DebugPanel extends Panel { + public $db = 'elasticsearch'; + + public function init() + { + $this->actions['elasticsearch-query'] = [ + 'class' => 'yii\\elasticsearch\\DebugAction', + 'panel' => $this, + 'db' => $this->db, + ]; + } + public function getName() { return 'Elasticsearch'; @@ -47,13 +59,14 @@ EOD; public function getDetail() { + $timings = $this->calculateTimings(); + ArrayHelper::multisort($timings, 3, SORT_DESC); $rows = []; $i = 0; - foreach ($this->data['messages'] as $log) { - list ($message, $level, $category, $time, $traces) = $log; - if ($level == Logger::LEVEL_PROFILE_BEGIN) { - continue; - } + foreach ($timings as $logId => $timing) { + $duration = sprintf('%.1f ms', $timing[3] * 1000); + $message = $timing[1]; + $traces = $timing[4]; if (($pos = mb_strpos($message, "#")) !== false) { $url = mb_substr($message, 0, $pos); $body = mb_substr($message, $pos + 1); @@ -66,48 +79,43 @@ EOD; $traceString .= Html::ul($traces, [ 'class' => 'trace', 'item' => function ($trace) { - return "
$body
$traceString$body
$traceStringUrl / Query | -Run Query on node | +Time | +Url / Query | +Run Query on node |
---|