php 错误日志级别,关于php错误日志

现代的php开发,通常的习惯是将错误信息对用户隐藏,一来提高体验,二来隐藏系统内部细节。

但是错误日志需要保留,便于开发人员解决BUG。

现在web端最常用的组合是nginx+php-fpm,php以fastcgi方式运行,此时php会有两个配置文件:php.ini 和 php-fpm.conf,两个配置文件各自负责不同的设置,这里只重点说一下日志相关的配置,以下内容基于 php7.3.6。

错误日志

php.ini 中与日志有关的配置项有:

# 是否将错误信息作为输出的一部分显示到屏幕,出于前面提到的习惯,这个配置项应该设置为 Off

display_errors = Off

# 是否将脚本运行的错误信息记录到服务器错误日志或者error_log之中,出于前面提到的习惯,这个配置项应该设置为 On

log_errors = On

# 设置 log_errors 的最大字节数

log_errors_max_len = 1024

# 不记录重复的信息,设置为 Off,即重复的信息也要记录下来

ignore_repeated_errors = Off

# 忽略重复消息时,也忽略消息的来源,同上,这里也设置为 Off,这样,所有的错误消息都会被记录

ignore_repeated_source = Off

# 如果开启,最后的一个错误将永远存在于变量 $php_errormsg 中。从 PHP 7.2.0 起 $php_errormsg 已被废弃,track_errors 设置为 Off 即可

track_errors = Off

# 设置脚本错误将被记录到的文件

error_log = /var/log/php/error_log

# 设置错误报告的级别,E_ALL&~E_NOTICE 的意思是记录除 E_NOTICE 之外的所有错误信息

error_reporting = E_ALL&~E_NOTICE

如果按照上述配置,达到的效果是,页面上不会显示错误信息,除 E_NOTICE 之外的所有错误信息都会被记录到文件 /var/log/php/error_log 中,这是一个可以用在生产环境上的配置,也比较严格,由于php可以通过 ini_set() 函数在运行时动态调整配置,因此php.ini中最好直接做成生产可用的,其它环境下的个别需求可以通过ini_set来调整,比如开发环境下,error_reporting最好是设置为 E_ALL,这样便于在开发阶段找出程序中的隐患并解决,而在生产环境关闭 E_NOTICE 的用意是为了更好的突出比较严重的错误,使之不会淹没在大量notice中。

php-fpm.conf 中于日志有关的配置项有:

[global]

; 设置脚本错误将被记录到的文件

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

; 错误级别。可用级别为:alert(必须立即处理),error(错误情况),warning(警告情况),notice(一般重要信息),debug(调试信息)。默认:notice

log_level = notice

; 错误长度

log_limit = 8192

[www]

; 设置access log的位置,通常不用设置,/proc/self/fd/2 这个值是php的官方docker容器中的配置,目的是为了通过 docker log 命令可以看到容器的访问记录

access.log = /proc/self/fd/2

; 设置 是否将 stdout 和 stderr 输出到 error log,如果不设置,信息会被输出到 /dev/null ,因此这里应设置为 yes

catch_workers_output = yes

; 是否修饰输出,默认为 yes

decorate_workers_output = yes

需要注意的是,php.ini 的优先级高于 php-fpm.conf,如果 php.ini 中设置了 error_log ,那么 php-fpm.conf 的设置将会失效,通常来说,对错误日志的配置比较适合放在 php.ini 中

慢日志

php-fpm.conf 中可以设置是否开启慢日志,这个非常有用,原则上,来自web的访问都应该很快结束,哪怕是出错了,如果有进程被长时间占用,那么很有可能会导致php-fpm子进程池被消耗光,从而导致新的访问无法被执行,nginx就会报504错误,所以记录下慢日志,可以方便查找错误,开启方法很简单,增加两行配置:

[www]

; 设置记录慢日志的超时时间

request_slowlog_timeout = 5s

; 设置日志文件位置

slowlog = /var/log/php/slow_log

需要注意的是,在Linux系统中,php-fpm使用 SYS_PTRACE 跟踪 worker 进程,但是docker容器默认是不启用这个功能的,因此,当php运行在docker容器中时,慢日志无法被记录到文件中,可以这样解决,如果是用命令行启动的容器,在命令上加上:

--cap-add=SYS_PTRACE

如果用了compose,在docker-compose.yaml文件中加上:

php:

#...

cap_add:

- SYS_PTRACE

#...

重启容器即可。

错误/异常捕获

摘录php官方文档中的一段话:

PHP 7 改变了大多数错误的报告方式。不同于传统(PHP 5)的错误报告机制,现在大多数错误被作为 Error 异常抛出。

这种 Error 异常可以像 Exception 异常一样被第一个匹配的 try / catch 块所捕获。如果没有匹配的 catch 块,则调用异常处理函数(事先通过 set_exception_handler() 注册)进行处理。 如果尚未注册异常处理函数,则按照传统方式处理:被报告为一个致命错误(Fatal Error)。

当选择不在页面上显示错误,并将错误全部写入日志文件时,想要跟踪或者发现系统运行中的问题,都要依赖日志文件,这种方式并不方便。

现代的web框架基本都提供捕获错误/异常的功能,这样一来,开发人员就可以比较自由的来选择如何处理这些错误,比如是否显示在页面上,是否写入日志文件,也便于对代码做更严格的校验,比如遇到任何级别的错误都让服务器报500,降低代码隐患。

php7里面有三个函数可以用来辅助这件事:

set_exception_handler

设置默认的异常处理程序,用于没有用 try/catch 块来捕获的异常。

set_error_handler

设置用户的函数 (error_handler) 来处理脚本中出现的错误。

register_shutdown_function

注册一个 callback ,它会在脚本执行完成或者 exit() 后被调用。

通过这三个函数的组合运用,基本可以把程序运行时所产生的大部分错误捕获到。

每一个web框架,对于捕获到的错误都有其默认的处理规则,具体的可以去各家源代码中一探究竟。

你可能感兴趣的:(php,错误日志级别)