|
|
|
@ -9,9 +9,8 @@ namespace yii\debug\panels;
|
|
|
|
|
|
|
|
|
|
use Yii; |
|
|
|
|
use yii\debug\Panel; |
|
|
|
|
use yii\helpers\Html; |
|
|
|
|
use yii\log\Logger; |
|
|
|
|
use yii\log\Target; |
|
|
|
|
use yii\debug\models\search\Log; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Debugger panel that collects and displays logs. |
|
|
|
@ -21,6 +20,12 @@ use yii\log\Target;
|
|
|
|
|
*/ |
|
|
|
|
class LogPanel extends Panel |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* @var array log messages extracted to array as models, to use with data provider. |
|
|
|
|
*/ |
|
|
|
|
private $_models ; |
|
|
|
|
|
|
|
|
|
public function getName() |
|
|
|
|
{ |
|
|
|
|
return 'Logs'; |
|
|
|
@ -28,72 +33,19 @@ class LogPanel extends Panel
|
|
|
|
|
|
|
|
|
|
public function getSummary() |
|
|
|
|
{ |
|
|
|
|
$output = ['<span class="label">' . count($this->data['messages']) . '</span>']; |
|
|
|
|
$title = 'Logged ' . count($this->data['messages']) . ' messages'; |
|
|
|
|
$errorCount = count(Target::filterMessages($this->data['messages'], Logger::LEVEL_ERROR)); |
|
|
|
|
if ($errorCount) { |
|
|
|
|
$output[] = '<span class="label label-important">' . $errorCount . '</span>'; |
|
|
|
|
$title .= ", $errorCount errors"; |
|
|
|
|
} |
|
|
|
|
$warningCount = count(Target::filterMessages($this->data['messages'], Logger::LEVEL_WARNING)); |
|
|
|
|
if ($warningCount) { |
|
|
|
|
$output[] = '<span class="label label-warning">' . $warningCount . '</span>'; |
|
|
|
|
$title .= ", $warningCount warnings"; |
|
|
|
|
} |
|
|
|
|
$log = implode(' ', $output); |
|
|
|
|
$url = $this->getUrl(); |
|
|
|
|
return <<<EOD |
|
|
|
|
<div class="yii-debug-toolbar-block"> |
|
|
|
|
<a href="$url" title="$title">Log $log</a> |
|
|
|
|
</div> |
|
|
|
|
EOD; |
|
|
|
|
return Yii::$app->view->render('panels/log/summary',['data' => $this->data, 'panel' => $this]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public function getDetail() |
|
|
|
|
{ |
|
|
|
|
$rows = []; |
|
|
|
|
foreach ($this->data['messages'] as $log) { |
|
|
|
|
list ($message, $level, $category, $time, $traces) = $log; |
|
|
|
|
$time = date('H:i:s.', $time) . sprintf('%03d', (int)(($time - (int)$time) * 1000)); |
|
|
|
|
$message = nl2br(Html::encode($message)); |
|
|
|
|
if (!empty($traces)) { |
|
|
|
|
$message .= Html::ul($traces, [ |
|
|
|
|
'class' => 'trace', |
|
|
|
|
'item' => function ($trace) { |
|
|
|
|
return "<li>{$trace['file']}({$trace['line']})</li>"; |
|
|
|
|
}, |
|
|
|
|
]); |
|
|
|
|
} |
|
|
|
|
if ($level == Logger::LEVEL_ERROR) { |
|
|
|
|
$class = ' class="danger"'; |
|
|
|
|
} elseif ($level == Logger::LEVEL_WARNING) { |
|
|
|
|
$class = ' class="warning"'; |
|
|
|
|
} elseif ($level == Logger::LEVEL_INFO) { |
|
|
|
|
$class = ' class="success"'; |
|
|
|
|
} else { |
|
|
|
|
$class = ''; |
|
|
|
|
} |
|
|
|
|
$level = Logger::getLevelName($level); |
|
|
|
|
$rows[] = "<tr$class><td style=\"width: 100px;\">$time</td><td style=\"width: 100px;\">$level</td><td style=\"width: 250px;\">$category</td><td><div>$message</div></td></tr>"; |
|
|
|
|
} |
|
|
|
|
$rows = implode("\n", $rows); |
|
|
|
|
return <<<EOD |
|
|
|
|
<h1>Log Messages</h1> |
|
|
|
|
$searchModel = new Log(); |
|
|
|
|
$dataProvider = $searchModel->search($_GET, $this->getModels()); |
|
|
|
|
|
|
|
|
|
<table class="table table-condensed table-bordered table-striped table-hover" style="table-layout: fixed;"> |
|
|
|
|
<thead> |
|
|
|
|
<tr> |
|
|
|
|
<th style="width: 100px;">Time</th> |
|
|
|
|
<th style="width: 65px;">Level</th> |
|
|
|
|
<th style="width: 250px;">Category</th> |
|
|
|
|
<th>Message</th> |
|
|
|
|
</tr> |
|
|
|
|
</thead> |
|
|
|
|
<tbody> |
|
|
|
|
$rows |
|
|
|
|
</tbody> |
|
|
|
|
</table> |
|
|
|
|
EOD; |
|
|
|
|
return Yii::$app->view->render('panels/log/detail',[ |
|
|
|
|
'dataProvider' => $dataProvider, |
|
|
|
|
'panel' => $this, |
|
|
|
|
'searchModel' => $searchModel, |
|
|
|
|
]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public function save() |
|
|
|
@ -102,4 +54,29 @@ EOD;
|
|
|
|
|
$messages = $target->filterMessages($target->messages, Logger::LEVEL_ERROR | Logger::LEVEL_INFO | Logger::LEVEL_WARNING | Logger::LEVEL_TRACE); |
|
|
|
|
return ['messages' => $messages]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Returns array of models that represents logs of the current request. Can be used with data providers, |
|
|
|
|
* like yii\data\ArrayDataProvider. |
|
|
|
|
* @param boolean $refresh if needed to build models from log messages and refresh them. |
|
|
|
|
* @return array models |
|
|
|
|
*/ |
|
|
|
|
protected function getModels($refresh=false) |
|
|
|
|
{ |
|
|
|
|
if ($this->_models === null || $refresh) { |
|
|
|
|
$this->_models = []; |
|
|
|
|
|
|
|
|
|
foreach($this->data['messages'] as $message) { |
|
|
|
|
$this->_models[] = [ |
|
|
|
|
'message' => $message[0], |
|
|
|
|
'level' => $message[1], |
|
|
|
|
'category' => $message[2], |
|
|
|
|
'time' => ($message[3] * 1000), #time in milliseconds |
|
|
|
|
'trace' => $message[4] |
|
|
|
|
]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return $this->_models; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|