nginx.conf、php-fpm.conf和php.ini三者之中的error_log指令之間的區別和聯繫

error_log這個指令在nginx的配置文件nginx.conf、php-fpm的配置文件php-fpm.conf以及php.ini三者中都存在,本文試圖簡要說明下這三個配置之間的區別和聯繫。

php.ini

error_log string

設置腳本錯誤將被記錄到的文件。該文件必須是web服務器用戶可寫的。如果特殊值 syslog 被設置,則將錯誤信息發送到系統日誌記錄器。在Unix以及類似系統上,使用的是 syslog(3) ,而在 Windows NT 類系統上則爲事件日誌。Windows 95上不支持系統日誌記錄。參見: syslog(). 如果該配置沒有設置,則錯誤信息會被髮送到 SAPI 錯誤記錄器。例如,出現在Apache的錯誤日誌中,或者在CLI中發送到 stderr

 php-fpm.conf

error_log string

錯誤日誌的位置。默認:#INSTALL_PREFIX#/log/php-fpm.log。 如果設置爲 "syslog",日誌將不會寫入本地文件,而是發送到 syslogd。

nginx.conf

Syntax: error_log file [level];
Default:
error_log logs/error.log error;
Context: mainhttpmailstreamserverlocation

Configures logging. Several logs can be specified on the same level (1.5.2). If on the main configuration level writing a log to a file is not explicitly defined, the default file will be used.

The first parameter defines a file that will store the log. The special value stderr selects the standard error file. Logging to syslog can be configured by specifying the “syslog:” prefix. Logging to a cyclic memory buffer can be configured by specifying the “memory:” prefix and buffer size, and is generally used for debugging (1.7.11).

The second parameter determines the level of logging, and can be one of the following: debuginfonoticewarnerrorcritalert, or emerg. Log levels above are listed in the order of increasing severity. Setting a certain log level will cause all messages of the specified and more severe log levels to be logged. For example, the default level error will cause errorcritalert, and emerg messages to be logged. If this parameter is omitted then error is used.

從上面的文檔初步可以看出 php.ini 中 error_log 優先級較高,下面依次實驗這些配置的組合,讓我們來看看它們的優先級,

測試報錯使用以下簡單的php代碼:

<?php
throw new Exception('foobar');

其中各個error_log的配置值如下:

nginx:error_log  /var/log/nginx/error.log;

php-fpm:error_log = /var/log/php-fpm/error.log

php.ini:error_log = /var/log/php/error.log

1、當三個值同時配置時,php的錯誤日誌會寫入php.ini中error_log指定的文件

[21-Apr-2019 22:19:13 Asia/Shanghai] PHP Fatal error:  Uncaught Exception: foobar in /usr/share/nginx/html/error.php:5
Stack trace:
#0 {main}
  thrown in /usr/share/nginx/html/error.php on line 5

但如果這個error_log指定的文件沒有可寫權限時會怎樣呢,會不會記錄到nginx或者php-fpm的error_log文件中呢?答案是否定的,此時報錯信息會因爲無法寫入而丟失。

2、不配置php.ini 中的error_log,同時配置 nginx.conf 和php-fpm.conf 中的error_log,此時錯誤日誌會寫入到nginx的error_log文件中

2019/04/21 22:33:04 [error] 2031#0: *102 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Exception: foobar in /usr/share/nginx/html/error.php:5
Stack trace:
#0 {main}
  thrown in /usr/share/nginx/html/error.php on line 5" while reading response header from upstream, client: 127.0.0.1, server: _, request: "GET /error.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "127.0.0.1"
 

3、由於nginx的error_log不支持關閉,所以無法比較 nginx.conf 和 php-fpm.conf 中 error_log 的優先級,實際上 php-fpm.conf 中的error_log並不用來記錄php的報錯信息,而用來記錄php-fpm進程本身的一些運行時信息。

4、雖然php-fpm.conf 中的error_log 不會記錄php的報錯信息,但是在php-fpm.conf 中可以用  php_value/php_flag 或 php_admin_value/php_admin_flag 配置來覆蓋php.ini中的配置:

還可以在爲一個運行池傳遞附加的環境變量,或者更新 PHP 的配置值。可以在進程池配置文件中如下面的配置參數來做到:

Example #1 給運行池傳遞環境變量和設置 PHP 的配置值

env[HOSTNAME] = $HOSTNAME
       env[PATH] = /usr/local/bin:/usr/bin:/bin
       env[TMP] = /tmp
       env[TMPDIR] = /tmp
       env[TEMP] = /tmp

       php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f [email protected]
       php_flag[display_errors] = off
       php_admin_value[error_log] = /var/log/fpm-php.www.log
       php_admin_flag[log_errors] = on
       php_admin_value[memory_limit] = 32M
PHP配置值通過 php_value 或者 php_flag 設置,並且會覆蓋以前的值。請注意 disable_functions 或者disable_classes 在 php.ini 之中定義的值不會被覆蓋掉,但是會將新的設置附加在原有值的後面。

使用 php_admin_value 或者 php_admin_flag 定義的值,不能被 PHP 代碼中的 ini_set() 覆蓋。

例如,在php-fpm.conf 中配置  php_admin_value[error_log] = /var/log/php-fpm/www-error.log , 同時配置php.ini 中的error_log,會發現php報錯信息會寫入 /var/log/php-fpm/www-error.log文件中

總結:

error_log優先級:php-fpm.conf 中的 php_value[error_log] / php_admin_value[error_log]

                                大於 php.ini 中的 error_log

                                大於 nginx.conf 中的 error_log

而 php-fpm.conf 中的error_log 跟記錄php運行時報錯信息無關。

而最簡單的獲取php的錯誤日誌記錄的地方就是查看phpinfo() 信息,看其中的error_log 的值,如果有值,則錯誤日誌就是記錄在這個值指定的地方,沒有則記錄在nginx的error_log中。

有的框架使用set_exception_handler 和 set_error_handler 以及 register_shutdown_function重新設置了異常處理和報錯處理,可能把錯誤日誌寫到另外一個地方,所以在開發環境下還是臨時打開 display_errors 吧,這是最快速的定位錯誤的方法。

That's all

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章