Yi 採分層日誌架構:CLogger 收集暫存記憶體,CLogRouter 於請求結束分發至多個處理器 (CFileLogRoute、CEmailLogRoute 等)。本文涵蓋頁面級日誌、Yii2 元件擴充、核心邏輯流程、多路由配置與自訂郵件日誌實戰。
'log' => array(
'class' => 'CLogRouter',
'routes' => array(
array(
'class' => 'CFileLogRoute',
'levels' => 'error, warning',
),
array(
'class' => 'CWebLogRoute',
'levels' => 'trace',
'categories' => 'system.db.*',
),
),
),
namespace common\components;
use Yii;
use yii\helpers\FileHelper;
class FileTarget extends \yii\log\FileTarget {
public $enableDatePrefix = false;
public $enableCategoryDir = false;
private $_logFilePath = '';
public function init() {
if ($this->logFile === null) {
$this->logFile = Yii::$app->getRuntimePath() . '/logs/app.log';
} else {
$this->logFile = Yii::getAlias($this->logFile);
}
$this->_logFilePath = dirname($this->logFile);
if ($this->enableDatePrefix) {
$filename = basename($this->logFile);
$this->logFile = $this->_logFilePath . '/' . date('Ymd') . '_' . $filename;
}
if (!is_dir($this->_logFilePath)) {
FileHelper::createDirectory($this->_logFilePath, $this->dirMode, true);
}
if ($this->maxLogFiles < 1) $this->maxLogFiles = 1;
if ($this->maxFileSize < 1) $this->maxFileSize = 1;
}
}
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
['class' => 'common\components\FileTarget', 'levels' => ['error'], 'logVars' => ['_GET','_POST','_FILES','_COOKIE','_SESSION','_SERVER'], 'logFile' => '@app/runtime/logs/error/app.log', 'enableDatePrefix' => true, 'maxFileSize' => 1024, 'maxLogFiles' => 100],
['class' => 'common\components\FileTarget', 'levels' => ['warning'], 'logVars' => ['_GET','_POST','_FILES','_COOKIE','_SESSION','_SERVER'], 'logFile' => '@app/runtime/logs/warning/app.log', 'enableDatePrefix' => true, 'maxFileSize' => 1024, 'maxLogFiles' => 100],
['class' => 'common\components\FileTarget', 'levels' => ['info'], 'logVars' => ['_GET','_POST','_FILES','_COOKIE','_SESSION','_SERVER'], 'logFile' => '@app/runtime/logs/info/app.log', 'enableDatePrefix' => true, 'maxFileSize' => 1024, 'maxLogFiles' => 100],
['class' => 'common\components\FileTarget', 'levels' => ['trace'], 'logVars' => ['_GET','_POST','_FILES','_COOKIE','_SESSION','_SERVER'], 'logFile' => '@app/runtime/logs/trace/app.log', 'enableDatePrefix' => true, 'maxFileSize' => 1024, 'maxLogFiles' => 100],
],
],
Yii::log($message, CLogger::LEVEL_ERROR, $category);
CLogger 實例YII_DEBUG 且非 profile 等級 → 產生回溯資訊附加CLogger::log() 暫存記憶體CLogRouter::init() 綁定兩事件:
Yii::getLogger()->onFlush → collectLogs() (記憶體超量時刷新)Yii::app()->onEndRequest → processLogs() (請求結束處理)CApplication::run() 結束呼叫 onEndRequest 觸發寫入。
CLogRouter::processLogs() 遍歷路由collectLogs($levels, $categories) 從 Logger 取得並過濾processLogs($logs) 實際寫入 (檔案、資料庫、郵件等)CFileLogRoute 內建日誌輪轉 (LogRotate) 功能。
class myEmailLogRoute extends CEmailLogRoute {
// 重寫 sendEmail() 使用 SMTP 驗證發送
}
'log' => array(
'class' => 'CLogRouter',
'routes' => array(
array('class' => 'CFileLogRoute', 'levels' => 'error, warning, trace'),
array(
'class' => 'myEmailLogRoute',
'levels' => 'error',
'categories' => 'exception.CDbException',
'host' => 'mail.163.com',
'port' => 25,
'user' => 'jeff_yu',
'password' => 'your_password',
'timeout' => 30,
'emails' => 'jeff_yu@gmail.com',
'sentFrom' => 'jeff_yu@gmail.com',
),
),
),
同一份日誌可同時寫檔、發郵件、存資料庫,極具彈性。