mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-20 10:27:18 +08:00
debug toolbar WIP
This commit is contained in:
@ -16,32 +16,34 @@ use yii\log\Target;
|
||||
*/
|
||||
class LogTarget extends Target
|
||||
{
|
||||
/**
|
||||
* @var Module
|
||||
*/
|
||||
public $module;
|
||||
public $maxLogFiles = 20;
|
||||
|
||||
public function __construct($module, $config = array())
|
||||
{
|
||||
parent::__construct($config);
|
||||
$this->module = $module;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
public function export()
|
||||
{
|
||||
$path = Yii::$app->getRuntimePath() . '/debug';
|
||||
if (!is_dir($path)) {
|
||||
mkdir($path);
|
||||
}
|
||||
$file = $path . '/' . Yii::$app->getLog()->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,
|
||||
);
|
||||
$tag = Yii::$app->getLog()->getTag();
|
||||
$file = "$path/$tag.log";
|
||||
$data = array();
|
||||
foreach ($this->module->panels as $panel) {
|
||||
$data[$panel->id] = $panel->save();
|
||||
}
|
||||
file_put_contents($file, json_encode($data));
|
||||
}
|
||||
|
||||
|
@ -18,19 +18,28 @@ use yii\helpers\Html;
|
||||
class Module extends \yii\base\Module
|
||||
{
|
||||
public $controllerNamespace = 'yii\debug\controllers';
|
||||
public $panels;
|
||||
/**
|
||||
* @var array|Panel[]
|
||||
*/
|
||||
public $panels = array();
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
Yii::$app->log->targets['debug'] = new LogTarget;
|
||||
|
||||
foreach (array_merge($this->corePanels(), $this->panels) as $id => $config) {
|
||||
$config['id'] = $id;
|
||||
$this->panels[$id] = Yii::createObject($config);
|
||||
}
|
||||
|
||||
Yii::$app->getLog()->targets['debug'] = new LogTarget($this);
|
||||
Yii::$app->getView()->on(View::EVENT_END_BODY, array($this, 'renderToolbar'));
|
||||
}
|
||||
|
||||
public function beforeAction($action)
|
||||
{
|
||||
Yii::$app->getView()->off(View::EVENT_END_BODY, array($this, 'renderToolbar'));
|
||||
unset(Yii::$app->log->targets['debug']);
|
||||
unset(Yii::$app->getLog()->targets['debug']);
|
||||
return parent::beforeAction($action);
|
||||
}
|
||||
|
||||
@ -49,4 +58,19 @@ class Module extends \yii\base\Module
|
||||
'style' => 'display: none',
|
||||
));
|
||||
}
|
||||
|
||||
protected function corePanels()
|
||||
{
|
||||
return array(
|
||||
'config' => array(
|
||||
'class' => 'yii\debug\panels\ConfigPanel',
|
||||
),
|
||||
'request' => array(
|
||||
'class' => 'yii\debug\panels\RequestPanel',
|
||||
),
|
||||
'log' => array(
|
||||
'class' => 'yii\debug\panels\LogPanel',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
45
framework/yii/debug/Panel.php
Normal file
45
framework/yii/debug/Panel.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug;
|
||||
|
||||
use yii\base\Component;
|
||||
|
||||
/**
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Panel extends Component
|
||||
{
|
||||
public $id;
|
||||
public $data;
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getSummary()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getDetail()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function load($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ namespace yii\debug\controllers;
|
||||
|
||||
use Yii;
|
||||
use yii\web\Controller;
|
||||
use yii\web\HttpException;
|
||||
|
||||
/**
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
@ -16,22 +17,48 @@ use yii\web\Controller;
|
||||
*/
|
||||
class DefaultController extends Controller
|
||||
{
|
||||
/** @var \yii\debug\Module */
|
||||
public $module;
|
||||
public $layout = 'main';
|
||||
|
||||
public function actionIndex($tag)
|
||||
public function actionIndex($tag, $panel = null)
|
||||
{
|
||||
return $this->render('index');
|
||||
$this->loadData($tag);
|
||||
if (isset($this->module->panels[$panel])) {
|
||||
$activePanel = $this->module->panels[$panel];
|
||||
} else {
|
||||
$activePanel = reset($this->module->panels);
|
||||
}
|
||||
return $this->render('index', array(
|
||||
'tag' => $tag,
|
||||
'panels' => $this->module->panels,
|
||||
'activePanel' => $activePanel,
|
||||
));
|
||||
}
|
||||
|
||||
public function actionToolbar($tag)
|
||||
{
|
||||
$this->loadData($tag);
|
||||
return $this->renderPartial('toolbar', array(
|
||||
'panels' => $this->module->panels,
|
||||
));
|
||||
}
|
||||
|
||||
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);
|
||||
$data['tag'] = $tag;
|
||||
return $this->renderPartial('toolbar', $data);
|
||||
foreach ($this->module->panels as $id => $panel) {
|
||||
if (isset($data[$panel->id])) {
|
||||
$panel->load($data[$panel->id]);
|
||||
} else {
|
||||
return "Unable to find debug data tagged with '$tag'.";
|
||||
// remove the panel since it has not received any data
|
||||
unset($this->module->panels[$id]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new HttpException(404, "Unable to find debug data tagged with '$tag'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
50
framework/yii/debug/panels/ConfigPanel.php
Normal file
50
framework/yii/debug/panels/ConfigPanel.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\debug\Panel;
|
||||
use yii\helpers\Html;
|
||||
|
||||
/**
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ConfigPanel extends Panel
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'Config';
|
||||
}
|
||||
|
||||
public function getSummary()
|
||||
{
|
||||
$link = Html::a('more details', array('index', 'tag' => $this->data['tag']));
|
||||
return <<<EOD
|
||||
<div class="yii-debug-toolbar-block">
|
||||
PHP: {$this->data['phpVersion']},
|
||||
Yii: {$this->data['phpVersion']},
|
||||
$link
|
||||
</div>
|
||||
EOD;
|
||||
}
|
||||
|
||||
public function getDetail()
|
||||
{
|
||||
return '<h2>Config</h2>';
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
return array(
|
||||
'tag' => Yii::$app->getLog()->getTag(),
|
||||
'phpVersion' => PHP_VERSION,
|
||||
'yiiVersion' => Yii::getVersion(),
|
||||
);
|
||||
}
|
||||
}
|
45
framework/yii/debug/panels/LogPanel.php
Normal file
45
framework/yii/debug/panels/LogPanel.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use Yii;
|
||||
use yii\debug\Panel;
|
||||
|
||||
/**
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class LogPanel extends Panel
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'Logs';
|
||||
}
|
||||
|
||||
public function getSummary()
|
||||
{
|
||||
$count = count($this->data['messages']);
|
||||
return <<<EOD
|
||||
<div class="yii-debug-toolbar-block">
|
||||
Log messages: $count
|
||||
</div>
|
||||
EOD;
|
||||
}
|
||||
|
||||
public function getDetail()
|
||||
{
|
||||
return '<h2>Logs</h2>';
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
return array(
|
||||
'messages' => Yii::$app->getLog()->targets['debug']->messages,
|
||||
);
|
||||
}
|
||||
}
|
57
framework/yii/debug/panels/RequestPanel.php
Normal file
57
framework/yii/debug/panels/RequestPanel.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\debug\panels;
|
||||
|
||||
use yii\debug\Panel;
|
||||
|
||||
/**
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class RequestPanel extends Panel
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'Request';
|
||||
}
|
||||
|
||||
public function getSummary()
|
||||
{
|
||||
$memory = sprintf('%.2fMB', $this->data['memory'] / 1048576);
|
||||
$time = sprintf('%.3fs', $this->data['time']);
|
||||
|
||||
return <<<EOD
|
||||
<div class="yii-debug-toolbar-block">
|
||||
Peak memory: $memory
|
||||
</div>
|
||||
|
||||
<div class="yii-debug-toolbar-block">
|
||||
Time spent: $time
|
||||
</div>
|
||||
EOD;
|
||||
}
|
||||
|
||||
public function getDetail()
|
||||
{
|
||||
return '<h2>Request</h2>';
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
return array(
|
||||
'memory' => memory_get_peak_usage(),
|
||||
'time' => microtime(true) - YII_BEGIN_TIME,
|
||||
'SERVER' => $_SERVER,
|
||||
'GET' => $_GET,
|
||||
'POST' => $_POST,
|
||||
'COOKIE' => $_COOKIE,
|
||||
'FILES' => empty($_FILES) ? array() : $_FILES,
|
||||
'SESSION' => empty($_SESSION) ? array() : $_SESSION,
|
||||
);
|
||||
}
|
||||
}
|
@ -1 +1,16 @@
|
||||
here we are
|
||||
<?php
|
||||
|
||||
use yii\helpers\Html;
|
||||
|
||||
/**
|
||||
* @var \yii\base\View $this
|
||||
* @var string $tag
|
||||
* @var \yii\debug\Panel[] $panels
|
||||
* @var \yii\debug\Panel $activePanel
|
||||
*/
|
||||
?>
|
||||
<?php foreach ($panels as $panel): ?>
|
||||
<?php echo Html::a(Html::encode($panel->getName()), array('debug/default/index', 'tag' => $tag, 'panel' => $panel->id)); ?><br>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php echo $activePanel->getDetail(); ?>
|
||||
|
@ -1,6 +1,10 @@
|
||||
<?php use yii\helpers\Html;
|
||||
|
||||
echo Html::style("
|
||||
<?php
|
||||
/**
|
||||
* @var \yii\base\View $this
|
||||
* @var \yii\debug\Panel[] $panels
|
||||
*/
|
||||
?>
|
||||
<style>
|
||||
#yii-debug-toolbar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
@ -17,24 +21,11 @@ echo Html::style("
|
||||
.yii-debug-toolbar-block {
|
||||
float: left;
|
||||
margin: 0 10px;
|
||||
");
|
||||
?>
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="yii-debug-toolbar">
|
||||
<div class="yii-debug-toolbar-block">
|
||||
<?php echo Html::a('more details', array('index', 'tag' => $tag)); ?>
|
||||
</div>
|
||||
|
||||
<div class="yii-debug-toolbar-block">
|
||||
Peak memory: <?php echo sprintf('%.2fMB', $memory / 1048576); ?>
|
||||
</div>
|
||||
|
||||
<div class="yii-debug-toolbar-block">
|
||||
Time spent: <?php echo sprintf('%.3fs', $time); ?>
|
||||
</div>
|
||||
|
||||
<div class="yii-debug-toolbar-block">
|
||||
</div>
|
||||
|
||||
<div class="yii-debug-toolbar-block">
|
||||
</div>
|
||||
<?php foreach ($panels as $panel): ?>
|
||||
<?php echo $panel->getSummary(); ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
@ -72,16 +72,14 @@ class DbTarget extends Target
|
||||
|
||||
/**
|
||||
* Stores log messages to DB.
|
||||
* @param array $messages the messages to be exported. See [[Logger::messages]] for the structure
|
||||
* of each message.
|
||||
*/
|
||||
public function export($messages)
|
||||
public function export()
|
||||
{
|
||||
$tableName = $this->db->quoteTableName($this->logTable);
|
||||
$sql = "INSERT INTO $tableName ([[level]], [[category]], [[log_time]], [[message]])
|
||||
VALUES (:level, :category, :log_time, :message)";
|
||||
$command = $this->db->createCommand($sql);
|
||||
foreach ($messages as $message) {
|
||||
foreach ($this->messages as $message) {
|
||||
$command->bindValues(array(
|
||||
':level' => $message[1],
|
||||
':category' => $message[2],
|
||||
|
@ -38,13 +38,11 @@ class EmailTarget extends Target
|
||||
|
||||
/**
|
||||
* Sends log messages to specified email addresses.
|
||||
* @param array $messages the messages to be exported. See [[Logger::messages]] for the structure
|
||||
* of each message.
|
||||
*/
|
||||
public function export($messages)
|
||||
public function export()
|
||||
{
|
||||
$body = '';
|
||||
foreach ($messages as $message) {
|
||||
foreach ($this->messages as $message) {
|
||||
$body .= $this->formatMessage($message);
|
||||
}
|
||||
$body = wordwrap($body, 70);
|
||||
|
@ -65,14 +65,12 @@ class FileTarget extends Target
|
||||
|
||||
/**
|
||||
* Sends log messages to specified email addresses.
|
||||
* @param array $messages the messages to be exported. See [[Logger::messages]] for the structure
|
||||
* of each message.
|
||||
* @throws InvalidConfigException if unable to open the log file for writing
|
||||
*/
|
||||
public function export($messages)
|
||||
public function export()
|
||||
{
|
||||
$text = '';
|
||||
foreach ($messages as $message) {
|
||||
foreach ($this->messages as $message) {
|
||||
$text .= $this->formatMessage($message);
|
||||
}
|
||||
if (($fp = @fopen($this->logFile, 'a')) === false) {
|
||||
|
@ -124,7 +124,7 @@ class Logger extends Component
|
||||
*/
|
||||
public $messages = array();
|
||||
/**
|
||||
* @var array the log targets. Each array element represents a single [[Target|log target]] instance
|
||||
* @var array|Target[] the log targets. Each array element represents a single [[Target|log target]] instance
|
||||
* or the configuration for creating the log target instance.
|
||||
*/
|
||||
public $targets = array();
|
||||
|
@ -68,18 +68,17 @@ abstract class Target extends Component
|
||||
public $exportInterval = 1000;
|
||||
/**
|
||||
* @var array the messages that are retrieved from the logger so far by this log target.
|
||||
* Please refer to [[Logger::messages]] for the details about the message structure.
|
||||
*/
|
||||
public $messages = array();
|
||||
|
||||
private $_levels = 0;
|
||||
|
||||
/**
|
||||
* Exports log messages to a specific destination.
|
||||
* 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.
|
||||
*/
|
||||
abstract public function export($messages);
|
||||
abstract public function export();
|
||||
|
||||
/**
|
||||
* Processes the given log messages.
|
||||
@ -97,7 +96,7 @@ abstract class Target extends Component
|
||||
if (($context = $this->getContextMessage()) !== '') {
|
||||
$this->messages[] = array($context, Logger::LEVEL_INFO, 'application', YII_BEGIN_TIME);
|
||||
}
|
||||
$this->export($this->messages);
|
||||
$this->export();
|
||||
$this->messages = array();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user