Lightweight psr-3 logger library.
It is recommended to install the package with composer:
require: {
"joebengalen/logger": "*"
}
use JoeBengalen\Logger\Logger;
use JoeBengalen\Logger\Handler;
// basic instantiation of the logger
$logger = new Logger([
// callable handlers
]);
// basic usage
$logger->emergency('emergency message'); // System is unusable
$logger->alert('alert message'); // Action must be taken immediately (Example: Entire website down, database unavailable, etc. This should trigger the SMS alerts and wake you up.)
$logger->critical('critical message'); // Critical conditions (Example: Application component unavailable, unexpected exception.)
$logger->error('error message'); // Runtime errors that do not require immediate action but should typically be logged and monitored.
$logger->warning('warning message'); // Exceptional occurrences that are not errors (Example: Use of deprecated APIs, poor use of an API, undesirable things that are not necessarily wrong.)
$logger->notice('notice message'); // Normal but significant events.
$logger->info('info message'); // Interesting events (Example: User logs in, SQL logs.)
$logger->debug('debug message'); // Detailed debug information.
Along with a message also a second argument can be passed. This context is an array which could contain anything.
The $context
can be used to replace placeholders in the message.
$logger->info('User {username} created.', ['username' => 'John Doe']);
// -> User John Doe created.
The context has a special key exception which could be used to pass an \Exception
. The handler can recognize the \Exception
and act upon it.
$logger->critical("Unexpected Exception occurred.", ['exception' => new \Exception('Something went horribly wrong :(')]);
Aside from the named functionality the context array can be used to pass any data that may be useful for the message.
Handers are callables registered to the logger. It is up to the user which handler(s) to register. Note that there is no default handler. So if none is registered nothing happens. The registered handlers will be called in the order they are given.
All shipped handlers process every message. There if no filter based on the log level.
The FileHandler
is given a file in its initialization and logs all messages into that file.
$logger = new Logger([
new Handler\FileHandler('default.log')
]);
The DatabaseHandler
is given \PDO
instance in its initialization and logs all messages into a table.
$logger = new Logger([
new Handler\DatabaseHander(new \PDO(...));
]);
A handler is, simply put, a callable, which is given an instance of JoeBengalen\Logger\MessageInterface
.
function (\JoeBengalen\Logger\MessageInterface $message) { }
All shipped handlers are invokable objects, but a handler could as well be an anonymous function, a static class method or any other valid callable.
use JoeBengalen\Logger\MessageInterface;
use Psr\Log\LogLevel;
$logger = new Logger([
// anonymous function
function (MessageInterface $message) {
if ($message->getLevel() === LogLevel::EMERGENCY) {
// send an email
}
},
// static class method
['ClassName', 'staticMethod'] // declared somewhere else
]);
Note that it is up to the handler to handle the context array properly. (For example, replacing placeholders in the message and recognizing an \Exception
)
The factory to create a MessageInterface instance is another callable, registered as $option message.factory
. This factory is given three arguments. The $level
, $message
and array $context
and should return an instance that implements the JoeBengalen\Logger\MessageInterface
. Apart from that the factory is completely free to return any object (as long as it implements the right interface) it wants and format the given arguments as it pleases.
By default an instance of Message
is returned.
use JoeBengalen\Logger\Logger;
use JoeBengalen\Logger\Message;
$logger = new Logger([
// handlers
], [
// MessageInterface factory
'message.factory' => function($level, $message, $context) {
return new Message($level, $message, $context);
}
]);