我正在尝试找出我的设置中 PHP 错误出在哪里。我正在运行 nginx 作为 PHP-FPM 的反向代理,但我没有看到各种电子通知或者电子警告我的应用程序正在生成的消息。我知道它们发生的唯一原因是响应失败并且 NewRelic 捕获堆栈跟踪。
这是日志配置:
nginx.conf
proxy_intercept_errors on;
fastcgi_intercept_errors on;
php.ini
error_reporting = E_ALL
display_errors = Off
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = On
error_log = syslog
php-fpm.conf
[global]
error_log = /var/log/php-fpm/fpm-error.log
[www]
access.log = /var/log/php-fpm/access.log
access.format = "%t \"%m %r%Q%q\" %s %{mili}dms %{kilo}Mkb %C%%"
catch_workers_output = yes
php_flag[display_errors] = on
php_admin_flag[log_errors] = true
rsyslog.conf
:syslogtag, contains, "php" /var/log/php-fpm/error.log
我已经将 PHP 配置为记录到 syslog,但是 FPM 没有 syslog 功能,因此它记录到文件中。我并不真正关心错误最终会出现在哪里,只要它们最终出现在某个地方即可。
关于如何让它工作,有什么线索吗?
答案1
您的 php-fpm.conf 文件未设置为将错误发送到 syslog。请参阅下面的示例了解如何执行此操作。
; Error log file
; If it's set to "syslog", log is sent to syslogd instead of being written
; in a local file.
; Note: the default prefix is /var
; Default Value: log/php-fpm.log
error_log = syslog
; syslog_facility is used to specify what type of program is logging the
; message. This lets syslogd specify that messages from different facilities
; will be handled differently.
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
; Default Value: daemon
;syslog.facility = daemon
; syslog_ident is prepended to every message. If you have multiple FPM
; instances running on the same server, you can change the default value
; which must suit common needs.
; Default Value: php-fpm
;syslog.ident = php-fpm
; Log level
; Possible Values: alert, error, warning, notice, debug
; Default Value: notice
;log_level = notice
答案2
您确定您对 rsyslog.conf 的假设正确吗?也就是说,您确定所有此类 syslog 消息都标有小写的“php”吗?
尝试将 syslog.facility 设置为类似 local2(或 local1 或 local7)的值,并相应地替换 rsyslog.conf 配置行:
local2.* /var/log/php-fpm/error.log
答案3
当您使用 php-fpm 时,它似乎会覆盖php.ini
设置。
日志记录最有可能需要在其中进行配置.../www.conf
。
我取消了这些行的注释以获取 PHP 日志。
php_admin_value[error_log] = /var/log/php-errors.log
php_admin_flag[log_errors] = on
也可以在此文件中找到与此类似的 Web 服务器用户和组(unix 套接字和代理配置之间可能有所不同)。
listen.owner = www-data
listen.group = www-data
接下来只需创建文件并正确配置它即可。
touch /var/log/php-errors.log
chmod 644 /var/log/php-errors.log
chgrp www-data /var/log/php-errors.log
chown www-data /var/log/php-errors.log
我相信日志级别仍在使用,php-fpm.conf
因此您可能还需要检查这一点。
log_level = error
答案4
要在 nginx 错误日志中获取 php-fpm 错误,您需要:
至于 nginx:只需基本配置就足够了
# cat default | grep -v "#"
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
}
对于 php-fpm,主要设置是
log_errors = On
基本上就足够了。但是为了安全起见,我建议在 php-fpm 配置(/etc/php/7.0/fpm/php.ini)中放入以下块:
[PHP]
...
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = On
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
html_errors = On
...
之后所有 php 堆栈跟踪都将在
# tail /var/log/nginx/error.log
2023/06/20 23:37:06 [error] 20307#20307: *1 FastCGI sent in stderr: "PHP message: PHP Parse error: syntax error, unexpected '"asd"' (T_CONSTANT_ENCAPSED_STRING) in /var/www/html/php1.php on line 2" while reading response header from upstream, client: 127.0.0.1, server: _, request: "GET /php1.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.0-fpm.sock:", host: "localhost"
2023/06/20 23:48:40 [error] 20307#20307: *5 FastCGI sent in stderr: "PHP message: PHP Parse error: syntax error, unexpected '"asd"' (T_CONSTANT_ENCAPSED_STRING) in /var/www/html/php1.php on line 2" while reading response header from upstream, client: 127.0.0.1, server: _, request: "GET /php1.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.0-fpm.sock:", host: "localhost"
2023/06/21 00:18:17 [error] 20307#20307: *7 FastCGI sent in stderr: "PHP message: PHP Parse error: syntax error, unexpected '"asd"' (T_CONSTANT_ENCAPSED_STRING) in /var/www/html/php1.php on line 2" while reading response header from upstream, client: 127.0.0.1, server: _, request: "GET /php1.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.0-fpm.sock:", host: "localhost:4545"
如果你不想在 nginx erorr 文件中查看 php 堆栈跟踪,而是想在单独的文件中查看,则需要添加 错误日志设置
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = On
log_errors = On
error_log = /var/log/php-errors.log
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
html_errors = On
还很重要手动创建 /var/log/php-errors.log 并设置适当的权限,因为 php-fpm 不会这样做,并且会继续将错误传输到 nginx。所以
# touch /var/log/php-errors.log
# chown www-data.www-data /var/log/php-errors.log
# systemctl restart php7.0-fpm
此后,nginx 错误日志 /var/log/nginx/error.log 将为空,但所有 php 错误都将在 /var/log/php-errors.log 中