Sorry for the delay in getting the next parts finished, Heartbleed forced a rather sudden “time to learn more about server security” session.
If you’ve been following thus far, we have a Logger class we can drop in wherever we need it, that won’t cause a major headache if we want to upgrade in the future. Now, let’s make it a useful class.
At its core, my Logger is a wrapper for the Monolog\Logger class. To get it up and running, we need an instance of Monolog and a handler to actually do something.
namespace Core; class Logger { protected static $instance; protected $logger; public static function getInstance() { if (self::$instance === null) { self::$instance = new \Core\Logger(); } return self::$instance; } protected function __construct() { $this->logger = new \Monolog\Logger('Application'); $streamHandler = new \Monolog\Handler\StreamHandler('/var/log/monolog.log'); $this->logger->pushHandler($streamHandler); } }
The getInstance is just standard Singleton code. Line 14 creates the Monolog instance. We pass in the name of our logger, this appears in all log entries. This can be used if you want multiple loggers writing to a single file.
At this point, we can issue log commands to $this->logger, but it won’t do anything. To get Monolog to be of use, we attach handlers, the most basic of which is the StreamHandler. This simply writes any log entries to a file, here we’re using /var/log/monolog.log. With the handler created, we push it on to the base logger, and we’re all set for our first logging session.
To actually make calls to the logger, we need a way to pass in the info through to the underlying Monolog. We’ll start with just the Info method:
public function addInfo($message) { $this->logger->addInfo($message); }
(it might seem a waste to have such a simple wrapper, but later on this will allow us to add functionality to the logger)
All that’s left it to actually log something!
$logger = Logger::getInstance(); $logger->addInfo('Interesting event');
If the machine spirits are smiling, have a look at /var/log/monolog.log and you should see
[2014-04-29 11:52:57] Application.INFO: Interesting event [] []
Congratulations on your first custom log message! A quick guide, “Application” was set in out Logger constructor, “INFO” is the log level, followed by our message. The “[] []” is for additional information we can attach to the logger, but that’s for a future time.
“Application” comes in useful if you want to set up a secondary logger, say “Security”, but have it end up in the same file. The benefit of this approach is logs are no longer just about errors, but events. A user locking their account out with repeated failed attempts might warrant a Security.INFO entry, even though it’s not an actual programming error.
For your homework, have a read up on the error log severity levels (we used INFO earlier). It’s entirely up to you what levels you’ll be logging at, but you want to keep it consistent. Have a think about what will be beneficial to record in your current sites, and I’ll be back soon with the next part, completing the logger with a few enhancements for basic logging.