mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-26 06:15:19 +08:00
Merge pull request #3755 from yiisoft/logger-arrays
refactored logger to support array values out of the box.
This commit is contained in:
@ -15,6 +15,9 @@ Basic logging is as simple as calling one method:
|
||||
\Yii::info('Hello, I am a test log message');
|
||||
```
|
||||
|
||||
You can log simple strings as well as more complex data structures such as arrays or objects.
|
||||
When logging data that is not a string the defaulf yii log targets will serialize the value using [[yii\helpers\Vardumper::export()]].
|
||||
|
||||
### Message category
|
||||
|
||||
Additionally to the message itself message category could be specified in order to allow filtering such messages and
|
||||
|
@ -63,7 +63,6 @@ class LogPanel extends Panel
|
||||
{
|
||||
$target = $this->module->logTarget;
|
||||
$messages = $target->filterMessages($target->messages, Logger::LEVEL_ERROR | Logger::LEVEL_INFO | Logger::LEVEL_WARNING | Logger::LEVEL_TRACE);
|
||||
|
||||
return ['messages' => $messages];
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,6 @@ class ProfilingPanel extends Panel
|
||||
{
|
||||
$target = $this->module->logTarget;
|
||||
$messages = $target->filterMessages($target->messages, Logger::LEVEL_PROFILE);
|
||||
|
||||
return [
|
||||
'memory' => memory_get_peak_usage(),
|
||||
'time' => microtime(true) - YII_BEGIN_TIME,
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
use yii\helpers\Html;
|
||||
use yii\grid\GridView;
|
||||
use yii\helpers\VarDumper;
|
||||
use yii\log\Logger;
|
||||
|
||||
?>
|
||||
@ -51,8 +52,7 @@ echo GridView::widget([
|
||||
[
|
||||
'attribute' => 'message',
|
||||
'value' => function ($data) {
|
||||
$message = nl2br(Html::encode($data['message']));
|
||||
|
||||
$message = Html::encode(is_string($data['message']) ? $data['message'] : VarDumper::export($data['message']));
|
||||
if (!empty($data['trace'])) {
|
||||
$message .= Html::ul($data['trace'], [
|
||||
'class' => 'trace',
|
||||
@ -61,7 +61,6 @@ echo GridView::widget([
|
||||
}
|
||||
]);
|
||||
};
|
||||
|
||||
return $message;
|
||||
},
|
||||
'format' => 'html',
|
||||
|
@ -60,6 +60,7 @@ Yii Framework 2 Change Log
|
||||
- Enh #3222: Added `useTablePrefix` option to the model generator for Gii (horizons2)
|
||||
- Enh #3230: Added `yii\filters\AccessControl::user` to support access control with different actors (qiangxue)
|
||||
- Enh #3232: Added `export()` and `exportAsString()` methods to `yii\helpers\BaseVarDumper` (klimov-paul)
|
||||
- Enh #3244: Allow logging complex data such as arrays and object via the log system (cebe)
|
||||
- Enh #3252: Added support for case insensitive matching using ILIKE to PostgreSQL QueryBuilder (cebe)
|
||||
- Enh #3284: Added support for checking multiple ETags by `yii\filters\HttpCache` (qiangxue)
|
||||
- Enh #3298: Supported configuring `View::theme` using a class name (netyum, qiangxue)
|
||||
@ -106,6 +107,8 @@ Yii Framework 2 Change Log
|
||||
- Chg: `yii\data\ActiveDataProvider::$query` will not be modified directly with pagination and sorting anymore so it will be reuseable (cebe)
|
||||
- Chg: Removed `yii\rest\ActiveController::$transactional` property and connected functionality (samdark)
|
||||
- Chg: Changed the default value of the `keyPrefix` property of cache components to be null (qiangxue)
|
||||
- Chg: Added `prefix` column to `yii\log\DbTarget` to have the same amount of information logged as in files and emails (cebe)
|
||||
|
||||
|
||||
2.0.0-beta April 13, 2014
|
||||
-------------------------
|
||||
|
@ -43,4 +43,7 @@ Upgrade from Yii 2.0 Beta
|
||||
of the callable to be `function ($model, $key, $index, $widget)`. The `$key` parameter was newly added
|
||||
in this release.
|
||||
|
||||
* `yii\console\controllers\AssetController` is now using hashes instead of timestamps. Replace all `{ts}` with `{hash}`.
|
||||
* `yii\console\controllers\AssetController` is now using hashes instead of timestamps. Replace all `{ts}` with `{hash}`.
|
||||
|
||||
* The database table of the `yii\log\DbTarget` now needs a `prefix` column to store context information.
|
||||
You can add it with `ALTER TABLE log ADD COLUMN prefix TEXT AFTER log_time;`.
|
||||
|
@ -133,6 +133,8 @@ class BaseVarDumper
|
||||
* This method is similar to `var_export()`. The main difference is that
|
||||
* it generates more compact string representation using short array syntax.
|
||||
*
|
||||
* It also handles objects by using the PHP functions serialize() and unserialize().
|
||||
*
|
||||
* PHP 5.4 or above is required to parse the exported value.
|
||||
*
|
||||
* @param mixed $var the variable to be exported.
|
||||
|
@ -16,7 +16,7 @@ use yii\di\Instance;
|
||||
* DbTarget stores log messages in a database table.
|
||||
*
|
||||
* By default, DbTarget stores the log messages in a DB table named 'log'. This table
|
||||
* must be pre-created. The table name can be changed by setting [[logTable]].
|
||||
* must be pre-created. The table name can be changed by setting the [[logTable]] property.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
@ -39,6 +39,7 @@ class DbTarget extends Target
|
||||
* level INTEGER,
|
||||
* category VARCHAR(255),
|
||||
* log_time INTEGER,
|
||||
* prefix TEXT,
|
||||
* message TEXT,
|
||||
* INDEX idx_log_level (level),
|
||||
* INDEX idx_log_category (category)
|
||||
@ -55,6 +56,7 @@ class DbTarget extends Target
|
||||
*/
|
||||
public $logTable = '{{%log}}';
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the DbTarget component.
|
||||
* This method will initialize the [[db]] property to make sure it refers to a valid DB connection.
|
||||
@ -72,15 +74,20 @@ class DbTarget extends Target
|
||||
public function export()
|
||||
{
|
||||
$tableName = $this->db->quoteTableName($this->logTable);
|
||||
$sql = "INSERT INTO $tableName ([[level]], [[category]], [[log_time]], [[message]])
|
||||
VALUES (:level, :category, :log_time, :message)";
|
||||
$sql = "INSERT INTO $tableName ([[level]], [[category]], [[log_time]], [[prefix]], [[message]])
|
||||
VALUES (:level, :category, :log_time, :prefix, :message)";
|
||||
$command = $this->db->createCommand($sql);
|
||||
foreach ($this->messages as $message) {
|
||||
list($text, $level, $category, $timestamp) = $message;
|
||||
if (!is_string($text)) {
|
||||
$text = var_export($text, true);
|
||||
}
|
||||
$command->bindValues([
|
||||
':level' => $message[1],
|
||||
':category' => $message[2],
|
||||
':log_time' => $message[3],
|
||||
':message' => $message[0],
|
||||
':level' => $level,
|
||||
':category' => $category,
|
||||
':log_time' => $timestamp,
|
||||
':prefix' => $this->getMessagePrefix($message),
|
||||
':message' => $text,
|
||||
])->execute();
|
||||
}
|
||||
}
|
||||
|
@ -13,14 +13,14 @@ use yii\base\Component;
|
||||
/**
|
||||
* Dispatcher manages a set of [[Target|log targets]].
|
||||
*
|
||||
* Dispatcher implements [[dispatch()]] that forwards the log messages from [[Logger]] to
|
||||
* Dispatcher implements the [[dispatch()]]-method that forwards the log messages from a [[Logger]] to
|
||||
* the registered log [[targets]].
|
||||
*
|
||||
* Dispatcher is registered as a core application component and can be accessed using `Yii::$app->log`.
|
||||
* An instance of Dispatcher is registered as a core application component and can be accessed using `Yii::$app->log`.
|
||||
*
|
||||
* You may configure the targets in application configuration, like the following:
|
||||
*
|
||||
* ~~~
|
||||
* ```php
|
||||
* [
|
||||
* 'components' => [
|
||||
* 'log' => [
|
||||
@ -41,14 +41,13 @@ use yii\base\Component;
|
||||
* ],
|
||||
* ],
|
||||
* ]
|
||||
* ~~~
|
||||
* ```
|
||||
*
|
||||
* Each log target can have a name and can be referenced via the [[targets]] property
|
||||
* as follows:
|
||||
* Each log target can have a name and can be referenced via the [[targets]] property as follows:
|
||||
*
|
||||
* ~~~
|
||||
* ```php
|
||||
* Yii::$app->log->targets['file']->enabled = false;
|
||||
* ~~~
|
||||
* ```
|
||||
*
|
||||
* @property integer $flushInterval How many messages should be logged before they are sent to targets. This
|
||||
* method returns the value of [[Logger::flushInterval]].
|
||||
@ -66,6 +65,7 @@ class Dispatcher extends Component
|
||||
* or the configuration for creating the log target instance.
|
||||
*/
|
||||
public $targets = [];
|
||||
|
||||
/**
|
||||
* @var Logger the logger.
|
||||
*/
|
||||
@ -77,6 +77,7 @@ class Dispatcher extends Component
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
{
|
||||
// ensure logger gets set before any other config option
|
||||
if (isset($config['logger'])) {
|
||||
$this->setLogger($config['logger']);
|
||||
unset($config['logger']);
|
||||
|
@ -35,6 +35,7 @@ class EmailTarget extends Target
|
||||
*/
|
||||
public $mail = 'mail';
|
||||
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
|
@ -57,6 +57,7 @@ class FileTarget extends Target
|
||||
*/
|
||||
public $rotateByCopy = false;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the route.
|
||||
* This method is invoked after the route is created by the route manager.
|
||||
|
@ -13,7 +13,7 @@ use yii\base\Component;
|
||||
/**
|
||||
* Logger records logged messages in memory and sends them to different targets if [[dispatcher]] is set.
|
||||
*
|
||||
* Logger can be accessed via `Yii::getLogger()`. You can call the method [[log()]] to record a single log message.
|
||||
* A Logger instance can be accessed via `Yii::getLogger()`. You can call the method [[log()]] to record a single log message.
|
||||
* For convenience, a set of shortcut methods are provided for logging messages of various severity levels
|
||||
* via the [[Yii]] class:
|
||||
*
|
||||
@ -25,7 +25,8 @@ use yii\base\Component;
|
||||
* - [[Yii::endProfile()]]
|
||||
*
|
||||
* When the application ends or [[flushInterval]] is reached, Logger will call [[flush()]]
|
||||
* to send logged messages to different log targets, such as file, email, Web, with the help of [[dispatcher]].
|
||||
* to send logged messages to different log targets, such as [[FileTarget|file]], [[EmailTarget|email]],
|
||||
* or [[DbTarget|database]], with the help of the [[dispatcher]].
|
||||
*
|
||||
* @property array $dbProfiling The first element indicates the number of SQL statements executed, and the
|
||||
* second element the total time spent in SQL execution. This property is read-only.
|
||||
@ -122,7 +123,8 @@ class Logger extends Component
|
||||
* Logs a message with the given type and category.
|
||||
* If [[traceLevel]] is greater than 0, additional call stack information about
|
||||
* the application code will be logged as well.
|
||||
* @param string $message the message to be logged.
|
||||
* @param string|array $message the message to be logged. This can be a simple string or a more
|
||||
* complex data structure that will be handled by a [[Target|log target]].
|
||||
* @param integer $level the level of the message. This must be one of the following:
|
||||
* `Logger::LEVEL_ERROR`, `Logger::LEVEL_WARNING`, `Logger::LEVEL_INFO`, `Logger::LEVEL_TRACE`,
|
||||
* `Logger::LEVEL_PROFILE_BEGIN`, `Logger::LEVEL_PROFILE_END`.
|
||||
|
@ -8,6 +8,7 @@
|
||||
namespace yii\log;
|
||||
|
||||
use Yii;
|
||||
use yii\helpers\VarDumper;
|
||||
|
||||
/**
|
||||
* SyslogTarget writes log to syslog.
|
||||
@ -39,6 +40,7 @@ class SyslogTarget extends Target
|
||||
Logger::LEVEL_ERROR => LOG_ERR,
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Writes log messages to syslog
|
||||
*/
|
||||
@ -59,11 +61,10 @@ class SyslogTarget extends Target
|
||||
list($text, $level, $category, $timestamp) = $message;
|
||||
$level = Logger::getLevelName($level);
|
||||
if (!is_string($text)) {
|
||||
$text = var_export($text, true);
|
||||
$text = VarDumper::export($text, true);
|
||||
}
|
||||
|
||||
$prefix = $this->prefix ? call_user_func($this->prefix, $message) : $this->getMessagePrefix($message);
|
||||
|
||||
$prefix = $this->getMessagePrefix($message);
|
||||
return "{$prefix}[$level][$category] $text";
|
||||
}
|
||||
}
|
||||
|
@ -60,9 +60,12 @@ abstract class Target extends Component
|
||||
*/
|
||||
public $logVars = ['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION', '_SERVER'];
|
||||
/**
|
||||
* @var callable a PHP callable that returns a string to be prefix to every exported message.
|
||||
* If not set, [[getMessagePrefix()]] will be used, which prefixes user IP, user ID and session ID
|
||||
* to every message. The signature of the callable should be `function ($message)`.
|
||||
* @var callable a PHP callable that returns a string to be prefixed to every exported message.
|
||||
*
|
||||
* If not set, [[getMessagePrefix()]] will be used, which prefixes the message with context information
|
||||
* such as user IP, user ID and session ID.
|
||||
*
|
||||
* The signature of the callable should be `function ($message)`.
|
||||
*/
|
||||
public $prefix;
|
||||
/**
|
||||
@ -79,6 +82,7 @@ abstract class Target extends Component
|
||||
|
||||
private $_levels = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Exports log [[messages]] to a specific destination.
|
||||
* Child classes must implement this method.
|
||||
@ -177,7 +181,8 @@ abstract class Target extends Component
|
||||
|
||||
/**
|
||||
* Filters the given messages according to their categories and levels.
|
||||
* @param array $messages messages to be filtered
|
||||
* @param array $messages messages to be filtered.
|
||||
* The message structure follows that in [[Logger::messages]].
|
||||
* @param integer $levels the message levels to filter by. This is a bitmap of
|
||||
* level values. Value 0 means allowing all levels.
|
||||
* @param array $categories the message categories to filter by. If empty, it means all categories are allowed.
|
||||
@ -214,14 +219,13 @@ abstract class Target extends Component
|
||||
unset($messages[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a log message.
|
||||
* The message structure follows that in [[Logger::messages]].
|
||||
* Formats a log message for display as a string.
|
||||
* @param array $message the log message to be formatted.
|
||||
* The message structure follows that in [[Logger::messages]].
|
||||
* @return string the formatted message
|
||||
*/
|
||||
public function formatMessage($message)
|
||||
@ -229,30 +233,38 @@ abstract class Target extends Component
|
||||
list($text, $level, $category, $timestamp) = $message;
|
||||
$level = Logger::getLevelName($level);
|
||||
if (!is_string($text)) {
|
||||
$text = var_export($text, true);
|
||||
$text = VarDumper::export($text, true);
|
||||
}
|
||||
|
||||
$prefix = $this->prefix ? call_user_func($this->prefix, $message) : $this->getMessagePrefix($message);
|
||||
|
||||
$prefix = $this->getMessagePrefix($message);
|
||||
return date('Y-m-d H:i:s', $timestamp) . " {$prefix}[$level][$category] $text";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string to be prefixed to the given message.
|
||||
* If [[prefix]] is configured it will return the result of the callback.
|
||||
* The default implementation will return user IP, user ID and session ID as a prefix.
|
||||
* @param array $message the message being exported
|
||||
* @param array $message the message being exported.
|
||||
* The message structure follows that in [[Logger::messages]].
|
||||
* @return string the prefix string
|
||||
*/
|
||||
public function getMessagePrefix($message)
|
||||
{
|
||||
if ($this->prefix !== null) {
|
||||
return call_user_func($this->prefix, $message);
|
||||
}
|
||||
|
||||
$request = Yii::$app->getRequest();
|
||||
$ip = $request instanceof Request ? $request->getUserIP() : '-';
|
||||
|
||||
/** @var \yii\web\User $user */
|
||||
$user = Yii::$app->has('user', true) ? Yii::$app->get('user') : null;
|
||||
$userID = $user ? $user->getId(false) : '-';
|
||||
|
||||
/** @var \yii\web\Session $session */
|
||||
$session = Yii::$app->has('session', true) ? Yii::$app->get('session') : null;
|
||||
$sessionID = $session && $session->getIsActive() ? $session->getId() : '-';
|
||||
|
||||
return "[$ip][$userID][$sessionID]";
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user