Monolog is perhaps the most popular logging library out there for PHP at the time of this writing. It has a lot of support and a nice balance of features.
Unfortunately I have one gripe to make about the rather closed implementation of the SocketHandler , er, handler?
The problem with the Monolog SocketHandler (as of 1.4.1)
The key problem is that Monolog treats it complete with assumption that say, a TCP port can be connected to. So you can setup your chain of handlers and processors; but with a critical application such as logging, the SocketHandler simply let’s itself into the logger object without testing to see if it can make a TCP connection.
The problem is: there’s no pragmatic way to test if a SocketHandler object can connect; there’s only an isConnected() helper method – but no canConnect() or similar.
The solution…
The solution is a bit less pragmatic than I wanted, because the SocketHandler class has it’s key method: connect() as a private method. Thankfully the class has a ‘mock’ method to at least attempt a socket connection and not affect the state of the object. We can use that to probe if the socket can be opened, and add it as a handler to our logger object accordingly.
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<? class SocketHandler extends \Monolog\Handler\SocketHandler { public function canConnect() { if ($this->isConnected()) { return true; } if ( ($probe = $this->fsockopen() && is_resource($probe)) { fclose($probe); return true; } return false; } } ?> |
Then, you can have a little bit more assurance that you’ll get your logging to go through the handler without a nasty exception…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<? $logger = new Logger( 'itn', array( new StreamHandler('/path/to/logfile') ) ); $socketHandler = new SocketHandler('tcp://127.0.0.1:7065'); if ($socketLogger->canConnect()) { $socketLogger->pushHandler($socketHandler); } else { $logger->alert('SocketHandler connection failed.'); } ?> |
A final word…
In a high parity environment; the SocketHandler is still not immune to losing connectivity to the target socket. It would sadly, be better practice to make your own logger wrapper to safely handle logging to a file, and the SocketHandler. Perhaps sometime in the future the SocketHandler can be revised to (optionally) suppress itself from connection failures.
Leave a Reply