diff --git a/docs/guide/runtime-logging.md b/docs/guide/runtime-logging.md index f68be378c8..2fb439642c 100644 --- a/docs/guide/runtime-logging.md +++ b/docs/guide/runtime-logging.md @@ -1,76 +1,175 @@ Logging ======= -> Note: This section is under development. +Yii provides a powerful logging framework that is highly customizable and extensible. Using this framework, you +can easily log various types of messages, filter them, and gather them at different targets, such as files, databases, +emails. -Yii provides flexible and extensible logger that is able to handle messages according to severity level or their type. -You may filter messages by multiple criteria and forward them to files, email, debugger etc. +Using the Yii logging framework involves the following steps of work: + +* Record [log messages](#log-messages) at various places in your code; +* Configure [log targets](#log-targets) in the application configuration to filter and gather log messages; +* Examine the filtered logged messages at different targets (e.g. the [Yii debugger](tool-debugger.md)). -Logging basics --------------- +In this section, we will mainly describe the first two steps. -Basic logging is as simple as calling one method: + +## Log Messages + +Recording log messages is as simple as calling one of the following logging methods: + +* [[Yii::trace()]]: record a message to trace how a piece of code runs. This is mainly for development use. +* [[Yii::info()]]: record a message that conveys some useful information. +* [[Yii::warning()]]: record a warning message that indicates something unexpected has happened. +* [[Yii::error()]]: record a fatal error that should be investigated as soon as possible. + +These logging methods record log messages at various *severity levels* and *categories*. They share +the same function signature `function ($message, $category = 'application')`, where `$message` stands for +the log message to be recorded, while `$category` is the category of the log message. The code in the following +example records a trace message under the default category `application`: ```php -\Yii::info('Hello, I am a test log message'); +Yii::trace('start calculating average revenue'); ``` -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()]]. +> Info: Log messages can be strings as well as complex data, such as arrays or objects. It is the responsibility +of [log targets](#log-targets) to properly deal with log messages. By default, if a log message is not a string, +it will be exported as a string by calling [[yii\helpers\VarDumper::export()]]. -### Message category - -Additionally to the message itself message category could be specified in order to allow filtering such messages and -handing these differently. Message category is passed as a second argument of logging methods and is `application` by -default. - -### Severity levels - -There are multiple severity levels and corresponding methods available: - -- [[Yii::trace]] used maily for development purpose to indicate workflow of some code. Note that it only works in - development mode when `YII_DEBUG` is set to `true`. -- [[Yii::error]] used when there's unrecoverable error. -- [[Yii::warning]] used when an error occurred but execution can be continued. -- [[Yii::info]] used to keep record of important events such as administrator logins. - -Log targets ------------ - -When one of the logging methods is called, message is passed to [[yii\log\Logger]] component accessible as -`Yii::getLogger()`. Logger accumulates messages in memory and then when there are enough messages -or when the current request finishes, sends them to different log targets, such as file or email. - -You may configure the targets in application configuration, like the following: +To better organize and filter log messages, it is recommended that you specify an appropriate category for each +log message. You may choose a hierarchical naming scheme for categories, which will make it easier for +[log targets](#log-targets) to filter messages based on their categories. A simple yet effective naming scheme +is to use the PHP magic constant `__METHOD__` as category names. This is also the approached used in the core +Yii framework code. For example, ```php -[ - 'bootstrap' => ['log'], // ensure logger gets loaded before application starts +Yii::trace('start calculating average revenue', __METHOD__); +``` + +The `__METHOD__` constant evaluates as the name of the method (prefixed with the fully qualified class name) where +the constant appears. For example, it equals to the string `'app\controllers\RevenueController::calculate'` if +the above line of code is called within this method. + +> Info: The logging methods described above are actually shortcuts to the [[yii\log\Logger::log()|log()]] method +of the [[yii\log\Logger|logger object]] which is a singleton accessible through the expression `Yii::getLogger()`. When +enough messages are logged or when the application ends, the logger object will call a +[[yii\log\Dispatcher|message dispatcher]] to send recorded log messages to the registered [log targets](#log-targets). + + +## Log Targets + +A log target is an instance of [[yii\log\Target]] class or its child class. It filters the log messages by their +severity levels and categories, and then processes them in a particular way. For example, a +[[yii\log\DbTarget|database target]] keeps the log messages in a database table, while +a [[yii\log\EmailTarget|email target]] sends the log messages to pre-specified email addresses. + +You can register multiple log targets in an application by configuring them through the `log` application component +in the application configuration, like the following: + +```php +return [ + // the "log" component must be loaded during bootstrapping time + 'bootstrap' => ['log'], + 'components' => [ 'log' => [ + 'traceLevel' => YII_DEBUG ? 3 : 0, 'targets' => [ - 'file' => [ - 'class' => 'yii\log\FileTarget', - 'levels' => ['trace', 'info'], - 'categories' => ['yii\*'], - ], - 'email' => [ - 'class' => 'yii\log\EmailTarget', + [ + 'class' => 'yii\log\DbTarget', 'levels' => ['error', 'warning'], + ], + [ + 'class' => 'yii\log\EmailTarget', + 'levels' => ['error'], + 'categories' => ['yii\db\*'], 'message' => [ - 'to' => ['admin@example.com', 'developer@example.com'], - 'subject' => 'New example.com log message', + 'from' => ['log@example.com'], + 'to' => ['admin@example.com', 'developer@example.com'], + 'subject' => 'Database errors at example.com', ], ], ], ], ], +]; +``` + +Note that the `log` component must be loaded during [bootstrapping](runtime-bootstrapping.md) time so that +it can capture the log messages flushed from the [[yii\log\Logger|message logger]] as early as possible. + +In the above code, two log targets are registered in the [[yii\log\Dispatcher::targets]] property: + +* the first target selects error and warning messages and saves them in a database table; +* the second target selects error messages under the categories whose names start with `yii\db\`, and sends + them in an email to both `admin@example.com` and `developer@example.com`. + +Yii comes with the following built-in log targets. Please refer to the API documentation about these classes to +learn how to configure and use them. + +* [[yii\log\DbTarget]]: stores log messages in a database table. +* [[yii\log\EmailTarget]]: sends log messages to pre-specified email addresses. +* [[yii\log\FileTarget]]: saves log messages in files. +* [[yii\log\SyslogTarget]]: saves log messages to syslog by calling the PHP function `syslog()`. + +In the following, we will describe the features common to all log targets. + + +### Message Filtering + +For each log target, you can configure its [[yii\log\Target::levels|levels]] and +[[yii\log\Target::categories|categories]] properties to specify which severity levels and categories of the messages +that you want the target to process. + +The [[yii\log\Target::levels|levels]] property takes an array consisting of one or several of the following values: + +* `error`: corresponding to messages logged by [[Yii::error()]]. +* `warning`: corresponding to messages logged by [[Yii::warning()]]. +* `info`: corresponding to messages logged by [[Yii::info()]]. +* `trace`: corresponding to messages logged by [[Yii::trace()]]. +* `profile`: corresponding to messages logged by [[Yii::beginProfile()]], which will be explained in more details +in the [Profiling](#profiling) subsection. + +If you do not specify the [[yii\log\Target::levels|levels]] property, it means the target will process messages +of *any* severity level. + +The [[yii\log\Target::categories|categories]] property takes an array consisting of message category names or patterns. +A target will only process messages whose category can be found or match one of the patterns in this array. +A category pattern is a category name prefix with an asterisk `*` at its end. A category name matches a category pattern +if it starts with the same prefix of the pattern. For example, `yii\db\Command::execute` and `yii\db\Command::query` +are used as category names for the log messages recorded in the [[yii\db\Command]] class. They both match +the pattern `yii\db\*`. + +If you do not specify the [[yii\log\Target::categories|categories]] property, it means the target will process +messages of *any* category. + +Besides whitelisting the categories by the [[yii\log\Target::categories|categories]] property, you may also +blacklisting certain categories by the [[yii\log\Target::except|except]] property. If the category of a message +is found or matches one of the patterns in this property, it will NOT be processed by the target. + +The following target configuration specifies that the target should only process error and warning messages +under the categories whose names match either `yii\db\*` or `yii\web\HttpException:*`, but not `yii\web\HttpException:404`. + +```php +[ + 'class' => 'yii\log\FileTarget', + 'levels' => ['error', 'warning'], + 'categories' => [ + 'yii\db\*', + 'yii\web\HttpException:*', + ], + 'except' => [ + 'yii\web\HttpException:404', + ], ] ``` -In the config above we are defining two log targets: [[yii\log\FileTarget|file]] and [[yii\log\EmailTarget|email]]. -In both cases we are filtering messages handles by these targets by severity. In case of file target we're -additionally filter by category. `yii\*` means all categories starting with `yii\`. + +### Message Formatting + + +### Message Flushing and Exporting + Each log target can have a name and can be referenced via the [[yii\log\Logger::targets|targets]] property as follows: @@ -81,12 +180,12 @@ Yii::$app->log->targets['file']->enabled = false; When the application ends or [[yii\log\Logger::flushInterval|flushInterval]] is reached, Logger will call [[yii\log\Logger::flush()|flush()]] to send logged messages to different log targets, such as file, email, web. -> Note: In the above configuration we added the log component to the list of [bootstrap](runtime-bootstrapping.md) components that - get initialized when the application is initialized to ensure logging is enabled from the start. + +### Creating New Targets -Profiling ---------- + +## Profiling Performance profiling is a special type of message logging that can be used to measure the time needed for the specified code blocks to execute and find out what the performance bottleneck is. @@ -114,3 +213,4 @@ Note, code blocks need to be nested properly such as ``` Profiling results [could be displayed in debugger](module-debug.md). + diff --git a/extensions/redis/Connection.php b/extensions/redis/Connection.php index 6b5b700523..e2111443b3 100644 --- a/extensions/redis/Connection.php +++ b/extensions/redis/Connection.php @@ -247,7 +247,7 @@ class Connection extends Component return; } $connection = $this->hostname . ':' . $this->port . ', database=' . $this->database; - \Yii::trace('Opening redis DB connection: ' . $connection, __CLASS__); + \Yii::trace('Opening redis DB connection: ' . $connection, __METHOD__); $this->_socket = @stream_socket_client( 'tcp://' . $this->hostname . ':' . $this->port, $errorNumber, @@ -278,7 +278,7 @@ class Connection extends Component { if ($this->_socket !== null) { $connection = $this->hostname . ':' . $this->port . ', database=' . $this->database; - \Yii::trace('Closing DB connection: ' . $connection, __CLASS__); + \Yii::trace('Closing DB connection: ' . $connection, __METHOD__); $this->executeCommand('QUIT'); stream_socket_shutdown($this->_socket, STREAM_SHUT_RDWR); $this->_socket = null; @@ -334,7 +334,7 @@ class Connection extends Component * * @param string $name the name of the command * @param array $params list of parameters for the command - * @return array|bool|null|string Dependend on the executed command this method + * @return array|bool|null|string Dependent on the executed command this method * will return different data types: * * - `true` for commands that return "status reply". @@ -357,7 +357,7 @@ class Connection extends Component $command .= '$' . mb_strlen($arg, '8bit') . "\r\n" . $arg . "\r\n"; } - \Yii::trace("Executing Redis Command: {$name}", __CLASS__); + \Yii::trace("Executing Redis Command: {$name}", __METHOD__); fwrite($this->_socket, $command); return $this->parseResponse(implode(' ', $params));