前言:
我們日常在調試錯誤信息時,想要知道這個錯誤是來自那個請求的,這種時候如果沒有明顯的關係,就只能靠時間來推測,是很不準確的,如果我們能夠在php-error.log中記錄下nginx的logid,就能夠很快的定位出問題的來源,也就能夠快速找到該條nginx請求。
PHP中無法直接獲取到Nginx的logid,但是可以使用相同的算法從而得到和Nginx中相同的logid,算法如下:
$arr = gettimeofday();
$logid = ((($arr['sec']*100000 + $arr['usec']/10) & 0x7FFFFFFF) | 0x80000000);
這樣就能得到Nginx中的logid。
在PHP中編寫如下函數:
public function addLogIdToErrorLog($error_no, $error_str, error_file, error_line) {
$log_file = "/usr/local/php/php-error.log";//你的php-error.log所在的位置,最好使用絕對路徑
$display_str = "";
switch($error_no) {
case E_ERROR:
$display_str = 'nginx_logid:' . $logid . '這是致命錯誤' . $error_str . PHP_EOL;
break;
case E_WARNING:
$display_str = 'nginx_logid:' . $logid . '這是警告' . $error_str . PHP_EOL;
break;
...
/*
* 如果不想修改默認錯誤,只想要修改用戶級別的錯誤,只需要case出用戶錯誤,再進行修改
*/
}
}
然後在PHP中你需要修改記錄error_log的地方調用以下代碼
$error_handler = set_error_handler("myErrorHandler");//開啓自定義錯誤日誌
最後來一張PHP error_level配置表:
數字 | 常量 | 說明 |
---|---|---|
1 | E_ERROR | 致命錯誤,腳本執行中斷,就是腳本中有不可識別的東西出現 舉例: Error:Invalid parameters. Invalid parameter name |
2 | E_WARNING | 部分代碼出錯,但不影響整體運行 舉例: Warning: require_once(E:/include/config_base.php) |
4 | E_PARSE | 字符、變量或結束的地方寫規範有誤舉例: Parse error: syntax error, unexpected $end in |
8 | E_NOTICE | 一般通知,如變量未定義等舉例: Notice: Undefined variable: p in E:\web\index.php on line 17 |
16 | E_CORE_ERROR | PHP進程在啓動時,發生了致命性錯誤 舉例: 暫無 |
32 | E_CORE_WARNING | 在PHP啓動時警告(非致命性錯誤)舉例: 暫無 |
64 | E_COMPILE_ERROR | 編譯時致命性錯誤舉例: 暫無 |
128 | E_COMPILE_WARNING | 編譯時警告級錯誤舉例: 暫無 |
256 | E_USER_ERROR | 用戶自定義的錯誤消息舉例: 暫無 |
512 | E_USER_WARNING | 用戶自定義的警告消息舉例: 暫無 |
1024 | E_USER_NOTICE | 用戶自定義的提醒消息舉例: 暫無 |
2047 | E_ALL | 以上所有的報錯信息,但不包括E_STRICT的報錯信息舉例: 暫無 |
2048 | E_STRICT | 編碼標準化警告,允許PHP建議如何修改代碼以確保最佳的互操作性向前兼容性。 |
參考資料
淺談php自定義錯誤日誌