Browse Source

...

tags/2.0.0-beta
Qiang Xue 13 years ago
parent
commit
d743d9bc02
  1. 2
      framework/logging/DbTarget.php
  2. 2
      framework/logging/EmailTarget.php
  3. 2
      framework/logging/FileTarget.php
  4. 49
      framework/logging/Logger.php
  5. 61
      framework/logging/Router.php
  6. 30
      framework/logging/Target.php

2
framework/logging/DbTarget.php

@ -94,7 +94,5 @@ class DbTarget extends Target
':message' => $message[0], ':message' => $message[0],
))->execute(); ))->execute();
} }
$this->messages = array();
} }
} }

2
framework/logging/EmailTarget.php

@ -53,8 +53,6 @@ class EmailTarget extends Target
foreach ($this->emails as $email) { foreach ($this->emails as $email) {
$this->sendEmail($subject, $body, $email, $this->sentFrom, $this->headers); $this->sendEmail($subject, $body, $email, $this->sentFrom, $this->headers);
} }
$this->messages = array();
} }
/** /**

2
framework/logging/FileTarget.php

@ -79,8 +79,6 @@ class FileTarget extends Target
$messages[] = $this->formatMessage($message); $messages[] = $this->formatMessage($message);
} }
@file_put_contents($logFile, implode('', $messages), FILE_APPEND | LOCK_EX); @file_put_contents($logFile, implode('', $messages), FILE_APPEND | LOCK_EX);
$this->messages = array();
} }
/** /**

49
framework/logging/Logger.php

@ -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. * 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. * 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. * 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; public $flushInterval = 1000;
/** /**
* @var boolean this property will be passed as the parameter to [[flush]] when it is * @var array logged messages. This property is mainly managed by [[log()]] and [[flush()]].
* 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]].
* Each log message is of the following structure: * Each log message is of the following structure:
* *
* ~~~ * ~~~
* array( * array(
* [0] => message (string) * [0] => message (mixed)
* [1] => level (string) * [1] => level (string)
* [2] => category (string) * [2] => category (string)
* [3] => timestamp (float, obtained by microtime(true)) * [3] => timestamp (float, obtained by microtime(true))
@ -67,7 +59,7 @@ class Logger extends \yii\base\Component
* Logs an error message. * Logs an error message.
* An error message is typically logged when an unrecoverable error occurs * An error message is typically logged when an unrecoverable error occurs
* during the execution of an application. * 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. * @param string $category the category of the message.
*/ */
public function error($message, $category = 'application') public function error($message, $category = 'application')
@ -79,7 +71,7 @@ class Logger extends \yii\base\Component
* Logs a trace message. * Logs a trace message.
* Trace messages are logged mainly for development purpose to see * Trace messages are logged mainly for development purpose to see
* the execution work flow of some code. * 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. * @param string $category the category of the message.
*/ */
public function trace($message, $category = 'application') public function trace($message, $category = 'application')
@ -91,24 +83,24 @@ class Logger extends \yii\base\Component
* Logs a warning message. * Logs a warning message.
* A warning message is typically logged when an error occurs while the execution * A warning message is typically logged when an error occurs while the execution
* can still continue. * 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. * @param string $category the category of the message.
*/ */
public function warning($message, $category = 'application') public function warning($message, $category = 'application')
{ {
$this->log($message, self::LEVEL_TRACE, $category); $this->log($message, self::LEVEL_WARNING, $category);
} }
/** /**
* Logs an informative message. * Logs an informative message.
* An informative message is typically logged by an application to keep record of * An informative message is typically logged by an application to keep record of
* something important (e.g. an administrator logs in). * 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. * @param string $category the category of the message.
*/ */
public function info($message, $category = 'application') 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 * @param string $category the category of this log message
* @see endProfile * @see endProfile
*/ */
public function beginProfile($token, $category) public function beginProfile($token, $category = 'application')
{ {
$this->log($token, self::LEVEL_PROFILE_BEGIN, $category); $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 * @param string $category the category of this log message
* @see beginProfile * @see beginProfile
*/ */
public function endProfile($token, $category) public function endProfile($token, $category = 'application')
{ {
$this->log($token, self::LEVEL_PROFILE_END, $category); $this->log($token, self::LEVEL_PROFILE_END, $category);
} }
@ -145,9 +137,10 @@ class Logger extends \yii\base\Component
* 'trace', 'info', 'warning', 'error', 'profile'. * 'trace', 'info', 'warning', 'error', 'profile'.
* @param string $category the category of the message. * @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(); $traces = debug_backtrace();
$count = 0; $count = 0;
foreach ($traces as $trace) { foreach ($traces as $trace) {
@ -159,25 +152,19 @@ class Logger extends \yii\base\Component
} }
} }
} }
$this->messages[] = array($message, $level, $category, $time);
$this->messages[] = array($message, $level, $category, microtime(true));
if (count($this->messages) >= $this->flushInterval && $this->flushInterval > 0) { if (count($this->messages) >= $this->flushInterval && $this->flushInterval > 0) {
$this->flush($this->autoExport); $this->flush();
} }
} }
/** /**
* Removes all recorded messages from the memory. * Removes all recorded messages from the memory.
* This method will raise a `flush` event. * 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( $this->trigger('flush');
'export' => $export,
'flush' => true,
)));
$this->messages = array(); $this->messages = array();
} }

61
framework/logging/Router.php

@ -57,17 +57,10 @@ namespace yii\logging;
class Router extends \yii\base\ApplicationComponent 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; public $targets = array();
/**
* Constructor.
*/
public function __construct()
{
$this->_targets = new \yii\base\Dictionary;
}
/** /**
* Initializes this application component. * Initializes this application component.
@ -78,42 +71,17 @@ class Router extends \yii\base\ApplicationComponent
public function init() public function init()
{ {
parent::init(); parent::init();
\Yii::getLogger()->on('flush', array($this, 'processMessages'));
if (($app = \Yii::$application) !== null) {
$app->on('afterRequest', array($this, 'processMessages'));
}
}
/** foreach ($this->targets as $name => $target) {
* Returns the log targets managed by this log router. if (!$target instanceof Target) {
* The keys of the dictionary are the names of the log targets. $this->targets[$name] = \Yii::createObject($target);
* 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;
}
/**
* 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) public function processMessages($event)
{ {
$messages = \Yii::getLogger()->messages; $messages = \Yii::getLogger()->messages;
$export = !isset($event->data['export']) || $event->data['export']; $final = $event->name !== 'flush';
$final = !isset($event->data['flush']) || !$event->data['flush']; foreach ($this->targets as $target) {
foreach ($this->_targets as $target) {
if ($target->enabled) { if ($target->enabled) {
$target->processMessages($messages, $export, $final); $target->processMessages($messages, $final);
} }
} }
} }

30
framework/logging/Target.php

@ -16,11 +16,9 @@ namespace yii\logging;
* to its [[levels]] and [[categories]] properties. It may also export the filtered * to its [[levels]] and [[categories]] properties. It may also export the filtered
* messages to specific destination defined by the target, such as emails, files. * messages to specific destination defined by the target, such as emails, files.
* *
* Level filter and category filter are combinational, i.e., only messages * Level filter and category filter are combinatorial, i.e., only messages
* satisfying both filter conditions will they be returned. Additionally, you * satisfying both filter conditions will be handled. Additionally, you
* may specify [[excludeCategories]]. If a message's category falls within the excluded * may specify [[except]] to exclude messages of certain categories.
* categories, it will be filtered out, even if it passes the [[levels]] and
* [[categories]] filters.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @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'. * categories starting with 'yii\db\', such as 'yii\db\dao\Connection'.
* @see categories * @see categories
*/ */
public $excludeCategories = array(); public $except = array();
/** /**
* @var boolean whether to prefix each log message with the current session ID. Defaults to false. * @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; 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 * @see \yii\web\User
*/ */
public $logUser = false; 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'); 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. * @var array the messages that are retrieved from the logger so far by this log target.
* @see autoExport
*/ */
public $messages = array(); 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). * 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 * @param array $messages log messages to be processed. See [[Logger::messages]] for the structure
* of each message. * 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 * @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); $messages = $this->filterMessages($messages);
$this->messages = array_merge($this->messages, $messages); $this->messages = array_merge($this->messages, $messages);
if ($export && !empty($this->messages)) { if (!empty($this->messages) && ($this->autoExport || $final)) {
$this->prepareExport($final); $this->prepareExport($final);
$this->exportMessages($final); $this->exportMessages($final);
$this->messages = array();
} }
} }
@ -188,7 +193,7 @@ abstract class Target extends \yii\base\Component implements \yii\base\Initable
} }
if ($matched) { if ($matched) {
foreach ($this->excludeCategories as $category) { foreach ($this->except as $category) {
$prefix = rtrim($category, '*'); $prefix = rtrim($category, '*');
foreach ($messages as $i => $message) { foreach ($messages as $i => $message) {
if (strpos($message[2], $prefix) === 0 && ($message[2] === $category || $prefix !== $category)) { 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) 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";
} }
} }

Loading…
Cancel
Save