Commit faf445bb by Qiang Xue

debugger wip

parent 26b47917
...@@ -21,7 +21,6 @@ class LogTarget extends Target ...@@ -21,7 +21,6 @@ class LogTarget extends Target
*/ */
public $module; public $module;
public $tag; public $tag;
public $historySize = 20;
/** /**
* @param \yii\debug\Module $module * @param \yii\debug\Module $module
...@@ -31,7 +30,7 @@ class LogTarget extends Target ...@@ -31,7 +30,7 @@ class LogTarget extends Target
{ {
parent::__construct($config); parent::__construct($config);
$this->module = $module; $this->module = $module;
$this->tag = date('Ymd-His', microtime(true)); $this->tag = uniqid();
} }
/** /**
...@@ -40,16 +39,32 @@ class LogTarget extends Target ...@@ -40,16 +39,32 @@ class LogTarget extends Target
*/ */
public function export() public function export()
{ {
$path = Yii::$app->getRuntimePath() . '/debug'; $path = $this->module->dataPath;
if (!is_dir($path)) { if (!is_dir($path)) {
mkdir($path); mkdir($path);
} }
$file = "$path/{$this->tag}.log"; $indexFile = "$path/index.json";
if (!is_file($indexFile)) {
$manifest = array();
} else {
$manifest = json_decode(file_get_contents($indexFile), true);
}
$request = Yii::$app->getRequest();
$manifest[$this->tag] = array(
'url' => $request->getAbsoluteUrl(),
'ajax' => $request->getIsAjax(),
'method' => $request->getMethod(),
'ip' => $request->getUserIP(),
'time' => time(),
);
$dataFile = "$path/{$this->tag}.json";
$data = array(); $data = array();
foreach ($this->module->panels as $id => $panel) { foreach ($this->module->panels as $id => $panel) {
$data[$id] = $panel->save(); $data[$id] = $panel->save();
} }
file_put_contents($file, json_encode($data)); file_put_contents($dataFile, json_encode($data));
file_put_contents($indexFile, json_encode($manifest));
} }
/** /**
...@@ -65,33 +80,6 @@ class LogTarget extends Target ...@@ -65,33 +80,6 @@ class LogTarget extends Target
$this->messages = array_merge($this->messages, $messages); $this->messages = array_merge($this->messages, $messages);
if ($final) { if ($final) {
$this->export($this->messages); $this->export($this->messages);
$this->gc();
}
}
protected function gc()
{
if (mt_rand(0, 10000) > 100) {
return;
}
$iterator = new \DirectoryIterator(Yii::$app->getRuntimePath() . '/debug');
$files = array();
foreach ($iterator as $file) {
/** @var \DirectoryIterator $file */
if (preg_match('/^[\d\-]+\.log$/', $file->getFileName()) && $file->isFile()) {
$files[] = $file->getPathname();
}
}
sort($files);
if (count($files) > $this->historySize) {
$n = count($files) - $this->historySize;
foreach ($files as $i => $file) {
if ($i < $n) {
unlink($file);
} else {
break;
}
}
} }
} }
} }
...@@ -35,11 +35,17 @@ class Module extends \yii\base\Module ...@@ -35,11 +35,17 @@ class Module extends \yii\base\Module
* @var array|Panel[] * @var array|Panel[]
*/ */
public $panels = array(); public $panels = array();
/**
* @var string the directory storing the debugger data files. This can be specified using a path alias.
*/
public $dataPath = '@runtime/debug';
public $historySize = 5;
public function init() public function init()
{ {
parent::init(); parent::init();
$this->dataPath = Yii::getAlias($this->dataPath);
$this->logTarget = Yii::$app->getLog()->targets['debug'] = new LogTarget($this); $this->logTarget = Yii::$app->getLog()->targets['debug'] = new LogTarget($this);
Yii::$app->getView()->on(View::EVENT_END_BODY, array($this, 'renderToolbar')); Yii::$app->getView()->on(View::EVENT_END_BODY, array($this, 'renderToolbar'));
...@@ -84,9 +90,6 @@ class Module extends \yii\base\Module ...@@ -84,9 +90,6 @@ class Module extends \yii\base\Module
protected function corePanels() protected function corePanels()
{ {
return array( return array(
'config' => array(
'class' => 'yii\debug\panels\ConfigPanel',
),
'request' => array( 'request' => array(
'class' => 'yii\debug\panels\RequestPanel', 'class' => 'yii\debug\panels\RequestPanel',
), ),
...@@ -99,6 +102,9 @@ class Module extends \yii\base\Module ...@@ -99,6 +102,9 @@ class Module extends \yii\base\Module
'db' => array( 'db' => array(
'class' => 'yii\debug\panels\DbPanel', 'class' => 'yii\debug\panels\DbPanel',
), ),
'config' => array(
'class' => 'yii\debug\panels\ConfigPanel',
),
); );
} }
} }
...@@ -23,7 +23,7 @@ class DefaultController extends Controller ...@@ -23,7 +23,7 @@ class DefaultController extends Controller
public function actionIndex($tag, $panel = null) public function actionIndex($tag, $panel = null)
{ {
$this->loadData($tag); $meta = $this->loadData($tag);
if (isset($this->module->panels[$panel])) { if (isset($this->module->panels[$panel])) {
$activePanel = $this->module->panels[$panel]; $activePanel = $this->module->panels[$panel];
} else { } else {
...@@ -31,6 +31,8 @@ class DefaultController extends Controller ...@@ -31,6 +31,8 @@ class DefaultController extends Controller
} }
return $this->render('index', array( return $this->render('index', array(
'tag' => $tag, 'tag' => $tag,
'meta' => $meta,
'manifest' => $this->getManifest(),
'panels' => $this->module->panels, 'panels' => $this->module->panels,
'activePanel' => $activePanel, 'activePanel' => $activePanel,
)); ));
...@@ -45,11 +47,39 @@ class DefaultController extends Controller ...@@ -45,11 +47,39 @@ class DefaultController extends Controller
)); ));
} }
private $_manifest;
protected function getManifest()
{
if ($this->_manifest === null) {
$indexFile = $this->module->dataPath . '/index.json';
if (is_file($indexFile)) {
$this->_manifest = json_decode(file_get_contents($indexFile), true);
} else {
$this->_manifest = array();
}
if (count($this->_manifest) > $this->module->historySize) {
$n = count($this->_manifest) - $this->module->historySize;
foreach (array_keys($this->_manifest) as $tag) {
$file = $this->module->dataPath . "/$tag.json";
@unlink($file);
unset($this->_manifest[$tag]);
if (--$n <= 0) {
break;
}
}
file_put_contents($indexFile, json_encode($this->_manifest));
}
}
return $this->_manifest;
}
protected function loadData($tag) protected function loadData($tag)
{ {
$file = Yii::$app->getRuntimePath() . "/debug/$tag.log"; $manifest = $this->getManifest();
if (preg_match('/^[\w\-]+$/', $tag) && is_file($file)) { if (isset($manifest[$tag])) {
$data = json_decode(file_get_contents($file), true); $dataFile = $this->module->dataPath . "/$tag.json";
$data = json_decode(file_get_contents($dataFile), true);
foreach ($this->module->panels as $id => $panel) { foreach ($this->module->panels as $id => $panel) {
if (isset($data[$id])) { if (isset($data[$id])) {
$panel->load($data[$id]); $panel->load($data[$id]);
...@@ -58,6 +88,7 @@ class DefaultController extends Controller ...@@ -58,6 +88,7 @@ class DefaultController extends Controller
unset($this->module->panels[$id]); unset($this->module->panels[$id]);
} }
} }
return $manifest[$tag];
} else { } else {
throw new HttpException(404, "Unable to find debug data tagged with '$tag'."); throw new HttpException(404, "Unable to find debug data tagged with '$tag'.");
} }
......
...@@ -26,7 +26,7 @@ class ConfigPanel extends Panel ...@@ -26,7 +26,7 @@ class ConfigPanel extends Panel
return <<<EOD return <<<EOD
<div class="yii-debug-toolbar-block"> <div class="yii-debug-toolbar-block">
PHP: {$this->data['phpVersion']}, PHP: {$this->data['phpVersion']},
Yii: {$this->data['phpVersion']} Yii: {$this->data['yiiVersion']}
</div> </div>
EOD; EOD;
} }
......
...@@ -11,6 +11,7 @@ use Yii; ...@@ -11,6 +11,7 @@ use Yii;
use yii\debug\Panel; use yii\debug\Panel;
use yii\helpers\Html; use yii\helpers\Html;
use yii\log\Logger; use yii\log\Logger;
use yii\log\Target;
/** /**
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
...@@ -25,12 +26,29 @@ class LogPanel extends Panel ...@@ -25,12 +26,29 @@ class LogPanel extends Panel
public function getSummary() public function getSummary()
{ {
$count = count($this->data['messages']); $output = array();
return <<<EOD $errorCount = count(Target::filterMessages($this->data['messages'], Logger::LEVEL_ERROR));
if ($errorCount === 1) {
$output[] = '1 error';
} elseif ($errorCount > 1) {
$output[] = "$errorCount errors";
}
$warningCount = count(Target::filterMessages($this->data['messages'], Logger::LEVEL_WARNING));
if ($warningCount === 1) {
$output[] = '1 warning';
} elseif ($warningCount > 1) {
$output[] = "$warningCount warnings";
}
if (!empty($output)) {
$log = implode(', ', $output);
return <<<EOD
<div class="yii-debug-toolbar-block"> <div class="yii-debug-toolbar-block">
Log messages: $count $log
</div> </div>
EOD; EOD;
} else {
return '';
}
} }
public function getDetail() public function getDetail()
......
...@@ -4,10 +4,14 @@ use yii\helpers\Html; ...@@ -4,10 +4,14 @@ use yii\helpers\Html;
/** /**
* @var \yii\base\View $this * @var \yii\base\View $this
* @var array $meta
* @var string $tag * @var string $tag
* @var array $manifest
* @var \yii\debug\Panel[] $panels * @var \yii\debug\Panel[] $panels
* @var \yii\debug\Panel $activePanel * @var \yii\debug\Panel $activePanel
*/ */
$this->registerAssetBundle('yii/bootstrap/dropdown');
?> ?>
<div class="default-index"> <div class="default-index">
<div class="navbar"> <div class="navbar">
...@@ -21,8 +25,7 @@ use yii\helpers\Html; ...@@ -21,8 +25,7 @@ use yii\helpers\Html;
<div class="container-fluid"> <div class="container-fluid">
<div class="row-fluid"> <div class="row-fluid">
<div class="span2"> <div class="span2">
<div class="well sidebar-nav"> <ul class="nav nav-tabs nav-list nav-stacked">
<ul class="nav nav-list">
<?php <?php
foreach ($panels as $id => $panel) { foreach ($panels as $id => $panel) {
$link = Html::a(Html::encode($panel->getName()), array('debug/default/index', 'tag' => $tag, 'panel' => $id)); $link = Html::a(Html::encode($panel->getName()), array('debug/default/index', 'tag' => $tag, 'panel' => $id));
...@@ -30,9 +33,31 @@ use yii\helpers\Html; ...@@ -30,9 +33,31 @@ use yii\helpers\Html;
} }
?> ?>
</ul> </ul>
</div><!--/.well -->
</div><!--/span--> </div><!--/span-->
<div class="span10"> <div class="span10">
<div class="meta alert alert-info">
<div class="btn-group">
<button class="btn dropdown-toggle" data-toggle="dropdown">
View others
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<?php foreach ($manifest as $tag2 => $meta2) {
$label = $meta2['method'] . ' ' . $meta2['url'] . ($meta2['ajax'] ? ' (AJAX)' : '')
. ', ' . date('Y/m/d h:i:sa', $meta2['time'])
. ', ' . $meta2['ip'] . ', ' . $tag2;
$url = array('debug/default/index', 'tag' => $tag2);
echo '<li>' . Html::a(Html::encode($label), $url) . '</li>';
} ?>
</ul>
</div>
Debugging:
<?php echo $meta['method']; ?>
<?php echo Html::a(Html::encode($meta['url']), $meta['url']); ?>
<?php echo $meta['ajax'] ? ' (AJAX)' : ''; ?>
at <?php echo date('Y/m/d h:i:sa', $meta['time']); ?>
by <?php echo $meta['ip']; ?>
</div>
<?php echo $activePanel->getDetail(); ?> <?php echo $activePanel->getDetail(); ?>
</div> </div>
</div> </div>
......
...@@ -27,10 +27,10 @@ use yii\helpers\Html; ...@@ -27,10 +27,10 @@ use yii\helpers\Html;
</style> </style>
<div id="yii-debug-toolbar"> <div id="yii-debug-toolbar">
<div class="yii-debug-toolbar-block">
<?php echo Html::a('Yii Debugger', array('index', 'tag' => $tag)); ?>
</div>
<?php foreach ($panels as $panel): ?> <?php foreach ($panels as $panel): ?>
<?php echo $panel->getSummary(); ?> <?php echo $panel->getSummary(); ?>
<?php endforeach; ?> <?php endforeach; ?>
<div class="yii-debug-toolbar-block">
<?php echo Html::a('more details', array('index', 'tag' => $tag)); ?>
</div>
</div> </div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment