前言
将架构从apache+mod_php迁移到nginx+fpm上,会发现如果php脚本出错,nginx的eror_log里不会有记录,只在access_log里记录了500状态码。出现的原因:nginx将php的脚本执行通过fastcgi转到fpm上,所以出错的信息当然不会记录在nginx的error_log里了,但是对于测试环境下程序员的调试这是个悲剧啊,所以我们需要配置fpm的错误日志
nginx+fastcgi+fpm配置见:
http://blog.csdn.net/zinss26914/article/details/8175385
php5-fpm.conf
php5-fpm的错误日志是在php5-fpm.conf全局配置中进行设置,查看一下php5-fpm.conf日志:
- ;;;;;;;;;;;;;;;;;;
- ; Global Options ;
- ;;;;;;;;;;;;;;;;;;
- [global]
- ; Pid file
- ; Note: the default prefix is /var
- ; Default Value: none
- ;pid = run/php-fpm.pid
- pid = /var/run/php5-fpm.pid
- ; 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 = log/php-fpm.log
- #配置error_log,设置error_log的存放位置
- error_log = /var/log/fpm/php5-fpm.error.log
- ; 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
- #错误级别(生产环境下应该提高错误级别,推荐error)
- log_level = notice
- #表示在emergency_restart_interval所设时间内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过emergency_restart_threshold个,php-fpm就会优雅重启
- emergency_restart_threshold = 60
- emergency_restart_interval = 60s
- ; Time limit for child processes to wait for a reaction on signals from master.
- ; Available units: s(econds), m(inutes), h(ours), or d(ays)
- ; Default Unit: seconds
- ; Default Value: 0
- ;process_control_timeout = 0
- ; The maximum number of processes FPM will fork. This has been design to control
- ; the global number of processes when using dynamic PM within a lot of pools.
- ; Use it with caution.
- ; Note: A value of 0 indicates no limit
- ; Default Value: 0
- ; process.max = 128
- ; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.
- ; Default Value: yes
- #后台执行fpm,设置为yes
- daemonize = yes
pool.d目录下配置文件(例如:www.conf)
(1)保证配置文件中一个参数的开启,参数定义看英文注释很清楚:
- ; Redirect worker stdout and stderr into main error log. If not set, stdout and
- ; stderr will be redirected to /dev/null according to FastCGI specs.
- ; Note: on highloaded environement, this can cause some delay in the page
- ; process time (several ms).
- ; Default Value: no
- catch_workers_output = yes
(2)同时可以开启access_log和slow_log
- <span style="color:#ff0000;">access.log = /var/log/fpm/php5-fpm.access.log</span>
- ; The access log format.
- ; The following syntax is allowed
- ; %%: the '%' character
- ; %C: %CPU used by the request
- ; it can accept the following format:
- ; - %{user}C for user CPU only
- ; - %{system}C for system CPU only
- ; - %{total}C for user + system CPU (default)
- ; %d: time taken to serve the request
- ; it can accept the following format:
- ; - %{seconds}d (default)
- ; - %{miliseconds}d
- ; - %{mili}d
- ; - %{microseconds}d
- ; - %{micro}d
- ; %e: an environment variable (same as $_ENV or $_SERVER)
- ; it must be associated with embraces to specify the name of the env
- ; variable. Some exemples:
- ; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
- ; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
- ; %f: script filename
- ; %l: content-length of the request (for POST request only)
- ; %m: request method
- ; %M: peak of memory allocated by PHP
- ; it can accept the following format:
- ; - %{bytes}M (default)
- ; - %{kilobytes}M
- ; - %{kilo}M
- ; - %{megabytes}M
- ; - %{mega}M
- ; %n: pool name
- ; %o: ouput header
- ; it must be associated with embraces to specify the name of the header:
- ; - %{Content-Type}o
- ; - %{X-Powered-By}o
- ; - %{Transfert-Encoding}o
- ; - ....
- ; %p: PID of the child that serviced the request
- ; %P: PID of the parent of the child that serviced the request
- ; %q: the query string
- ; %Q: the '?' character if query string exists
- ; %r: the request URI (without the query string, see %q and %Q)
- ; %R: remote IP address
- ; %s: status (response code)
- ; %t: server time the request was received
- ; it can accept a strftime(3) format:
- ; %d/%b/%Y:%H:%M:%S %z (default)
- ; %T: time the log has been written (the request has finished)
- ; it can accept a strftime(3) format:
- ; %d/%b/%Y:%H:%M:%S %z (default)
- ; %u: remote user
- ;
- ; Default: "%R - %u %t \"%m %r\" %s"
- ;access.format = %R - %u %t "%m %r%Q%q" %s %f %{mili}d %{kilo}M %C%%
- ; The log file for slow requests
- ; Default Value: not set
- ; Note: slowlog is mandatory if request_slowlog_timeout is set
- slowlog = /var/log/fpm/php5-fpm.log.slow
- ; The timeout for serving a single request after which a PHP backtrace will be
- ; dumped to the 'slowlog' file. A value of '0s' means 'off'.
- ; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
- ; Default Value: 0
- request_slowlog_timeout = 3
fpm日志按天分割脚本
- #!/bin/bash -
- #1.fpm日志存放路径
- php5_fpm_path="/var/log/php5-fpm"
- path_array=($php5_fpm_path)
- #2.日志标识前缀数组
- icontact_fpm_sign="test"
- test_fpm_sign="php5-fpm"
- prefix_array=($icontact_fpm_sign $test_fpm_sign)
- #3.日志success or slow 标识后缀数组
- bool_array=("access" "slow" "error")
- #4.nginx日志切割备份后缀
- postfix=`date +%Y%m%d`".log"
- #5.备份当前的日志文件,重命名改为日期后缀
- for path in ${path_array[*]}
- do
- for prefix in ${prefix_array[*]}
- do
- for bool in ${bool_array[*]}
- do
- file=$path/$prefix.$bool.log
- backfile=$path/$prefix.$bool.$postfix
- if [ -e $file ]
- then
- mv $file $backfile
- fi
- done
- done
- done
- #6.查找nginx进程号,让其产生新的日志文件
- fpm_pid=`ps -aux |grep -E 'php-fpm: master process'|grep -v 'grep'|awk '{print $2}'`
- #USR1:Reopen log files,刷新nginx日志文件
- kill -USR1 $fpm_pid
经验和bug分享
问题
为了减少线上服务器的错误信息输出,我将php-fpm.conf的Log_level = error,但是这样配置后我在php5-fpm的错误日志里再也看不到错误信息了。
原因定位
可以看一下我将Log_level = notice后的错误日志信息截图:
可以发现fpm将php的不管是warning或者是error的错误全部定位成了notice级别,所以线上想看fpm的错误日志只能将错误级别定位成notice了