Converting Brainstorms to Blogs

Tuesday, November 28, 2006

Logging PHP errors with metalog

On production servers, PHP errors should not be displayed. Just logging errors to a file will be problematic once that file grows big.

Note: This article implies that you are running LAMP, and are using metalog as your system logger.

A huge update was due for my TattooJoy website, which automatically meant things could go wrong. Of course, as recommended in the php.ini file, I do have display_errors set to off. But if something went wrong after the update, how would I know?

PHP allows you to log errors to a file. Setting this up is fairly simple, all you have to do is decide where to save the file, set it's owner and permission correctly, tell PHP about this in the php.ini settings, and restart apache. These settings in php.ini will suffice:

error_reporting = E_ALL log_errors = On log_errors_max_len = 1024 ignore_repeated_errors = On ignore_repeated_source = Off report_memleaks = On track_errors = Off error_log = /var/log/php/errors.log

Most of these are default settings. The last line, error_log, defines the location of your error log file. In order to be able to write to this file, PHP must have permissions to do so. And since PHP is run by the apache web server, you must make sure that the user running apache (usually "apache" or "nobody") has write permissions to the file defined by errors_log file.

Once this is setup, just restart apache and produce an error (that should be easy!) in any PHP script. You will find all your errors logged into /var/log/php/errors.log

PHP's error log file can grow extremely large

Soon enough I found out that over time this file was just growing bigger and bigger. The directive log_errors_max_len made it appear as if PHP would do some kind of rotating once the log file reaches this size--but that was quite wrong.

log_errors_max_len only defines the length per line PHP writes into your error log file, don't be fooled.

Thankfully, I was sceptical, and regulary checked the log file. Once I learned that I had no control over it's growth, I started to think about other possibilities.

Logging PHP errors to the syslog facility

Another option PHP offers is to log to syslog. If you are on a Gentoo system, you probably know that any errors are logged into /var/log/everything/current. To get PHP to log it's errors to that file, you only have to change a tiny bit of code in your error handling section of the php.ini file:

error_reporting = E_ALL log_errors = On log_errors_max_len = 1024 ignore_repeated_errors = On ignore_repeated_source = Off report_memleaks = On track_errors = Off error_log = syslog

So, instead of specifying a path to an error log file, you simply specify syslog as your way of error logging. Restart apache, and reload your PHP script that contains an error.

Note that messages aren't immediately recorded into log files; that is actually a feature of metalog, it avoids disk I/O and improves performance. If you are too impatient to see your errors, you can temporarily disable caching:

kill -USR1 `ps -C metalog -o pid=`

And to turn it back on again:

kill -USR2 `ps -C metalog -o pid=`

Using metalog to log PHP errors into it's own error log

While it is useful to have PHP errors in the "everything" log, it would make more sense to designate a directory for PHP errors alone, just as other programs like ftpd or samba.

This is a lot simpler that it sounds. All there is to do is create a directory in e.g. /var/log, edit metalog's config file (which resides in /etc/metalog/metalog.conf), and restart metalog. Here is a sample PHP section for the metalog config file, in it's simplest way:

# DrTebi's PHP syslog logging PHP error message (sent by httpd): program = "httpd" logdir = "/var/log/php"

By default, if you are on a Gentoo system, all log files are rotated daily, or if they exceed 100KB, and a maximum of 5 log files is kept. These settings can be adjusted for every section individually, so you may want to play around with it, if you aren't happy with the defaults.

You can find more information about metalog at metalog's website, and read more about PHP's error directives on PHP's manual.

Blog Archive