PHP 錯誤與異常的日誌記錄

提到 Nginx + PHP 服務的錯誤日誌,咱們一般能想到的有 Nginx 的 access 日誌、error 日誌以及 PHP 的 error 日誌。雖然看起來是個很簡單的問題,但裏面其實又牽扯到應用配置以及日誌記錄位置的問題,若是是在 ubuntu 等系統下使用 apt-get 的方式來安裝,其自有一套較爲合理的的配置文件可用。再者運行的應用程序中的配置也會影響到日誌記錄的方式及內容。php

錯誤與異常的區別

關於錯誤與異常,咱們能夠用一個簡單的例子來理解:nginx

<?php try { 1 / 0; } catch (Exception $e) { echo "catched", PHP_EOL; } 

執行這個小示例會直接獲得一個『PHP Warning: Division by zero …』錯誤。緣由很簡單:這是邏輯錯誤,並非異常,因此不能被 try 捕獲。一樣,對於變量使用前未定義這種問題,也是一樣的會產生 warning 而不是被捕獲。git

可是這個問題在 PHP7 中卻有了一些改動,好比上面的例子中我把 / 改爲 %,在 PHP7 的環境中執行會獲得一個不同的提示:github

PHP Fatal error: Uncaught DivisionByZeroError …數據庫

根據這個提示,若是我把 catch 中的條件修改一下:ubuntu

<?php try { 1 / 0; } catch (DivisionByZeroError $e) { echo "catched", PHP_EOL; } 

這樣就能夠正常捕獲到錯誤並輸出 catched 了。框架

對於第一個示例,一樣若是把 Excepiton 修改成 ErrorException 也能夠正常捕獲。函數

至於爲何求餘和除法,在 PHP5 中提示一致而在 PHP7(個人測試環境是 7.0.4) 中除法不屬於 DivisionByZeroError 的問題,這應該是個 BUGphp-fpm

日誌的記錄

PHP 自己可配置的 log 大概有如下幾個:測試

  • php-fpm error log(php-fpm.conf 中配置,記錄 php-fpm 進程的啓動和終止等信息)
  • php-fpm slow log(也是在 php-fpm.conf 中配置,記錄慢執行)
  • php error log(php.ini 中配置,記錄應用程序的錯誤日誌)

此外 Nginx 還有兩個可配置的log:access 和 error log。這幾個日誌文件的功能不一樣,記錄的內容也不一樣。但其中有一個點須要注意:若是配置了 php-fpm 中的 error log 位置,但日誌位置不可寫(配置時位置得是對的,由於 php-fpm 啓動時會作檢查),在適當的配置條件下錯誤日誌會被返回到 cgi 中從而寫入 nginx 的 error log 中。

因此遇到問題是咱們通常的查找思路都是:

  1. 到 Nginx access log 中查看請求的狀態碼
  2. 查看 php error log 中的錯誤記錄以及 stack 信息
  3. 查看 php-fpm log 中有無異常重啓記錄(若是核心或者擴展問題,會出現此狀況)

可是在以上幾種狀況下你也會發現,這裏面並無上文提到的程序拋出異常的日誌記錄。

異常記錄

異常不一樣於錯誤,嚴格上說它是應用程序邏輯的異常而不是錯誤,是能夠經過合理的程序邏輯來手動觸發的。但大多狀況下異常也是要進行記錄的,好比數據庫沒法鏈接或者框架的不當使用觸發的異常,咱們須要經過日誌來定位問題並及時處理。

PHP 提供了兩個函數用於自定義處理錯誤和異常的方法:

  • set_error_handler
  • set_exception_handler

因此能夠經過 set_exception_handler 函數注入方法捕獲全部的異常並記錄 。

monolog 是一個優秀的異常記錄的庫,也是基於 PSR-3 標準的實現。Laravel、Symfony 中默認也是使用它來記錄異常。若有須要,也能夠考慮在本身的項目中引入。

相關文章
相關標籤/搜索