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