【Yii系列】錯誤處理和日志系統


緣起

跟隨上一章的腳步,上一章中,我們主要講解了在用戶發起請求,解析請求,服務器反饋請求以及session的一些知識點,這過程中,難免會遇到一些問題,比方說數據庫查詢失敗,用戶輸入導致腳本出錯,網絡問題等等突發情況,對於突發情況,做過軟件的一般都知道,會有錯誤處理和日志去記錄下這個過程,同樣的,Yii也提供了類似的功能幫助我們去抓住錯誤,記錄錯誤,並且對相應錯誤做出對應處理。

錯誤處理

Yii 內置了一個error handler錯誤處理器。

所有非致命PHP錯誤(如,警告,提示)會轉換成可獲取異常。

拋出異常

use yii\web\NotFoundHttpException;

throw new NotFoundHttpException();

對於可能產生異常的地方,我們要使用try...catch...

use Yii;
use yii\base\ErrorException;

try {
    10/0;
} catch (ErrorException $e) {
    Yii::warning("Division by zero.");
}

error handler 錯誤處理器默認啟用。

return [
    'components' => [
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
    ]
];

一般的保留原先應用主體中的配置即可,如果想要定制化錯誤的格式輸出,可以去官網好好研究研究呢,這里不細究,錯誤產生,打印出來即可,至於如何記錄下來,方便我們查找,這才是重要的。

日志系統

提起日志系統,大伙可能第一個想到的就是在適當的位置插入一行代碼,然后執行到這行代碼之后就會被記錄一些東西到一個文件中。

是的,這就是最原始的日志系統,之前搞的Python自動發郵件的那個日志記錄系統就是這么簡單的一個玩意兒,但是收到的成效會非常好。就和程序員寫注釋一樣,在對的位置加上log,這會大大降低你系統的維護成本。

Yii提供了一個強大的日志框架,這個框架具有高度的可定制性和可擴展性。

調用起來也相當簡單

Yii::trace():記錄一條消息去跟蹤一段代碼是怎樣運行的。這主要在開發的時候使用。
Yii::info():記錄一條消息來傳達一些有用的信息。
Yii::warning():記錄一個警告消息用來指示一些已經發生的意外。
Yii::error():記錄一個致命的錯誤,這個錯誤應該盡快被檢查。

上面的這幾個日志類型是根據嚴重程度來記錄的

exception需要記錄到warning和error里面

重要的日志信息會單獨記錄到單獨的key中,方便查找,就是這些個方法的第二個參數:category,這個參數是可以自定義的。這和你的配置有關,如下是一個比較標准的配置log的方式。

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',
                    ],
                ],
            ],
        ],
    ],
];

log 組件必須在 bootstrapping 期間就被加載,以便於它能夠及時調度日志消息到目標里。

上面的error和warning會被以存儲到數據表的形式存儲,我一般都會存儲在runtime的log下面,以文件的方式去存儲,過一周時間備份下這些log,然后從服務器刪除掉這些log。

第二個是error的時候要給admin和developer兩個example.com郵箱發送郵件。

Yii配備了以下的內建日志目標。

yii\log\DbTarget:在數據庫表里存儲日志消息。
yii\log\EmailTarget:發送日志消息到預先指定的郵箱地址。
yii\log\FileTarget:保存日志消息到文件中.
yii\log\SyslogTarget:通過調用PHP函數 syslog() 將日志消息保存到系統日志里。

我一般使用的就是那個FileTarget,配置如下:

'log' => [
        'traceLevel' => YII_DEBUG ? 3 : 0,
        'targets' => [
            [
                'class' => 'yii\log\FileTarget',
                'levels' => ['error', 'warning'],
            ],
            [
                'class' => 'yii\log\FileTarget',
                'categories' => ['tongzi.info.*', 'yii\db\*'],
                'levels' => ['info'],
                'logVars' => [],
            ]
        ],

    ]

上面的應用配置設置了 yii\log\Dispatcher::traceLevel 的層級,假如 YII_DEBUG 開啟則是3,否則是0。

這意味着,假如 YII_DEBUG 開啟,每個日志消息在日志消息被記錄的時候, 將被追加最多3個調用堆棧層級;假如 YII_DEBUG 關閉, 那么將沒有調用堆棧信息被包含。

categories 屬性是一個包含消息分類名稱或者模式的數組。

一個分類模式是一個以星號 * 結尾的分類名前綴。假如一個分類名與分類模式具有相同的前綴, 那么該分類名將和分類模式相匹配。

消息的格式

如果你使用了yii\log\FileTarget類的日志目標,你的消息格式應該是下面的~

2014-10-04 18:10:15 [::1][][-][trace][yii\base\Module::getModule] Loading module: debug

默認情況下,日志消息將被格式化,格式化的方式遵循 yii\log\Target::formatMessage():

Timestamp [IP address][User ID][Session ID][Severity Level][Category] Message Text

也可以自定義日志格式,不過完全沒有必要那么搞,這么多的信息足夠查錯啦。

另外,定義好各個category后,你就可以使用各種工具查看log啦。

這邊推薦大家使用兩個日志分析工具,splunk和日志易,splunk,我有個同學在里面,做大數據分析算法,反正我覺得挺牛,Splunk在全球大數據分析首屈一指。而且界面也很友好,只是免費版的只有500M的空間供你使用,這是個巨坑。

還有一個就是日志易啦,也是我目前在用的日志分析工具,國內比較好的工具,大家可以去到他的官網研究搞搞事情,挺不錯的。

好了,今天關於錯誤處理和日志系統相關的就講到這兒^_^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM