From 20666567e8bc0d60f54446e96045ba451632005c Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Thu, 27 Jun 2013 21:50:38 -0400 Subject: [PATCH] debug toolbar WIP --- framework/yii/base/View.php | 14 +++- framework/yii/debug/Debugger.php | 54 +++++++++++++ framework/yii/debug/LogTarget.php | 93 ++++++++++++++++++++++ framework/yii/debug/Module.php | 1 + framework/yii/debug/Toolbar.php | 38 --------- .../yii/debug/controllers/DefaultController.php | 9 ++- framework/yii/debug/views/default/index.php | 1 + framework/yii/debug/views/default/toolbar.php | 27 ++++--- framework/yii/debug/views/layouts/main.php | 21 +++++ framework/yii/logging/DebugTarget.php | 91 --------------------- 10 files changed, 202 insertions(+), 147 deletions(-) create mode 100644 framework/yii/debug/Debugger.php create mode 100644 framework/yii/debug/LogTarget.php delete mode 100644 framework/yii/debug/Toolbar.php create mode 100644 framework/yii/debug/views/default/index.php create mode 100644 framework/yii/debug/views/layouts/main.php delete mode 100644 framework/yii/logging/DebugTarget.php diff --git a/framework/yii/base/View.php b/framework/yii/base/View.php index a931a1b..e4485ef 100644 --- a/framework/yii/base/View.php +++ b/framework/yii/base/View.php @@ -25,14 +25,22 @@ use yii\widgets\FragmentCache; class View extends Component { /** - * @event ViewEvent an event that is triggered by [[beginPage()]]. + * @event Event an event that is triggered by [[beginPage()]]. */ const EVENT_BEGIN_PAGE = 'beginPage'; /** - * @event ViewEvent an event that is triggered by [[endPage()]]. + * @event Event an event that is triggered by [[endPage()]]. */ const EVENT_END_PAGE = 'endPage'; /** + * @event Event an event that is triggered by [[beginBody()]]. + */ + const EVENT_BEGIN_BODY = 'beginBody'; + /** + * @event Event an event that is triggered by [[endBody()]]. + */ + const EVENT_END_BODY = 'endBody'; + /** * @event ViewEvent an event that is triggered by [[renderFile()]] right before it renders a view file. */ const EVENT_BEFORE_RENDER = 'beforeRender'; @@ -532,6 +540,7 @@ class View extends Component public function beginBody() { echo self::PL_BODY_BEGIN; + $this->trigger(self::EVENT_BEGIN_BODY); } /** @@ -539,6 +548,7 @@ class View extends Component */ public function endBody() { + $this->trigger(self::EVENT_END_BODY); echo self::PL_BODY_END; } diff --git a/framework/yii/debug/Debugger.php b/framework/yii/debug/Debugger.php new file mode 100644 index 0000000..93ccc26 --- /dev/null +++ b/framework/yii/debug/Debugger.php @@ -0,0 +1,54 @@ + + * @since 2.0 + */ +class Debugger extends Component +{ + public $debugAction = 'debug/default/toolbar'; + public $panels; + + public function init() + { + parent::init(); + Yii::$app->setModule('debug', array( + 'class' => 'yii\debug\Module', + 'panels' => $this->panels, + )); + Yii::$app->log->targets[] = new LogTarget; + Yii::$app->getView()->on(View::EVENT_END_BODY, array($this, 'renderToolbar')); + } + + public function renderToolbar($event) + { + if (Yii::$app->getModule('debug', false) !== null) { + return; + } + + /** @var View $view */ + $id = 'yii-debug-toolbar'; + $url = Yii::$app->getUrlManager()->createUrl($this->debugAction, array( + 'tag' => Yii::getLogger()->tag, + )); + $view = $event->sender; + $view->registerJs("yii.debug.load('$id', '$url');"); + $view->registerAssetBundle('yii/debug'); + echo Html::tag('div', '', array( + 'id' => $id, + 'style' => 'display: none', + )); + } +} diff --git a/framework/yii/debug/LogTarget.php b/framework/yii/debug/LogTarget.php new file mode 100644 index 0000000..1192cb3 --- /dev/null +++ b/framework/yii/debug/LogTarget.php @@ -0,0 +1,93 @@ + + * @since 2.0 + */ +class LogTarget extends Target +{ + public $maxLogFiles = 20; + + /** + * Exports log messages to a specific destination. + * Child classes must implement this method. + * @param array $messages the messages to be exported. See [[Logger::messages]] for the structure + * of each message. + */ + public function export($messages) + { + $path = Yii::$app->getRuntimePath() . '/debug'; + if (!is_dir($path)) { + mkdir($path); + } + $file = $path . '/' . Yii::getLogger()->getTag() . '.log'; + $data = array( + 'messages' => $messages, + '_SERVER' => $_SERVER, + '_GET' => $_GET, + '_POST' => $_POST, + '_COOKIE' => $_COOKIE, + '_FILES' => empty($_FILES) ? array() : $_FILES, + '_SESSION' => empty($_SESSION) ? array() : $_SESSION, + 'memory' => memory_get_peak_usage(), + 'time' => microtime(true) - YII_BEGIN_TIME, + ); + file_put_contents($file, json_encode($data)); + } + + /** + * Processes the given log messages. + * This method will filter the given messages with [[levels]] and [[categories]]. + * And if requested, it will also export the filtering result to specific medium (e.g. email). + * @param array $messages log messages to be processed. See [[Logger::messages]] for the structure + * of each message. + * @param boolean $final whether this method is called at the end of the current application + */ + public function collect($messages, $final) + { + if (Yii::$app->getModule('debug', false) !== null) { + return; + } + $this->messages = array_merge($this->messages, $this->filterMessages($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->maxLogFiles) { + $n = count($files) - $this->maxLogFiles; + foreach ($files as $i => $file) { + if ($i < $n) { + unlink($file); + } else { + break; + } + } + } + } +} diff --git a/framework/yii/debug/Module.php b/framework/yii/debug/Module.php index a680f53..a0cf883 100644 --- a/framework/yii/debug/Module.php +++ b/framework/yii/debug/Module.php @@ -14,4 +14,5 @@ namespace yii\debug; class Module extends \yii\base\Module { public $controllerNamespace = 'yii\debug\controllers'; + public $panels; } diff --git a/framework/yii/debug/Toolbar.php b/framework/yii/debug/Toolbar.php deleted file mode 100644 index c205277..0000000 --- a/framework/yii/debug/Toolbar.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @since 2.0 - */ -class Toolbar extends Widget -{ - public $debugAction = 'debug/default/toolbar'; - - public function run() - { - if (Yii::$app->hasModule('debug')) { - $id = 'yii-debug-toolbar'; - $url = Yii::$app->getUrlManager()->createUrl($this->debugAction, array( - 'tag' => Yii::getLogger()->tag, - )); - $view = $this->getView(); - $view->registerJs("yii.debug.load('$id', '$url');"); - $view->registerAssetBundle('yii/debug'); - echo Html::tag('div', '', array( - 'id' => $id, - 'style' => 'display: none', - )); - } - } -} diff --git a/framework/yii/debug/controllers/DefaultController.php b/framework/yii/debug/controllers/DefaultController.php index f1160b1..56d583f 100644 --- a/framework/yii/debug/controllers/DefaultController.php +++ b/framework/yii/debug/controllers/DefaultController.php @@ -16,9 +16,11 @@ use yii\web\Controller; */ class DefaultController extends Controller { + public $layout = 'main'; + public function actionIndex($tag) { - echo $tag; + return $this->render('index'); } public function actionToolbar($tag) @@ -26,9 +28,10 @@ class DefaultController extends Controller $file = Yii::$app->getRuntimePath() . "/debug/$tag.log"; if (preg_match('/^[\w\-]+$/', $tag) && is_file($file)) { $data = json_decode(file_get_contents($file), true); - echo $this->renderPartial('toolbar', $data); + $data['tag'] = $tag; + return $this->renderPartial('toolbar', $data); } else { - echo "Unable to find debug data tagged with '$tag'."; + return "Unable to find debug data tagged with '$tag'."; } } } diff --git a/framework/yii/debug/views/default/index.php b/framework/yii/debug/views/default/index.php new file mode 100644 index 0000000..57cf853 --- /dev/null +++ b/framework/yii/debug/views/default/index.php @@ -0,0 +1 @@ +here we are diff --git a/framework/yii/debug/views/default/toolbar.php b/framework/yii/debug/views/default/toolbar.php index 0b08d4b..27f02f8 100644 --- a/framework/yii/debug/views/default/toolbar.php +++ b/framework/yii/debug/views/default/toolbar.php @@ -19,21 +19,22 @@ echo Html::style(" margin: 0 10px; "); ?> +
+
+ $tag)); ?> +
-
-
- -
-Peak memory: -
+
+ Peak memory: +
-
-Time spent: -
+
+ Time spent: +
-
-
+
+
-
+
+
- diff --git a/framework/yii/debug/views/layouts/main.php b/framework/yii/debug/views/layouts/main.php new file mode 100644 index 0000000..c43f3ff --- /dev/null +++ b/framework/yii/debug/views/layouts/main.php @@ -0,0 +1,21 @@ + + + +beginPage(); ?> + + <?php echo Html::encode($this->title); ?> + head(); ?> + + +beginBody(); ?> + +endBody(); ?> + +endPage(); ?> + diff --git a/framework/yii/logging/DebugTarget.php b/framework/yii/logging/DebugTarget.php deleted file mode 100644 index 92a74d6..0000000 --- a/framework/yii/logging/DebugTarget.php +++ /dev/null @@ -1,91 +0,0 @@ - - * @since 2.0 - */ -class DebugTarget extends Target -{ - public $maxLogFiles = 20; - - /** - * Exports log messages to a specific destination. - * Child classes must implement this method. - * @param array $messages the messages to be exported. See [[Logger::messages]] for the structure - * of each message. - */ - public function export($messages) - { - $path = Yii::$app->getRuntimePath() . '/debug'; - if (!is_dir($path)) { - mkdir($path); - } - $file = $path . '/' . Yii::getLogger()->getTag() . '.log'; - $data = array( - 'messages' => $messages, - '_SERVER' => $_SERVER, - '_GET' => $_GET, - '_POST' => $_POST, - '_COOKIE' => $_COOKIE, - '_FILES' => empty($_FILES) ? array() : $_FILES, - '_SESSION' => empty($_SESSION) ? array() : $_SESSION, - 'memory' => memory_get_peak_usage(), - 'time' => microtime(true) - YII_BEGIN_TIME, - ); - file_put_contents($file, json_encode($data)); - } - - /** - * Processes the given log messages. - * This method will filter the given messages with [[levels]] and [[categories]]. - * And if requested, it will also export the filtering result to specific medium (e.g. email). - * @param array $messages log messages to be processed. See [[Logger::messages]] for the structure - * of each message. - * @param boolean $final whether this method is called at the end of the current application - */ - public function collect($messages, $final) - { - if (Yii::$app->getModule('debug', false) !== null) { - return; - } - $this->messages = array_merge($this->messages, $this->filterMessages($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) { - if (preg_match('/^[\d\-]+\.log$/', $file->getFileName()) && $file->isFile()) { - $files[] = $file->getPathname(); - } - } - sort($files); - if (count($files) > $this->maxLogFiles) { - $n = count($files) - $this->maxLogFiles; - foreach ($files as $i => $file) { - if ($i < $n) { - unlink($file); - } else { - break; - } - } - } - } -}