Commit d743d9bc by Qiang Xue

...

parent d46ac5b1
......@@ -94,7 +94,5 @@ class DbTarget extends Target
':message' => $message[0],
))->execute();
}
$this->messages = array();
}
}
......@@ -53,8 +53,6 @@ class EmailTarget extends Target
foreach ($this->emails as $email) {
$this->sendEmail($subject, $body, $email, $this->sentFrom, $this->headers);
}
$this->messages = array();
}
/**
......
......@@ -79,8 +79,6 @@ class FileTarget extends Target
$messages[] = $this->formatMessage($message);
}
@file_put_contents($logFile, implode('', $messages), FILE_APPEND | LOCK_EX);
$this->messages = array();
}
/**
......
......@@ -37,24 +37,16 @@ class Logger extends \yii\base\Component
* Defaults to 1000, meaning the [[flush]] method will be invoked once every 1000 messages logged.
* Set this property to be 0 if you don't want to flush messages until the application terminates.
* This property mainly affects how much memory will be taken by the logged messages.
* A smaller value means less memory, but will increase the execution time due to the overhead of [[flush]].
* A smaller value means less memory, but will increase the execution time due to the overhead of [[flush()]].
*/
public $flushInterval = 1000;
/**
* @var boolean this property will be passed as the parameter to [[flush]] when it is
* called due to the [[flushInterval]] is reached. Defaults to true, meaning the flushed
* messages will be exported to the actual storage medium (e.g. DB, email) defined by each
* log target. If false, the flushed messages will be kept in the memory of each log target.
* @see flushInterval
*/
public $autoExport = true;
/**
* @var array logged messages. This property is mainly managed by [[log]] and [[flush]].
* @var array logged messages. This property is mainly managed by [[log()]] and [[flush()]].
* Each log message is of the following structure:
*
* ~~~
* array(
* [0] => message (string)
* [0] => message (mixed)
* [1] => level (string)
* [2] => category (string)
* [3] => timestamp (float, obtained by microtime(true))
......@@ -67,7 +59,7 @@ class Logger extends \yii\base\Component
* Logs an error message.
* An error message is typically logged when an unrecoverable error occurs
* during the execution of an application.
* @param string $message the message to be logged.
* @param mixed $message the message to be logged.
* @param string $category the category of the message.
*/
public function error($message, $category = 'application')
......@@ -79,7 +71,7 @@ class Logger extends \yii\base\Component
* Logs a trace message.
* Trace messages are logged mainly for development purpose to see
* the execution work flow of some code.
* @param string $message the message to be logged.
* @param mixed $message the message to be logged.
* @param string $category the category of the message.
*/
public function trace($message, $category = 'application')
......@@ -91,24 +83,24 @@ class Logger extends \yii\base\Component
* Logs a warning message.
* A warning message is typically logged when an error occurs while the execution
* can still continue.
* @param string $message the message to be logged.
* @param mixed $message the message to be logged.
* @param string $category the category of the message.
*/
public function warning($message, $category = 'application')
{
$this->log($message, self::LEVEL_TRACE, $category);
$this->log($message, self::LEVEL_WARNING, $category);
}
/**
* Logs an informative message.
* An informative message is typically logged by an application to keep record of
* something important (e.g. an administrator logs in).
* @param string $message the message to be logged.
* @param mixed $message the message to be logged.
* @param string $category the category of the message.
*/
public function info($message, $category = 'application')
{
$this->log($message, self::LEVEL_TRACE, $category);
$this->log($message, self::LEVEL_INFO, $category);
}
/**
......@@ -119,7 +111,7 @@ class Logger extends \yii\base\Component
* @param string $category the category of this log message
* @see endProfile
*/
public function beginProfile($token, $category)
public function beginProfile($token, $category = 'application')
{
$this->log($token, self::LEVEL_PROFILE_BEGIN, $category);
}
......@@ -131,7 +123,7 @@ class Logger extends \yii\base\Component
* @param string $category the category of this log message
* @see beginProfile
*/
public function endProfile($token, $category)
public function endProfile($token, $category = 'application')
{
$this->log($token, self::LEVEL_PROFILE_END, $category);
}
......@@ -145,9 +137,10 @@ class Logger extends \yii\base\Component
* 'trace', 'info', 'warning', 'error', 'profile'.
* @param string $category the category of the message.
*/
public function log($message, $level, $category)
public function log($message, $level, $category = 'application')
{
if (YII_DEBUG && YII_TRACE_LEVEL > 0 && $level <= self::LEVEL_TRACE) {
$time = microtime(true);
if (YII_DEBUG && YII_TRACE_LEVEL > 0) {
$traces = debug_backtrace();
$count = 0;
foreach ($traces as $trace) {
......@@ -159,25 +152,19 @@ class Logger extends \yii\base\Component
}
}
}
$this->messages[] = array($message, $level, $category, microtime(true));
$this->messages[] = array($message, $level, $category, $time);
if (count($this->messages) >= $this->flushInterval && $this->flushInterval > 0) {
$this->flush($this->autoExport);
$this->flush();
}
}
/**
* Removes all recorded messages from the memory.
* This method will raise a `flush` event.
* The attached event handlers can process the log messages before they are removed.
* @param boolean $export whether to notify log targets to export the filtered messages they have received.
*/
public function flush($export = false)
public function flush()
{
$this->trigger('flush', new \yii\base\Event($this, array(
'export' => $export,
'flush' => true,
)));
$this->trigger('flush');
$this->messages = array();
}
......
......@@ -57,17 +57,10 @@ namespace yii\logging;
class Router extends \yii\base\ApplicationComponent
{
/**
* @var \yii\base\Dictionary
* @var Target[] list of log target objects or configurations. If the latter, target objects will
* be created in [[init()]] by calling [[\Yii::createObject()]] with the corresponding object configuration.
*/
private $_targets;
/**
* Constructor.
*/
public function __construct()
{
$this->_targets = new \yii\base\Dictionary;
}
public $targets = array();
/**
* Initializes this application component.
......@@ -78,41 +71,16 @@ class Router extends \yii\base\ApplicationComponent
public function init()
{
parent::init();
\Yii::getLogger()->on('flush', array($this, 'processMessages'));
if (($app = \Yii::$application) !== null) {
$app->on('afterRequest', array($this, 'processMessages'));
}
}
/**
* Returns the log targets managed by this log router.
* The keys of the dictionary are the names of the log targets.
* You can use the name to access a specific log target. For example,
*
* ~~~
* $target = $router->targets['file'];
* ~~~
* @return \yii\base\Dictionary the targets managed by this log router.
*/
public function getTargets()
{
return $this->_targets;
foreach ($this->targets as $name => $target) {
if (!$target instanceof Target) {
$this->targets[$name] = \Yii::createObject($target);
}
/**
* Sets the log targets.
* @param array $config list of log target configurations. Each array element
* represents the configuration for creating a single log target. It will be
* passed to [[\Yii::createObject()]] to create the target instance.
*/
public function setTargets($config)
{
foreach ($config as $name => $target) {
if ($target instanceof Target) {
$this->_targets[$name] = $target;
} else {
$this->_targets[$name] = \Yii::createObject($target);
}
\Yii::getLogger()->on('flush', array($this, 'processMessages'));
if (\Yii::$application !== null) {
\Yii::$application->on('afterRequest', array($this, 'processMessages'));
}
}
......@@ -127,11 +95,10 @@ class Router extends \yii\base\ApplicationComponent
public function processMessages($event)
{
$messages = \Yii::getLogger()->messages;
$export = !isset($event->data['export']) || $event->data['export'];
$final = !isset($event->data['flush']) || !$event->data['flush'];
foreach ($this->_targets as $target) {
$final = $event->name !== 'flush';
foreach ($this->targets as $target) {
if ($target->enabled) {
$target->processMessages($messages, $export, $final);
$target->processMessages($messages, $final);
}
}
}
......
......@@ -16,11 +16,9 @@ namespace yii\logging;
* to its [[levels]] and [[categories]] properties. It may also export the filtered
* messages to specific destination defined by the target, such as emails, files.
*
* Level filter and category filter are combinational, i.e., only messages
* satisfying both filter conditions will they be returned. Additionally, you
* may specify [[excludeCategories]]. If a message's category falls within the excluded
* categories, it will be filtered out, even if it passes the [[levels]] and
* [[categories]] filters.
* Level filter and category filter are combinatorial, i.e., only messages
* satisfying both filter conditions will be handled. Additionally, you
* may specify [[except]] to exclude messages of certain categories.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
......@@ -50,7 +48,7 @@ abstract class Target extends \yii\base\Component implements \yii\base\Initable
* categories starting with 'yii\db\', such as 'yii\db\dao\Connection'.
* @see categories
*/
public $excludeCategories = array();
public $except = array();
/**
* @var boolean whether to prefix each log message with the current session ID. Defaults to false.
*/
......@@ -61,7 +59,7 @@ abstract class Target extends \yii\base\Component implements \yii\base\Initable
*/
public $prefixUser = false;
/**
* @var boolean whether to log a message containing the current user name and ID. Defaults to true.
* @var boolean whether to log a message containing the current user name and ID. Defaults to false.
* @see \yii\web\User
*/
public $logUser = false;
......@@ -72,7 +70,14 @@ abstract class Target extends \yii\base\Component implements \yii\base\Initable
*/
public $logVars = array('_GET', '_POST', '_FILES', '_COOKIE', '_SESSION', '_SERVER');
/**
* @var boolean whether this target should export the collected messages to persistent storage
* (e.g. DB, email) whenever [[processMessages()]] is called. Defaults to true. If false,
* the collected messages will be stored in [[messages]] without any further processing.
*/
public $autoExport = true;
/**
* @var array the messages that are retrieved from the logger so far by this log target.
* @see autoExport
*/
public $messages = array();
......@@ -99,17 +104,17 @@ abstract class Target extends \yii\base\Component implements \yii\base\Initable
* 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 $export whether to export the processing result
* @param boolean $final whether this method is called at the end of the current application
*/
public function processMessages($messages, $export, $final)
public function processMessages($messages, $final)
{
$messages = $this->filterMessages($messages);
$this->messages = array_merge($this->messages, $messages);
if ($export && !empty($this->messages)) {
if (!empty($this->messages) && ($this->autoExport || $final)) {
$this->prepareExport($final);
$this->exportMessages($final);
$this->messages = array();
}
}
......@@ -188,7 +193,7 @@ abstract class Target extends \yii\base\Component implements \yii\base\Initable
}
if ($matched) {
foreach ($this->excludeCategories as $category) {
foreach ($this->except as $category) {
$prefix = rtrim($category, '*');
foreach ($messages as $i => $message) {
if (strpos($message[2], $prefix) === 0 && ($message[2] === $category || $prefix !== $category)) {
......@@ -214,6 +219,7 @@ abstract class Target extends \yii\base\Component implements \yii\base\Initable
*/
public function formatMessage($message)
{
return @date('Y/m/d H:i:s', $message[3]) . " [{$message[1]}] [{$message[2]}] {$message[0]}\n";
$s = is_string($message[0]) ? $message[0] : var_export($message[0], true);
return date('Y/m/d H:i:s', $message[3]) . " [{$message[1]}] [{$message[2]}] $s\n";
}
}
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