Yii 提供了一个灵活可扩展的日志功能。记录的日志可以通过日志级别和信息分类进行归类。通过使用级别和分类过滤器,所选的信息还可以进一步路由到不同的目的地,例如一个文件,Email,浏览器窗口等。
1. 信息记录
信息可以通过 Yii::log 或 Yii::trace 记录。其区别是后者只在当应用程序运行在 调试模式(debug mode) 中时才会记录信息。
Yii::log($message, $level, $category); Yii::trace($message, $category);
当记录信息时,我们需要指定它的分类和级别分类是一段格式类似于 路径别名 的字符串。例如,如果一条信息是在 CController 中记录的,我们可以使用 system.web.CController 作为分类。信息级别应该是下列值中的一种:
trace: 这是在 Yii::trace 中使用的级别。它用于在开发中跟踪程序的执行流程。
info: 这个用于记录普通的信息。
profile: 这个是性能概述(profile)。下面马上会有更详细的说明。
warning: 这个用于警告(warning)信息。
error: 这个用于致命错误(fatal error)信息。
2. 信息路由
通过 Yii::log 或 Yii::trace 记录的信息是保存在内存中的。我们通常需要将它们显示到浏览器窗口中,或者将他们保存到一些持久存储例如文件、Email中。这个就叫作 信息路由,例如,发送信息到不同的目的地。
在 Yii 中,信息路由是由一个叫做 CLogRouter 的应用组件管理的。它负责管理一系列称作 日志路由 的东西。每个日志路由代表一个单独的日志目的地。通过一个日志路由发送的信息会被他们的级别和分类过滤。
要使用信息路由,我们需要安装并预加载一个 CLogRouter 应用组件。我们也还需要配置它的 routes 属性为我们想要的那些日志路由。下面的代码演示了一个所需的 应用配置 示例:
array( ...... 'preload'=>array('log'), 'components'=>array( ...... 'log'=>array( 'class'=>'CLogRouter', 'routes'=>array( array( 'class'=>'CFileLogRoute', 'levels'=>'trace, info', 'categories'=>'system.*', ), array( 'class'=>'CEmailLogRoute', 'levels'=>'error, warning', 'emails'=>'admin@example.com', ), ), ), ), )
在上面的例子中,我们定义了两个日志路由。第一个是 CFileLogRoute ,它会把信息保存在位于应用程序 runtime 目录中的一个文件中。而且只有级别为 trace 或 info 、分类以 system. 开头的信息才会被保存。 第二个路由是 CEmailLogRoute ,它会将信息发送到指定的 email 地址,且只有级别为 error 或 warning 的才会发送。
在 Yii 中,有下列几种日志路由可用:
CDbLogRoute: 将信息保存到数据库的表中。
CEmailLogRoute: 发送信息到指定的 Email 地址。
CFileLogRoute: 保存信息到应用程序 runtime 目录中的一个文件中。
CWebLogRoute: 将 信息 显示在当前页面的底部。
CProfileLogRoute: 在页面的底部显示概述(profiling)信息。
注:信息路由发生在当前请求周期最后的 onEndRequest 事件触发时。 要显式终止当前请求过程,请调用 CApplication::end() 而不是使用 die() 或 exit(),因为 CApplication::end() 将会触发 onEndRequest 事件, 这样信息才会被顺利地记录。
3. 信息过滤
正如我们所提到的,信息可以在他们被发送到一个日志路由之前通过它们的级别和分类过滤。这是通过设置对应日志路由的 levels 和 categories 属性完成的。多个级别或分类应使用逗号连接。
由于信息分类是类似 xxx.yyy.zzz 格式的,我们可以将其视为一个分类层级。具体地,我们说 xxx 是 xxx.yyy 的父级,而xxx.yyy 又是 xxx.yyy.zzz 的父级。这样我们就可以使用 xxx.* 表示分类 xxx 及其所有的子级和孙级分类
4. 记录上下文信息
从版本 1.0.6 起,我们可以设置记录附加的上下文信息,比如 PHP 的预定义变量(例如 $_GET, $_SERVER),session ID,用户名等。这是通过指定一个日志路由的 CLogRoute::filter属性为一个合适的日志过滤规则实现的。
The framework comes with the convenient CLogFilter that may be used as the needed log filter 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 each log route may have its own log filter. And by default, a log route does not have a log filter.
array( ...... 'preload'=>array('log'), 'components'=>array( ...... 'log'=>array( 'class'=>'CLogRouter', 'routes'=>array( array( 'class'=>'CFileLogRoute', 'levels'=>'error', 'filter'=>'CLogFilter', ), ...other log routes... ), ), ), )
Starting from version 1.0.7, Yii supports logging call stack information in the messages that are logged 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 entry script (before including yii.php) to be an integer greater than 0. Yii will then append to every trace message with the file name and line number of the call stacks belonging to application code. 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 the places that trigger the trace messages.
5. Performance Profiling
Performance profiling is a special type of message logging. Performance profiling can be used to measure the time needed for the specified code blocks and find out what the performance bottleneck is.
To use performance profiling, we need to identify which code blocks need to be profiled. We mark the beginning and the end of each code block by inserting the following methods:
Yii::beginProfile('blockID');
...code block being profiled...
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 cannot intersect with another. It must be either at a parallel level or be completely enclosed by the other code block.
To show profiling result, we need to install a CLogRouter application component with a CProfileLogRoute log route. This is the same as we do with normal message routing. The CProfileLogRoute route will display the performance results at the end of the current page.
6. Profiling SQL Executions
Profiling is especially useful when working with database since SQL executions are often the main performance bottleneck of an application. While we can manually insert beginProfile and endProfile statements at appropriate places to measure the time spent in each SQL execution, starting from version 1.0.6, Yii provides a 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 displayed using the aforementioned CProfileLogRoute, which can show us how much time is spent in executing what SQL statement. We can also call CDbConnection::getStats() to retrieve the total number SQL statements executed and their total execution time.
使用实例:想查看如下结果,但由于较大,var_dump时浏览器会崩溃,于是想到如果知道执行的sql是什么,那么就可以推出执行后的结果是什么。
//1,在 ../config/main.php里增加'class'=>'CProfileLogRoute' 'log'=>array( 'class'=>'CLogRouter', 'routes'=>array( array( 'class'=>'CFileLogRoute', 'levels'=>'error, warning', ), /* 此处为本次增加 */ array( 'class'=>'CProfileLogRoute', ), // uncomment the following to show log messages on web pages /* array( 'class'=>'CWebLogRoute', ), */ ), ), //2,在源码处增加三行代码 $c = new CDbCriteria(); $c->join = "JOIN idc_user on t.id=idc_user.user_id"; $c->condition = "idc_user.idc_id=$idc_id"; Yii::beginProfile('block1'); $r = User::model()->with('Idcs')->findAll($c); Yii::endProfile('block1'); //整理打印结果如下 SELECT `t`.`id` AS `t0_c0` , `t`.`username` AS `t0_c1` , `t`.`password` AS `t0_c2` , `t`.`display_name` AS `t0_c3` , `t`.`tel` AS `t0_c4` , `t`.`mobile` AS `t0_c5` , `t`.`email` AS `t0_c6` , `t`.`hi_id` AS `t0_c7` , `t`.`company_id` AS `t0_c8` , `t`.`last_login_at` AS `t0_c9` , `t`.`last_pwd_updated_at` AS `t0_c10` , `t`.`created_at` AS `t0_c11` , `Idcs`.`id` AS `t1_c0` , `Idcs`.`name` AS `t1_c1` , `Idcs`.`desc` AS `t1_c2` , `Idcs`.`created_at` AS `t1_c3` , `Idcs`.`chinese_name` AS `t1_c4` , `Idcs`.`clientele` AS `t1_c5` , `Idcs`.`contact_man` AS `t1_c6` , `Idcs`.`contact_phone` AS `t1_c7` , `Idcs`.`post_code` AS `t1_c8` , `Idcs`.`address` AS `t1_c9` , `Idcs`.`email` AS `t1_c10` , `Idcs`.`weight` AS `t1_c11` , `Idcs`.`pool_id` AS `t1_c12` , `Idcs`.`provider_id` AS `t1_c13` FROM `user` `t` JOIN idc_user ON t.id = idc_user.user_id LEFT OUTER JOIN `idc_user` `Idcs_Idcs` ON ( `t`.`id` = `Idcs_Idcs`.`user_id` ) LEFT OUTER JOIN `idc` `Idcs` ON ( `Idcs`.`id` = `Idcs_Idcs`.`idc_id` ) WHERE ( idc_user.idc_id =6 ) //打印结果如下 block2 1 0.01122 0.01122 0.01122 0.01122 system.db.CDbCommand.query(SELECT `t`.`id` AS `t0_c0`, `t`.`username` AS `t0_c1`, `t`.`password` AS `t0_c2`, `t`.`display_name` AS `t0_c3`, `t`.`tel` AS `t0_c4`, `t`.`mobile` AS `t0_c5`, `t`.`email` AS `t0_c6`, `t`.`hi_id` AS `t0_c7`, `t`.`company_id` AS `t0_c8`, `t`.`last_login_at` AS `t0_c9`, `t`.`last_pwd_updated_at` AS `t0_c10`, `t`.`created_at` AS `t0_c11`, `Idcs`.`id` AS `t1_c0`, `Idcs`.`name` AS `t1_c1`, `Idcs`.`desc` AS `t1_c2`, `Idcs`.`created_at` AS `t1_c3`, `Idcs`.`chinese_name` AS `t1_c4`, `Idcs`.`clientele` AS `t1_c5`, `Idcs`.`contact_man` AS `t1_c6`, `Idcs`.`contact_phone` AS `t1_c7`, `Idcs`.`post_code` AS `t1_c8`, `Idcs`.`address` AS `t1_c9`, `Idcs`.`email` AS `t1_c10`, `Idcs`.`weight` AS `t1_c11`, `Idcs`.`pool_id` AS `t1_c12`, `Idcs`.`provider_id` AS `t1_c13` FROM `user` `t` JOIN idc_user on t.id=idc_user.user_id LEFT OUTER JOIN `idc_user` `Idcs_Idcs` ON (`t`.`id`=`Idcs_Idcs`.`user_id`) LEFT OUTER JOIN `idc` `Idcs` ON (`Idcs`.`id`=`Idcs_Idcs`.`idc_id`) WHERE (idc_user.idc_id=6)) 1 0.00086 0.00086 0.00086 0.00086 system.db.CDbCommand.query(SHOW COLUMNS FROM `user`) 1 0.00083 0.00083 0.00083 0.00083 system.db.CDbCommand.query(SHOW COLUMNS FROM `idc`) 1 0.00078 0.00078 0.00078 0.00078 system.db.CDbCommand.query(SHOW COLUMNS FROM `idc_user`) 1 0.00060 0.00060 0.00060 0.00060 system.db.CDbCommand.query( SELECT data FROM YiiSession WHERE expire>1339135578 AND id=:id ) 1 0.00047 0.00047 0.00047 0.00047 system.db.CDbCommand.query(SELECT * FROM `user` `t` WHERE `t`.`id`=8 LIMIT 1) 1 0.00045 0.00045 0.00045 0.00045 system.db.CDbCommand.query(SHOW CREATE TABLE `user`) 1 0.00038 0.00038 0.00038 0.00038 system.db.CDbCommand.query(SHOW CREATE TABLE `idc`) 1 0.00038 0.00038 0.00038 0.00038 system.db.CDbCommand.query(SHOW CREATE TABLE `idc_user`) 1 0.00036 0.00036 0.00036 0.00036
相关推荐
- **扩展**:扩展是指第三方提供的额外功能包,可以轻松地为Yii应用添加新功能。 - 扩展安装:通过Composer安装所需的扩展包。 - 使用扩展:在项目中启用扩展,并按照文档说明进行配置。 #### 七、调试与日志 - ...
十、错误处理与日志 Yii 2.0 提供了统一的错误处理和日志记录机制,帮助开发者调试和优化应用,同时提供了一套优雅的方式显示错误信息。 十一、部署与性能优化 手册还会介绍如何将开发完成的应用部署到生产环境,...
16、友好的使用第三方代码:Yii精心设计让它第三方代码非常好的工作。例如,你可以在你的Yii应用程序中使用PEAR或Zend Framework的代码。 17、详细的文档:每一个单一的方法或属性都非常清楚的记录着。同时提供...
《基于Yii2的基础管理框架——RageFrame深度解析》 在现代Web开发中,高效的框架是构建强大应用程序的关键。Yii2作为一款流行的PHP框架,以其高性能、灵活性和丰富的特性受到开发者们的广泛青睐。本文将深入探讨一...
### Yii_Cookbook知识点概述 #### 一、简介 《Yii Cookbook》是一本关于Yii框架的中文参考手册,旨在提供一系列教程,帮助开发者解决具体的开发任务。本书面向所有拥有Yii论坛账户的用户开放,鼓励大家积极参与创建...
第十天:PHP框架与项目实践 - PHP框架介绍:讲解常见的PHP框架,如Laravel、CodeIgniter、Yii等,以及它们的优势和应用场景。 - 网站建设:通过一个简单的博客系统实例,将所学知识应用于实际项目中,体验完整的PHP...
#### 十四、Yii2 安装第三方扩展应用 **安装第三方扩展应用的方法:** 1. **使用Composer**: - 通过Composer添加第三方扩展到项目中是最常用的方法。 - 在 `composer.json` 文件中添加扩展的名称和版本,然后...
《PHP杂志(16~20)》是由PHPCHINA发行的一系列专业期刊,涵盖了从第16期到第20期的内容。这些期刊深入探讨了PHP编程语言及其在现代Web开发中的应用,旨在帮助开发者提升技能,了解最新的技术趋势和最佳实践。以下是...
六、图片处理 高仿花瓣网的源码可能会涉及图片的上传、缩略图生成、裁剪等操作。这可能用到PHP的GD库或ImageMagick,实现对图像的处理和优化。 七、模板引擎 为了分离业务逻辑和视图,源码可能采用了如Twig或Smarty...
... ... ...3. 数据类型:包括字符串、...每个章节对应压缩包内的子文件,例如Ch5可能对应第五章的内容,读者可以通过阅读源代码加深理解。请结合实际项目需求,逐步学习并实践这些知识,相信你将成为一名熟练的PHP开发者。