Logging Exception Traces To syslog
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/DbIf 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:23Now 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.