What it is
Monolog is PHP's standard logging library, implementing PSR-3 with handlers for files, syslog, Slack, Sentry, Elasticsearch and dozens more.
A Logger has a stack of handlers, each with a minimum level. Processors enrich every record with extra context.
Installation
composer require monolog/monologGetting started
The smallest useful thing you can do with it, and what each part means.
php
<?php
use Monolog\{Logger, Level};
use Monolog\Handler\{StreamHandler, RotatingFileHandler};
use Monolog\Formatter\JsonFormatter;
$log = new Logger('app');
$file = new RotatingFileHandler(__DIR__ . '/logs/app.log', 14, Level::Info);
$file->setFormatter(new JsonFormatter());
$log->pushHandler($file);
$log->pushHandler(new StreamHandler('php://stderr', Level::Error));
// The second argument is structured context, not interpolation.
$log->info('Order shipped', [
'order_id' => $order->id,
'customer' => $order->customer,
'total' => $order->total,
]);Advanced usage
Where the library earns its place over a simpler alternative.
php
<?php
// Stamp every record with request context.
$log->pushProcessor(function (Monolog\LogRecord $record) {
$record->extra['request_id'] = RequestContext::id();
$record->extra['memory'] = memory_get_usage(true);
return $record;
});
// Buffer everything, but only write it if an error occurs — full debug
// context for failures, silence for successful requests.
$log->pushHandler(new Monolog\Handler\FingersCrossedHandler(
new RotatingFileHandler('logs/app.log'),
activationStrategy: Level::Error,
bufferSize: 200,
));Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- No log output
- No handler is registered, or every handler's minimum level is above the records being logged.
- Log files grow without bound
- Use RotatingFileHandler with a retention count, or configure logrotate.
Best practices
- Pass data in the context array rather than interpolating it into the message.
- Use FingersCrossedHandler in production for full context on failures without the volume.
- Never log passwords, tokens or full request bodies.
- Type-hint Psr\Log\LoggerInterface in your classes, not the Monolog Logger.
Background
Why it exists, and what it was reacting to.
Monolog is the logging backend behind Laravel and Symfony. Its handler and processor architecture means routing logs to a new destination is a configuration change, not a code change.
