記錄日誌資訊

你可透過使用 log_message() 方法將訊息記錄到本地日誌檔案中。你必須在第一個參數中提供錯誤的「級別」,定義這是個怎麼樣的錯誤訊息( debug 或 error )。第二個參數則是錯誤訊息本體:

if ($some_var === '') {
    log_message('error', 'Some variable did not contain a value.');
}

共有 8 個不同的日誌級別,源自 RFC 5424 中提到的級別,具體說明如下:

等級 說明
debug 詳細的除錯資訊。
info 在你的應用程式中發生的重大事件,例如:使用者登入或記錄 SQL 查詢等。
notice 你的應用程式執行正常但必須記錄的重要事件。
warning 發生了不屬於錯誤的異常情形,比如說:使用了被淘汰的 API 、不當地使用 API ,或其他不一定是錯誤地不良情況。
error 不需要立即採取行動,但應該要被記錄和監測的執行期間錯誤。
critical 關鍵情況,如應用程式元件無法使用,或是出現意外異常。
alert 必須立即採取行動,比如整個網站癱瘓,或是資料庫無法使用等等。
emergency 系統無法使用。

日誌記錄系統不提供系統管理員或網站管理員注意這些事件的方法,它只記錄訊息。對於更關鍵的事件級別,日誌記錄將由錯誤處理程序自動觸發,如上所述。

組態設定

你可以在 /app/Config/Logger.php 設定檔案中修改實際記錄的級別,也可以指定不同的日誌記錄器來處理不同的級別。

設定檔案的 threshold (閥值)決定了整個應用程式該記錄那些級別。如果應用程式請求記錄某個級別,但並不符合閥值,那它將會被忽略。最簡單的方式是將這個數值設定會你需要記錄的最小級別。例如:如果你想記錄 warning 訊息,而不是 information 訊息,你可以將閥值設定為 5 。任何級別為 5 或更低的日誌記錄請求(包括執行時錯誤、系統錯誤等)都會被記錄下來,而 info 、 notices 與 debug 將會被忽略。

public $threshold = 5;

完整級別與其對應的閥值列表將在設定文件中供你參考。

你可以透過賦予閥值一個陣列,並宣告多個日誌級別號碼來選擇你所希望記錄的特定級別:

// Log only debug and info type messages
public $threshold = [5, 8];

使用多個日誌處理程序

記錄日誌系統支援多種日誌記錄處理程序同時執行的方法。可以將每個處理程序設定為特定的級別,從而忽略其他處理程序,預設安裝的處理程序有兩種:

  • 檔案處理程序 是預設的處理程序,將會每天在本地建立一個檔案。這是推薦的記錄方法。
  • ChromeLogger 處理程序 如果你在 Chrome Web 瀏覽器中安裝了 ChromeLogger extension 擴充模組,你可以使用這個處理程序在 Chrome 主控台中顯示日誌訊息。
  • Errorlog Handler This handler will take advantage of PHP’s native error_log() function and write the logs there. Currently, only the 0 and 4 message types of error_log() are supported.

處理程序是在核心設定檔案中的 $handlers 屬性設定的,它只是一個處理程序的陣列與其設定內容。每個處理程序將可以在這個陣列中被指定,「鍵」為以命名空間所構成的類別名稱,「值」將是一個針對每個處理程序的不同屬性的陣列。每個處理程序都會一個供通屬性: handles ,這是處理程序將記錄訊息的日誌級別的陣列。

    public $handlers = [
    // File Handler
    'CodeIgniter\Log\Handlers\FileHandler' => [
        'handles' => ['critical', 'alert', 'emergency', 'debug', 'error', 'info', 'notice', 'warning'],
    ]
];

依據語境修改訊息

你可能經常會想根據語境來修改被記錄事件的訊息細節。它們可能是使用者 ID 、 IP 位置,或是目前的 POST 變數等等。你可以利用在訊息中的置換符號來實現。每個置換符號必須使用大括弧包裹起來。在第三個參數中,你必須提供一個鍵值為置換符號名稱的陣列(沒有括號)和他們的值。這些內容將被替換至到訊息字串中:

// Generates a message like: User 123 logged into the system from 127.0.0.1
$info = [
    'id' => $user->id,
    'ip_address' => $this->request->ip_address()
];

log_message('info', 'User {id} logged into the system from {ip_address}', $info);

如果你想記錄一個異常或是錯誤,你可以在陣列中宣告一個鍵為「 exception 」值為錯誤本身的成員。這個設定將會從物件中產生一個包含錯誤資訊、檔案名稱和行數的字串。當然,在訊息字串中,你也得提供名為「 exception 」的置換符號:

try {
        // Something throws error here
} catch (\Exception $e) {
        log_message('error', '[ERROR] {exception}', ['exception' => $e]);
}

有幾個核心置換符號會根據目前的頁面請求自動為你擴充:

置換符號 替換值
{post_vars} $_POST 變數
{get_vars} $_GET 變數
{session_vars} $_SESSION 變數
{env} 目前的環境名稱,例如:development
{file} 呼叫日誌記錄器的檔案名稱
{line} 在 {file} 中呼叫日誌記錄器的那一行
{env:foo} $_ENV 中的 foo 的值

使用第三方日誌記錄器

只要你中意的日誌記錄器繼承至 Psr\Log\LoggerInterface 並且相容於 PSR3 規範,你就可以任意地使用它。這意味著,你可以容易地使用 PSR3 相容的日誌記錄器,或者是創建你自己的日誌記錄器。

將第三方記錄器添加到 /app/Config/Autoload.php 這個組態設定文件,或者是透過像是 Composer 的自動加載器,好讓系統可以找到你的第三方日誌記錄器。接下來,你應該要去修改 /app/Config/Services.php ,將日誌記錄器的別名指向你的新類別名稱。

現在,任何透過 log_message() 函數進行的呼叫都將使用你的程式庫。