首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Yii 2 日誌系統完整配置:FileTarget 與 DbTarget 雙輸出、環境區分、效能優化、Log Rotation 與 ELK 整合

     編輯:PHP 綜合知識

Yii 2 內建強大的日誌組件 (yii\log\Dispatcher),支援多 Target、多級別、過濾器、格式化器。本文示範生產級配置:檔案與資料庫雙輸出、開發/生產環境差異化、關鍵效能參數、日誌輪轉、結構化 JSON 輸出對接 ELK。

基礎配置 (config/web.php)

return [
    'bootstrap' => ['log'], // 關鍵:預載入 log 組件
    'components' => [
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0, // 開發環境記錄堆疊,生產關閉
            'targets' => [
                // 1. 檔案目標 (開發/除錯)
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning', 'info', 'trace'],
                    'categories' => ['application', 'db', 'api'],
                    'logFile' => '@runtime/logs/app.log',
                    'maxFileSize' => 10 * 1024 * 1024, // 10MB 輪轉
                    'maxLogFiles' => 20,               // 保留 20 個檔案
                    'logVars' => ['_GET', '_POST', '_SESSION', '_COOKIE', '_SERVER'], // 記錄請求上下文
                    'exportInterval' => 1,             // 立即寫入 (開發)
                ],
                // 2. 資料庫目標 (生產/審計)
                [
                    'class' => 'yii\log\DbTarget',
                    'levels' => ['error', 'warning'],
                    'categories' => ['security', 'audit', 'payment'],
                    'logTable' => '{{%log}}',
                    'prefix' => function () {
                        return json_encode([
                            'user_id' => Yii::$app->user->id ?? null,
                            'ip' => Yii::$app->request->userIP ?? null,
                            'request_id' => Yii::$app->request->headers->get('X-Request-Id') ?? null,
                        ]);
                    },
                ],
            ],
        ],
    ],
];

環境差異化配置 (config/web.php 合併 params.php)

// config/params.php
return [
    'log' => [
        'file' => [
            'levels' => YII_DEBUG ? ['error', 'warning', 'info', 'trace'] : ['error', 'warning'],
            'exportInterval' => YII_DEBUG ? 1 : 100, // 生產批次寫入
        ],
        'db' => [
            'levels' => YII_DEBUG ? ['error', 'warning', 'trace'] : ['error'],
        ],
    ],
];

// config/web.php
'targets' => [
    [
        'class' => 'yii\log\FileTarget',
        'levels' => $params['log']['file']['levels'],
        'exportInterval' => $params['log']['file']['exportInterval'],
        // ...
    ],
    [
        'class' => 'yii\log\DbTarget',
        'levels' => $params['log']['db']['levels'],
        // ...
    ],
],

建立資料庫日誌表

# 運行 Migration 建立 {{%log}} 表
./yii migrate --migrationPath=@yii/log/migrations/

# 表結構 (MySQL)
CREATE TABLE `log` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `level` INT NOT NULL,
    `category` VARCHAR(255) NOT NULL,
    `log_time` DOUBLE NOT NULL,
    `prefix` TEXT,
    `message` TEXT NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `idx_level_time` (`level`, `log_time`),
    INDEX `idx_category` (`category`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

效能優化關鍵參數

參數開發環境生產環境說明
exportInterval1 (立即)100-1000 (批次)累積多少條訊息才寫入,減少 IO
traceLevel30堆疊深度,生產關閉避免效能損耗
maxFileSize10MB100MB單檔大小觸發輪轉
maxLogFiles2050保留檔案數
logVars['_GET','_POST',...][] 或 ['_SERVER']記錄超全域變數,生產避免敏感資料洩漏

結構化 JSON 輸出 (對接 ELK/Logstash)

// 自定義 JsonFileTarget
namespace app\log;
use yii\log\FileTarget;

class JsonFileTarget extends FileTarget {
    public function formatMessage($message) {
        [$text, $level, $category, $timestamp] = $message;
        $log = [
            '@timestamp' => date('c', $timestamp),
            'level' => $this->getLevelName($level),
            'category' => $category,
            'message' => $text,
            'context' => $this->getContext(),
        ];
        return json_encode($log, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
    }
    private function getContext(): array {
        return [
            'request_id' => Yii::$app->request->headers->get('X-Request-Id') ?? uniqid(),
            'user_id' => Yii::$app->user->id ?? null,
            'ip' => Yii::$app->request->userIP ?? null,
            'url' => Yii::$app->request->absoluteUrl,
            'method' => Yii::$app->request->method,
            'memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2),
        ];
    }
}

// 使用
'targets' => [
    [
        'class' => 'app\log\JsonFileTarget',
        'levels' => ['error', 'warning', 'info'],
        'logFile' => '@runtime/logs/app.json.log',
        'exportInterval' => 10,
    ],
],

Log Rotation 策略

  • Yii 內建:maxFileSize + maxLogFiles 自動輪轉 (app.log.1, app.log.2...)。
  • 系統 logrotate:/etc/logrotate.d/yii-app 管理 /var/www/app/runtime/logs/*.log,支援壓縮、郵件通知、共享腳本重啟 PHP-FPM。
  • Docker 環境:採用 stdout/stderr 輸出,由 Docker logging driver (json-file, syslog, fluentd) 處理輪轉與轉發。

常見業務日誌類別設計

Yii::info('User login', 'auth.login');
Yii::warning('Login failed: wrong password', 'auth.login.failed');
Yii::error('Payment gateway timeout', 'payment.gateway');
Yii::trace('SQL: ' . $sql, 'db.query'); // 只在 traceLevel > 0 時記錄

// 控制器中快速記錄
\Yii::info('Order created', 'order.create');
\Yii::error('Exception: ' . $e->getMessage(), 'order.create');

避坑清單

  1. bootstrap 必須包含 log,否則 CLI/Queue 環境日誌不生效。
  2. DbTarget 使用同一資料庫連線時,大量寫入可能阻塞業務,建議獨立讀寫分離連線或改用檔案 + Logstash 收集。
  3. 生產環境 traceLevel = 0,否則每次記錄都生成堆疊字串,嚴重拖慢效能。
  4. logVars 生產環境務必清空或最小化,防止記錄密碼、Token、信用卡號等敏感資訊。
  5. 資料庫日誌表需建立分區表或定期歸檔,避免單表過大影響查詢。

Yii 2 日誌系統靈活強大,關鍵在於「環境差異化配置、批次寫入優化、結構化輸出、敏感資料過濾、輪轉策略」。將日誌視為可觀測性基礎設施,統一格式、標準欄位、自動收集,才能在故障排查、安全審計、業務分析中發揮最大價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved