NO IMAGE

Yii 提供了一個靈活可擴充套件的日誌功能。記錄的日誌可以通過日誌級別和資訊分類進行歸類。通過使用級別和分類過濾器,所選的資訊還可以進一步路由到不同的目的地,例如一個檔案,Email,瀏覽器視窗等。 

1. 資訊記錄 

資訊可以通過 Yii::log 或 Yii::trace 記錄。其區別是後者只在當應用程式執行在 除錯模式(debug mode) 中時才會記錄資訊。 

Php程式碼  收藏程式碼
  1. Yii::log($message, $level, $category);  
  2. 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 屬性為我們想要的那些日誌路由。下面的程式碼演示了一個所需的 應用配置 示例: 

Php程式碼  收藏程式碼
  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’=>’[email protected]’,  
  18.                 ),  
  19.             ),  
  20.         ),  
  21.     ),  
  22. )  

在上面的例子中,我們定義了兩個日誌路由。第一個是 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. 

Php程式碼  收藏程式碼
  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 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是什麼,那麼就可以推出執行後的結果是什麼。 

Php程式碼  收藏程式碼
  1. //1,在 ../config/main.php裡增加’class’=>’CProfileLogRoute’  
  2. ‘log’=>array(  
  3.             ‘class’=>’CLogRouter’,  
  4.             ‘routes’=>array(  
  5.                 array(  
  6.                     ‘class’=>’CFileLogRoute’,  
  7.                     ‘levels’=>’error, warning’,  
  8.                 ),  
  9.                 /*  此處為本次增加 */  
  10.                 array(  
  11.                     ‘class’=>’CProfileLogRoute’,  
  12.                 ),  
  13.                 // uncomment the following to show log messages on web pages  
  14.                 /* 
  15.                 array( 
  16.                     ‘class’=>’CWebLogRoute’, 
  17.                 ), 
  18.                 */  
  19.             ),  
  20.         ),  
  21.   
  22. //2,在原始碼處增加三行程式碼  
  23. $c = new CDbCriteria();  
  24. $c->join = “JOIN idc_user on t.id=idc_user.user_id”;  
  25. $c->condition = “idc_user.idc_id=$idc_id”;  
  26.   
  27. Yii::beginProfile(‘block1’);  
  28. $r = User::model()->with(‘Idcs’)->findAll($c);  
  29. Yii::endProfile(‘block1’);  
  30.   
  31.   
  32. //整理列印結果如下  
  33. 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`  
  34. FROM `user` `t`  
  35. JOIN idc_user ON t.id = idc_user.user_id  
  36. LEFT OUTER JOIN `idc_user` `Idcs_Idcs` ON ( `t`.`id` = `Idcs_Idcs`.`user_id` )  
  37. LEFT OUTER JOIN `idc` `Idcs` ON ( `Idcs`.`id` = `Idcs_Idcs`.`idc_id` )  
  38. WHERE (  
  39. idc_user.idc_id =6  
  40. )  
  41.   
  42. //列印結果如下  
  43. block2  1   0.01122     0.01122     0.01122     0.01122  
  44. 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  
  45. system.db.CDbCommand.query(SHOW COLUMNS FROM `user`)    1   0.00083     0.00083     0.00083     0.00083  
  46. system.db.CDbCommand.query(SHOW COLUMNS FROM `idc`)     1   0.00078     0.00078     0.00078     0.00078  
  47. system.db.CDbCommand.query(SHOW COLUMNS FROM `idc_user`)    1   0.00060     0.00060     0.00060     0.00060  
  48. system.db.CDbCommand.query( SELECT data FROM YiiSession WHERE expire>1339135578 AND id=:id )     1   0.00047     0.00047     0.00047     0.00047  
  49. system.db.CDbCommand.query(SELECT * FROM `user` `t` WHERE `t`.`id`=8 LIMIT 1)   1   0.00045     0.00045     0.00045     0.00045  
  50. system.db.CDbCommand.query(SHOW CREATE TABLE `user`)    1   0.00038     0.00038     0.00038     0.00038  
  51. system.db.CDbCommand.query(SHOW CREATE TABLE `idc`)     1   0.00038     0.00038     0.00038     0.00038  
  52. system.db.CDbCommand.query(SHOW CREATE TABLE `idc_user`)    1   0.00036     0.00036     0.00036     0.00036  

http://zccst.iteye.com/blog/1554803