《PHP編程:PHP的Yii框架的常用日志操作總結》要點:
本文介紹了PHP編程:PHP的Yii框架的常用日志操作總結,希望對您有用。如果有疑問,可以聯系我們。
相關主題:YII框架
PHP應用日志
Yii提供了一個高度自定義化和高擴展性的日志框架.根據使用場景的不同,你可以很容易的對各種消息就行記錄、過濾、合并,好比說文本文件,數據庫文件,郵件.
PHP應用使用Yii的日志框架包括如下步驟:
PHP應用調用日志記錄的辦法
PHP應用記錄日志其實就是簡簡單單的調用如下的辦法:
PHP應用上面的這些辦法雖然根據不同的level和類型來記錄信息,但是實際上它們調用的是同一個辦法function($message, $category = 'application').其中$message就是要記錄的信息,$category表示的是這個日志的歸屬類.下面的代碼表示在默認的‘application'分類下面記錄了一條trace類型的信息.
PHP應用
Yii::trace('start calculating average revenue');
PHP應用提示:記錄的$message可以是簡單的string也可以是復雜的數組、對象.你應該根據不同的場景下日志記錄的職責選取合適的$message類型.默認情況下,如果你記錄的$message不是String,日志在導出的時候都會調用[[yii\helpers\VarDumper::export()]] 辦法來輸出一個string類型的消息.
PHP應用為了更好的組織管理及篩選日志消息,通常情況下應當為每一種日志分配合適的類別.你可以選擇一種有明顯等級區分意思的分類,用以方便根據不同的目的來篩選不同分類的日志.一種簡單且有效的命名方式就是使用PHP的魔術常量METHOD來作為分類的名稱.Yii框架里面的核心代碼在做日志記錄的時候就是這么干的.好比說:
PHP應用
Yii::trace('start calculating average revenue', __METHOD__);
PHP應用在有常量METHOD出現的地方,它表示的就是當前的辦法的名稱(并且加上了當前辦法所屬的類的完整前綴).舉個例子吧,如果在app\controllers\RevenueController這個類里面的calculate辦法里面有上面的那行代碼,那么此時的METHOD表示的就是‘app\controllers\RevenueController::calculate'.
PHP應用提示:上面所說的辦法事實上只是單例對象[[yii\log\Logger|logger object]] 的[[yii\log\Logger::log()|log()]]辦法的簡單使用,我們可以通過Yii::getLogger()辦法來獲得這個單例對象.當我們記錄了足夠的日志信息或者當前的應用運行結束了,日志對象將調用[yii\log\Dispatcher|message dispatcher]] 辦法把記錄的日志信息寫入到配置的目的位置.
PHP應用log targets
一個log target是[[yii\log\Target]]或者其子類的實例.它根據嚴重的等級和分類類過濾日志,然后把日志導出到合適的媒介上面去.就好比說,一個[[yii\log\DbTarget|database target]] 對象就會把過濾之后的日志信息導出到對應數據庫.
你可以在應用的配置文件中的日志組件處注冊多個log targets,就像下面這樣:
PHP應用
return [
// the "log" component must be loaded during bootstrapping time
'bootstrap' => ['log'],
'components' => [
'log' => [
'targets' => [
[
'class' => 'yii\log\DbTarget',
'levels' => ['error', 'warning'],
],
[
'class' => 'yii\log\EmailTarget',
'levels' => ['error'],
'categories' => ['yii\db\*'],
'message' => [
'from' => ['log@example.com'],
'to' => ['admin@example.com', 'developer@example.com'],
'subject' => 'Database errors at example.com',
],
],
],
],
],
];
PHP應用注意:日志組件必需在bootstrap中配置,這樣才能把日志信息分發到對應的log target.
上面的代碼里面,兩個log target注冊到了[[yii\log\Dispatcher::targets]]里面.
PHP應用第一個篩選出錯誤和警告信息并且把這些信息保留到了數據庫.
第二個篩選出分類以yii\db*開頭的錯誤信息,并把這些信息通過郵件發送到admin@example.com 和 developer@example.com.
Yii有下面這些內置的log targets,你可以參考API文檔來學習具體怎么去配置和使用它們.
PHP應用接下來,我們就來看看常見的log target具有的功能.
PHP應用消息過濾
就每一種log target而言,你可以配置它的 [[yii\log\Target::levels|levels]] 和 [[yii\log\Target::categories|categories]]屬性類設置它的嚴重程度以及歸屬的分類.
[[yii\log\Target::levels|levels]]屬性的采用一個數組里面的一個或者多個值,這個數組包括如下值:
PHP應用如果你沒有指定[[yii\log\Target::levels|levels]] 的值,那么任何level的信息都會被記錄.
PHP應用[[yii\log\Target::categories|categories]] 屬性的值是數組,這個數組里面的值可以是一個具體的分類名稱,也可以是類似正則的匹配模式.只有在target能在這個數組里面找到對應的分類名或者符合某一個匹配模式,他才會處理這些消息.這里的匹配模式的組成是在分類的名稱后面加上一個號.如果這個分類恰好和這個匹配模式的號前的字符匹配,那么也就是這個分類找到對應匹配值.舉個例來說,在類[[yii\db\Command]]中的yii\db\Command::execute和yii \db\Command:: query 辦法使用類名類記錄相關日志信息,那么這個時候他們都匹配模式yii\db*
PHP應用同樣的,如果我們沒有指定[[yii\log\Target::categories|categories]],那么每一種分類的日志信息都會被處理.
除了通過[[yii\log\Target::categories|categories]] 屬性來設置分類的白名單外,你也可以通過 [[yii\log\Target::except|except]]屬性來設置分類的黑名單.屬于黑名單的分類日志信息不會被target處理.
PHP應用下面的配置指定了一個分類匹配yii\db*或者 yii\web\HttpException:*,但又不包含yii\web\HttpException:404的分類,而且它只處理錯誤和警告的日志信息.
PHP應用
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
'categories' => [
'yii\db\*',
'yii\web\HttpException:*',
],
'except' => [
'yii\web\HttpException:404',
],
]
PHP應用
2014-10-04 18:10:15 [::1][][-][trace][yii\base\Module::getModule] Loading module: debug
PHP應用默認情況下,[[yii\log\Target::formatMessage()]]:會幫我們把日志信息格式化成下面的這種格式:
PHP應用
Timestamp [IP address][User ID][Session ID][Severity Level][Category] Message Text
PHP應用你可以通過給[[yii\log\Target::prefix]] 屬性配置一個自定義的回調函數來 自定義日志的前綴.下面的代碼就實現了在每條日志信息前面加上了用戶的ID(ip地址,sessionId等敏感信息因為個人隱私被去掉了).
PHP應用
[
'class' => 'yii\log\FileTarget',
'prefix' => function ($message) {
$user = Yii::$app->has('user', true) ? Yii::$app->get('user') : null;
$userID = $user ? $user->getId(false) : '-';
return "[$userID]";
}
]
PHP應用除了日志消息的前綴,日志的target還把一些上下文信息附加在了每一批的日志記錄中.默認情況下,全局的PHP變量包括$_GET, $_POST, $_FILES, $_COOKIE, $_SESSION 和 $_SERVER. 你可以通過配置 [[yii\log\Target::logVars]] 來調整日志記錄的全局變量.下面的代碼表示的是只記錄$_SERVER相關的變量.
PHP應用
[
'class' => 'yii\log\FileTarget',
'logVars' => ['_SERVER'],
]
PHP應用當 'logVars'為空的時候,表示不記錄相關的上下文信息.如果你想自定義上下文信息的提供方式,你可以覆寫[[yii\log\Target::getContextMessage()]] 辦法.
PHP應用消息的trace等級
在開發的過程當中,我們總是期望能夠知道每一條日志消息是來自哪里.在Yii中你可以通過配置[[yii\log\Dispatcher::traceLevel|traceLevel]] 屬性來實現.配置的示例如下:
PHP應用
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [...],
],
],
];
PHP應用上面的示例在YII_DEBUG為true的時候將[[yii\log\Dispatcher::traceLevel|traceLevel]] 設置為3,反之設置為0. 意思是什么呢?3表現每一條日志記錄都會記錄與之相關的三層棧調用信息,0表現不記錄任何相關的棧調用信息
PHP應用提示:沒有必要總是記錄調用的堆棧信息,比較耗性能.所以,你應該只在你開發的時候或者用于調試的情況下使用該功能.
消息的清空和導出
就如同上面說的,記錄的消息以數組的形式保存在[[yii\log\Logger|logger object]]中.為了限制這個數組消耗過多的內存,當這個數組包括的內容大小達到某個量的時候會被對應的target從內存中轉移到對應的目標(文件,數據庫...)中.你可以通過設置 [[yii\log\Dispatcher::flushInterval|flushInterval]] 的值來決定量的大小.像下面這樣:
PHP應用
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'flushInterval' => 100, // default is 1000
'targets' => [...],
],
],
];
PHP應用注意:在應用運行結束的時候也會刷新內存,這樣辦事為了讓日志的target能夠記錄完整的信息.
把日志信息從內存刷到對應存放的地方的這一動作不是立即發生的.事實上,和上面一樣,都是當內存中的日志大小達到一定程度才會發生.你可以像下面的示例一樣通過配置不同target的[[yii\log\Target::exportInterval|exportInterval]]值,來達到修改的目的:
PHP應用
[
'class' => 'yii\log\FileTarget',
'exportInterval' => 100, // default is 1000
]
PHP應用因為清空和導出的設定,默認情況下你調用 Yii::trace() 或者其他的日志記錄辦法的時候不會在日志target下立馬看到日志消息.這對某些長時間運行的控制臺程序是一個問題.不過這個問題是可以解決的,辦法入下面的代碼,你需要把[[yii\log\Dispatcher::flushInterval|flushInterval]] 和[[yii\log\Target::exportInterval|exportInterval]] 的值都設置成1:
PHP應用
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'flushInterval' => 1,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'exportInterval' => 1,
],
],
],
],
];
PHP應用注意:如此頻繁的清空和導出日志消息會降低系統的性能.
切換日志的targets
你可以通過設置[[yii\log\Target::enabled|enabled]] 屬性來禁止日志的target.就如同下面的代碼描述的一樣:
PHP應用
Yii::$app->log->targets['file']->enabled = false;
PHP應用上面的代碼必要你在配置文件里面有一個下面的配置:
PHP應用
return [
'bootstrap' => ['log'],
'components' => [
'log' => [
'targets' => [
'file' => [
'class' => 'yii\log\FileTarget',
],
'db' => [
'class' => 'yii\log\DbTarget',
],
],
],
],
];
PHP應用創建一個新的target
首先,創建一個新的日志target是很簡單的.你主要做的事情是實現[[yii\log\Target::export()]] 辦法并且把數組類型的消息[[yii\log\Target::messages]]發送到指定的存儲媒介上去就行了.在這個過程中你可以調用[[yii\log\Target::formatMessage()]] 辦法來格式化每一條日志消息.至于更多的細節你可以在Yiid的發行版本里找到詳細的信息.
PHP應用性能評測
性能評測是一種比擬特別的日志記錄.它通常用來獲取某些模塊執行時間的數據,以此來找到性能的問題所在.比如說,[[yii\db\Command]] 這個類就用性能評測日志來獲得每一條sql查詢所花費的時間.
PHP應用要使用該類日志,你首先要做的時確定你要測試的代碼范圍.然后在每一段代碼之間你都應該要堅持它們是閉合的,就像下面這個樣子:
PHP應用
\Yii::beginProfile('myBenchmark');
...code block being profiled...
\Yii::endProfile('myBenchmark');
PHP應用myBenchmark只是一個標識,用于你在查看對應日志記錄的時候快速定位.
在beginProfile和endProfile之間是可以再嵌套的,但是必需保證正確的閉合關系,如下所示:
PHP應用
\Yii::beginProfile('block1');
// some code to be profiled
\Yii::beginProfile('block2');
// some other code to be profiled
\Yii::endProfile('block2');
\Yii::endProfile('block1');
PHP應用如果上面的閉合關系出錯了,對應的記錄都不會正常工作.
PHP應用對于每一塊被評測的代碼,日志的level都是profile.你可以再日志的target中配置這些信息并導出它們. Yii內建了 Yii debugger來展示評測的成果.
歡迎參與《PHP編程:PHP的Yii框架的常用日志操作總結》討論,分享您的想法,維易PHP學院為您提供專業教程。