Logging

Yii provides a flexible and extensible logging feature. Messages loggedcan be classified according to log levels and message categories. Usinglevel and category filters, selected messages can be further routed todifferent destinations, such as files, emails, browser windows, etc.

1. Message Logging

Messages can be logged by calling either Yii::log or Yii::trace. Thedifference between these two methods is that the latter logs a message onlywhen the application is in debug mode.

  1. Yii::log($message, $level, $category);
  2. Yii::trace($message, $category);

When logging a message, we need to specify its category and level.Category is a string in the format of xxx.yyy.zzz which resembles to thepath alias. For example, if a message islogged in CController, we may use the category system.web.CController.Message level should be one of the following values:

  • trace: this is the level used by Yii::trace. It is for tracingthe execution flow of the application during development.

  • info: this is for logging general information.

  • profile: this is for performance profile which is to be describedshortly.

  • warning: this is for warning messages.

  • error: this is for fatal error messages.

2. Message Routing

Messages logged using Yii::log or Yii::trace are kept in memory. Weusually need to display them in browser windows, or save them in somepersistent storage such as files, emails. This is called messagerouting, i.e., sending messages to different destinations.

In Yii, message routing is managed by a CLogRouter applicationcomponent. It manages a set of the so-called log routes. Each logroute represents a single log destination. Messages sent along a log routecan be filtered according to their levels and categories.

To use message routing, we need to install and preload a CLogRouterapplication component. We also need to configure itsroutes property with the log routes that we want. Thefollowing shows an example of the needed applicationconfiguration:

  1. array(
  2. ......
  3. 'preload'=>array('log'),
  4. 'components'=>array(
  5. ......
  6. 'log'=>array(
  7. 'class'=>'CLogRouter',
  8. 'routes'=>array(
  9. array(
  10. 'class'=>'CFileLogRoute',
  11. 'levels'=>'trace, info',
  12. 'categories'=>'system.*',
  13. ),
  14. array(
  15. 'class'=>'CEmailLogRoute',
  16. 'levels'=>'error, warning',
  17. 'emails'=>'admin@example.com',
  18. ),
  19. ),
  20. ),
  21. ),
  22. )

In the above example, we have two log routes. The first route isCFileLogRoute which saves messages in a file under the applicationruntime directory. Only messages whose level is trace or info and whosecategory starts with system. are saved. The second route isCEmailLogRoute which sends messages to the specified email addresses.Only messages whose level is error or warning are sent.

The following log routes are available in Yii:

  • CDbLogRoute: saves messages in a database table.
  • CEmailLogRoute: sends messages to specified email addresses.
  • CFileLogRoute: saves messages in a file under the application runtime directory.
  • CWebLogRoute: displays messages at the end of the current Web page.
  • CProfileLogRoute: displays profiling messages at the end of the current Web page.
Info: Message routing occurs at the end of the current request cycle when the onEndRequest event is raised. To explicitly terminate the processing of the current request, call CApplication::end() instead of die() or exit(), because CApplication::end() will raise the onEndRequest event so that the messages can be properly logged.

Message Filtering

As we mentioned, messages can be filtered according to their levels andcategories before they are sent long a log route. This is done by settingthe levels and categoriesproperties of the corresponding log route. Multiple levels or categoriesshould be concatenated by commas.

Because message categories are in the format of xxx.yyy.zzz, we maytreat them as a category hierarchy. In particular, we say xxx is theparent of xxx.yyy which is the parent of xxx.yyy.zzz. We can then usexxx.* to represent category xxx and all its child and grandchildcategories.

Logging Context Information

Starting from version 1.0.6, we can specify to log additional context information,such as PHP predefined variables (e.g. $_GET, $_SERVER), session ID, user name, etc.This is accomplished by specifying the CLogRoute::filter property of a log route to bea suitable log filter.

The framework comes with the convenient CLogFilter that may be used as the needed logfilter in most cases. By default, CLogFilter will log a message with variables like$_GET, $_SERVER which often contains valuable system context information.CLogFilter can also be configured to prefix each logged message with session ID, username, etc.,which may greatly simplifying the global search when we are checking the numerous logged messages.

The following configuration shows how to enable logging context information. Note that eachlog route may have its own log filter. And by default, a log route does not have a log filter.

  1. array(
  2. ......
  3. 'preload'=>array('log'),
  4. 'components'=>array(
  5. ......
  6. 'log'=>array(
  7. 'class'=>'CLogRouter',
  8. 'routes'=>array(
  9. array(
  10. 'class'=>'CFileLogRoute',
  11. 'levels'=>'error',
  12. 'filter'=>'CLogFilter',
  13. ),
  14. ...other log routes...
  15. ),
  16. ),
  17. ),
  18. )

Starting from version 1.0.7, Yii supports logging call stack information in the messages that arelogged by calling Yii::trace. This feature is disabled by default because it lowers performance.To use this feature, simply define a constant named YII_TRACE_LEVEL at the beginning of the entryscript (before including yii.php) to be an integer greater than 0. Yii will then append toevery trace message with the file name and line number of the call stacks belonging to applicationcode. The number YII_TRACE_LEVEL determines how many layers of each call stack should be recorded.This information is particularly useful during development stage as it can help us identify theplaces that trigger the trace messages.

3. Performance Profiling

Performance profiling is a special type of message logging. Performanceprofiling can be used to measure the time needed for the specified codeblocks and find out what the performance bottleneck is.

To use performance profiling, we need to identify which code blocks needto be profiled. We mark the beginning and the end of each code block byinserting the following methods:

  1. Yii::beginProfile('blockID');
  2. ...code block being profiled...
  3. Yii::endProfile('blockID');

where blockID is an ID that uniquely identifies the code block.

Note, code blocks need to be nested properly. That is, a code block cannotintersect with another. It must be either at a parallel level or becompletely enclosed by the other code block.

To show profiling result, we need to install a CLogRouter applicationcomponent with a CProfileLogRoute log route. This is the same as we dowith normal message routing. The CProfileLogRoute route will display theperformance results at the end of the current page.

Profiling SQL Executions

Profiling is especially useful when working with database since SQL executionsare often the main performance bottleneck of an application. While we can manuallyinsert beginProfile and endProfile statements at appropriate places to measurethe time spent in each SQL execution, starting from version 1.0.6, Yii providesa more systematic approach to solve this problem.

By setting CDbConnection::enableProfiling to be true in the application configuration,every SQL statement being executed will be profiled. The results can be readily displayedusing the aforementioned CProfileLogRoute, which can show us how much time is spentin executing what SQL statement. We can also call CDbConnection::getStats() to retrievethe total number SQL statements executed and their total execution time.

原文: https://www.yiichina.com/doc/guide/1.0/topics.logging