If you have ever visited StackOverflow.com you may have noticed the ads for Splunk. Splunk aggregates log files together and provides a web interface to search through those logs. The setup for php is easy: set the php.ini error_log value to "syslog". The Splunk instructions show you how add a single line to your syslong.conf to have syslog send those messages over to Splunk.
The only downside to this is that syslog commonly has a limit of 1024 characters per message. You can change this, but you have to recompile the kernel. This is especially frustrating when an uncaught exception gets logged. The log message looks something like this:
PHP Fatal error: Uncaught exception 'Zend_Db_Statement_Exception' with message 'SQLSTATE[HY093]:
Invalidparameter number: no parameters were bound' in /some/path/to/Zend/Db/Statement
/Pdo.php:234Stack trace: #0 /some/path/to/Zend/Db/Statement.php(320): Zend_Db_Statement_
Pdo->_execute(Array)#1 /some/path/to/Zend/Db/Adapter/Pdo/Mysql.php(572): Zend_Db_
Statement->execute(Array) #2 /some/path/to/Zend/Db
If you have used Zend_Db_Statement you have probably seen this error message. If not, it simply means that too few variables are being specified or one of the variables is null when trying to bind all the variables to the placeholders in a SQL statement. Do you see the problem with this log message though? It gets cut off way before the stack trace provides any hint as to what code caused it. If I am using automated testing, it may be very difficult to tell what actually caused the exception.
To get around this, I wrote an exception handler to split the stack trace into separate messages.
SQLSTATE[HY093]: Invalid parameter number: no parameters were bound Strack Trace:
PHP 0. _execute /some/path/to/Zend/Db/Statement.php:320
PHP 1. execute /some/path/to/Zend/Db/Adapter/Pdo/Mysql.php:572
PHP 2. query /some/path/to/Zend/Db/Table/Abstract.php:1509
PHP 3. _fetch /some/path/to/Zend/Db/Table/Abstract.php:1325
PHP 4. getDooDads /some/path/to/application/default/models/DooDads.php:112
PHP 5. getAction /some/path/to/application/default/controllers/DooDadsController.php:15
PHP 6. init /some/path/to/Zend/Controller/Action.php:133
PHP 7. __construct /some/path/to/Zend/Controller/Dispatcher/Standard.php:262
PHP 8. dispatch /some/path/to/Zend/Controller/Front.php:946
PHP 9. dispatch /some/path/to/html/index.php:23
Now it is very clear that I need to add some more validation to my DooDads model.
The code is on github here. I am able to just drop it in to any project I am working on and get more verbose logging via syslog.