added debug panel for elasticsearch

This commit is contained in:
Carsten Brandt
2013-12-01 14:17:56 +01:00
parent 494e3e3f23
commit 4565df9313
3 changed files with 195 additions and 1 deletions

View File

@ -267,7 +267,7 @@ class Connection extends Component
if (strncmp($host, 'inet[/', 6) == 0) {
$host = substr($host, 6, -1);
}
$profile = $q . $requestBody;
$profile = $method . ' ' . $q . '#' . $requestBody;
$url = 'http://' . $host . '/' . $q;
} else {
$profile = false;

View File

@ -0,0 +1,168 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\elasticsearch;
use yii\debug\Panel;
use yii\log\Logger;
use yii\helpers\Html;
use yii\web\View;
/**
* Debugger panel that collects and displays elasticsearch queries performed.
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class DebugPanel extends Panel
{
public function getName()
{
return 'Elasticsearch';
}
public function getSummary()
{
$timings = $this->calculateTimings();
$queryCount = count($timings);
$queryTime = 0;
foreach ($timings as $timing) {
$queryTime += $timing[3];
}
$queryTime = number_format($queryTime * 1000) . ' ms';
$url = $this->getUrl();
$output = <<<EOD
<div class="yii-debug-toolbar-block">
<a href="$url" title="Executed $queryCount elasticsearch queries which took $queryTime.">
ES <span class="label">$queryCount</span> <span class="label">$queryTime</span>
</a>
</div>
EOD;
return $queryCount > 0 ? $output : '';
}
public function getDetail()
{
$rows = [];
$i = 0;
foreach ($this->data['messages'] as $log) {
list ($message, $level, $category, $time, $traces) = $log;
if ($level == Logger::LEVEL_PROFILE_BEGIN) {
continue;
}
if (($pos = mb_strpos($message, "#")) !== false) {
$url = mb_substr($message, 0, $pos);
$body = mb_substr($message, $pos + 1);
} else {
$url = $message;
$body = null;
}
$traceString = '';
if (!empty($traces)) {
$traceString .= Html::ul($traces, [
'class' => 'trace',
'item' => function ($trace) {
return "<li>{$trace['file']}({$trace['line']})</li>";
},
]);
}
$runLinks = '';
$c = 0;
\Yii::$app->elasticsearch->open();
foreach(\Yii::$app->elasticsearch->nodes as $node) {
$pos = mb_strpos($url, ' ');
$type = mb_substr($url, 0, $pos);
if ($type == 'GET' && !empty($body)) {
$type = 'POST';
}
$host = $node['http_address'];
if (strncmp($host, 'inet[/', 6) == 0) {
$host = substr($host, 6, -1);
}
$nodeUrl = 'http://' . $host . '/' . mb_substr($url, $pos + 1);
$nodeUrl .= (strpos($nodeUrl, '?') === false) ? '?pretty=true' : '&pretty=true';
$nodeBody = json_encode($body);
\Yii::$app->view->registerJs(<<<JS
$('#elastic-link-$i-$c').on('click', function() {
$('#elastic-result-$i').html('Sending $type request to $nodeUrl...');
$('#elastic-result-$i').parent('tr').show();
$.ajax({
type: "$type",
url: "$nodeUrl",
body: $nodeBody,
success: function( data ) {
$('#elastic-result-$i').html(data);
},
dataType: "text"
});
return false;
});
JS
, View::POS_READY);
$runLinks .= Html::a(isset($node['name']) ? $node['name'] : $node['http_address'], '#', ['id' => "elastic-link-$i-$c"]) . '<br/>';
$c++;
}
$rows[] = "<tr><td style=\"width: 80%;\"><div><b>$url</b><br/><p>$body</p>$traceString</div></td><td style=\"width: 20%;\">$runLinks</td></tr><tr style=\"display: none;\"><td colspan=\"2\" id=\"elastic-result-$i\"></td></tr>";
$i++;
}
$rows = implode("\n", $rows);
return <<<HTML
<h1>Elasticsearch Queries</h1>
<table class="table table-condensed table-bordered table-striped table-hover" style="table-layout: fixed;">
<thead>
<tr>
<th style="width: 80%;">Url / Query</th>
<th style="width: 20%;">Run Query on node</th>
</tr>
</thead>
<tbody>
$rows
</tbody>
</table>
HTML;
}
private $_timings;
protected function calculateTimings()
{
if ($this->_timings !== null) {
return $this->_timings;
}
$messages = $this->data['messages'];
$timings = [];
$stack = [];
foreach ($messages as $i => $log) {
list($token, $level, $category, $timestamp) = $log;
$log[5] = $i;
if ($level == Logger::LEVEL_PROFILE_BEGIN) {
$stack[] = $log;
} elseif ($level == Logger::LEVEL_PROFILE_END) {
if (($last = array_pop($stack)) !== null && $last[0] === $token) {
$timings[$last[5]] = [count($stack), $token, $last[3], $timestamp - $last[3], $last[4]];
}
}
}
$now = microtime(true);
while (($last = array_pop($stack)) !== null) {
$delta = $now - $last[3];
$timings[$last[5]] = [count($stack), $last[0], $last[2], $delta, $last[4]];
}
ksort($timings);
return $this->_timings = $timings;
}
public function save()
{
$target = $this->module->logTarget;
$messages = $target->filterMessages($target->messages, Logger::LEVEL_PROFILE, ['yii\elasticsearch\Connection::httpRequest']);
return ['messages' => $messages];
}
}

View File

@ -146,3 +146,29 @@ $query->search(); // gives you all the records + stats about the visit_count fie
```
And there is so much more in it. "its endless what you can build"[¹](http://www.elasticsearch.org/)
Using the elasticsearch DebugPanel
----------------------------------
The yii2 elasticsearch extensions provides a `DebugPanel` that can be integrated with the yii debug module
an shows the executed elasticsearch queries. It also allows to run these queries on different cluster nodes
an view the results.
Add the following to you application config to enable it:
```php
// ...
'preload' => 'debug',
'modules' => [
'debug' => [
'class' => 'yii\\debug\\Module',
'panels' => [
'elasticsearch' => [
'class' => 'yii\\elasticsearch\\DebugPanel',
],
],
],
],
// ...
```