Commit faf445bb by Qiang Xue

debugger wip

parent 26b47917
......@@ -21,7 +21,6 @@ class LogTarget extends Target
*/
public $module;
public $tag;
public $historySize = 20;
/**
* @param \yii\debug\Module $module
......@@ -31,7 +30,7 @@ class LogTarget extends Target
{
parent::__construct($config);
$this->module = $module;
$this->tag = date('Ymd-His', microtime(true));
$this->tag = uniqid();
}
/**
......@@ -40,16 +39,32 @@ class LogTarget extends Target
*/
public function export()
{
$path = Yii::$app->getRuntimePath() . '/debug';
$path = $this->module->dataPath;
if (!is_dir($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();
foreach ($this->module->panels as $id => $panel) {
$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
$this->messages = array_merge($this->messages, $messages);
if ($final) {
$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
* @var array|Panel[]
*/
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()
{
parent::init();
$this->dataPath = Yii::getAlias($this->dataPath);
$this->logTarget = Yii::$app->getLog()->targets['debug'] = new LogTarget($this);
Yii::$app->getView()->on(View::EVENT_END_BODY, array($this, 'renderToolbar'));
......@@ -84,9 +90,6 @@ class Module extends \yii\base\Module
protected function corePanels()
{
return array(
'config' => array(
'class' => 'yii\debug\panels\ConfigPanel',
),
'request' => array(
'class' => 'yii\debug\panels\RequestPanel',
),
......@@ -99,6 +102,9 @@ class Module extends \yii\base\Module
'db' => array(
'class' => 'yii\debug\panels\DbPanel',
),
'config' => array(
'class' => 'yii\debug\panels\ConfigPanel',
),
);
}
}
......@@ -23,7 +23,7 @@ class DefaultController extends Controller
public function actionIndex($tag, $panel = null)
{
$this->loadData($tag);
$meta = $this->loadData($tag);
if (isset($this->module->panels[$panel])) {
$activePanel = $this->module->panels[$panel];
} else {
......@@ -31,6 +31,8 @@ class DefaultController extends Controller
}
return $this->render('index', array(
'tag' => $tag,
'meta' => $meta,
'manifest' => $this->getManifest(),
'panels' => $this->module->panels,
'activePanel' => $activePanel,
));
......@@ -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)
{
$file = Yii::$app->getRuntimePath() . "/debug/$tag.log";
if (preg_match('/^[\w\-]+$/', $tag) && is_file($file)) {
$data = json_decode(file_get_contents($file), true);
$manifest = $this->getManifest();
if (isset($manifest[$tag])) {
$dataFile = $this->module->dataPath . "/$tag.json";
$data = json_decode(file_get_contents($dataFile), true);
foreach ($this->module->panels as $id => $panel) {
if (isset($data[$id])) {
$panel->load($data[$id]);
......@@ -58,6 +88,7 @@ class DefaultController extends Controller
unset($this->module->panels[$id]);
}
}
return $manifest[$tag];
} else {
throw new HttpException(404, "Unable to find debug data tagged with '$tag'.");
}
......
......@@ -26,7 +26,7 @@ class ConfigPanel extends Panel
return <<<EOD
<div class="yii-debug-toolbar-block">
PHP: {$this->data['phpVersion']},
Yii: {$this->data['phpVersion']}
Yii: {$this->data['yiiVersion']}
</div>
EOD;
}
......
......@@ -11,6 +11,7 @@ use Yii;
use yii\debug\Panel;
use yii\helpers\Html;
use yii\log\Logger;
use yii\log\Target;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
......@@ -25,12 +26,29 @@ class LogPanel extends Panel
public function getSummary()
{
$count = count($this->data['messages']);
$output = array();
$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">
Log messages: $count
$log
</div>
EOD;
} else {
return '';
}
}
public function getDetail()
......
......@@ -4,10 +4,14 @@ use yii\helpers\Html;
/**
* @var \yii\base\View $this
* @var array $meta
* @var string $tag
* @var array $manifest
* @var \yii\debug\Panel[] $panels
* @var \yii\debug\Panel $activePanel
*/
$this->registerAssetBundle('yii/bootstrap/dropdown');
?>
<div class="default-index">
<div class="navbar">
......@@ -21,8 +25,7 @@ use yii\helpers\Html;
<div class="container-fluid">
<div class="row-fluid">
<div class="span2">
<div class="well sidebar-nav">
<ul class="nav nav-list">
<ul class="nav nav-tabs nav-list nav-stacked">
<?php
foreach ($panels as $id => $panel) {
$link = Html::a(Html::encode($panel->getName()), array('debug/default/index', 'tag' => $tag, 'panel' => $id));
......@@ -30,9 +33,31 @@ use yii\helpers\Html;
}
?>
</ul>
</div><!--/.well -->
</div><!--/span-->
<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(); ?>
</div>
</div>
......
......@@ -27,10 +27,10 @@ use yii\helpers\Html;
</style>
<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 echo $panel->getSummary(); ?>
<?php endforeach; ?>
<div class="yii-debug-toolbar-block">
<?php echo Html::a('more details', array('index', 'tag' => $tag)); ?>
</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