Using Monolog for Logging
What is Monolog?
Section titled “What is Monolog?”Monolog is a comprehensive logging library for PHP that sends your log records to files, sockets, inboxes, databases and various web services. It’s perfect for tracking application behavior, debugging issues, and monitoring your REST API built with Slim framework.
Key benefits:
- PSR-3 compliant logging interface
- Multiple handlers for different output destinations
- Processors to add extra information to log records
- Flexible formatting options
- Support for log levels from DEBUG to EMERGENCY
Installation
Section titled “Installation”Install Monolog using Composer:
composer require monolog/monolog- However, Monolog is already included in the provided Slim template. So you can skip this step.
Using Monolog with Slim Framework
Section titled “Using Monolog with Slim Framework”-
Import Monolog classes in your application
use Monolog\Logger;use Monolog\Handler\StreamHandler;php -
Create a logger instance with a channel name
// Create a logger with a channel name (e.g., 'app_access', 'api', 'database').$logger = new Logger('app_access');php -
Add one or more handlers to define where logs go
// Log to a file - INFO level and above.$logger->pushHandler(new StreamHandler(__DIR__ . '/logs/app.log', Logger::INFO));// You can add multiple handlers for different purposes.// For example, log errors to a separate file.$logger->pushHandler(new StreamHandler(__DIR__ . '/logs/errors.log', Logger::ERROR));php -
Use the logger throughout your application
$app->post('/api/planets', function ($request, $response) use ($logger) {$data = $request->getParsedBody();// Log the incoming request.$logger->info('Creating new planet', ['data' => $data]);// Your business logic here...return $response->withStatus(201);});php
Understanding Log Levels
Section titled “Understanding Log Levels”Monolog implements the PSR-3 logging standard with eight severity levels. Use the appropriate level based on the type of information you’re logging:
| Level | Method | When to Use | Example |
|---|---|---|---|
| DEBUG | $logger->debug() | Detailed debug information | Variable values, loop iterations |
| INFO | $logger->info() | Interesting events | User login, API requests |
| NOTICE | $logger->notice() | Normal but significant events | Configuration changes |
| WARNING | $logger->warning() | Exceptional occurrences that are not errors | Use of deprecated APIs, poor API usage |
| ERROR | $logger->error() | Runtime errors that don’t require immediate action | Database connection failed |
| CRITICAL | $logger->critical() | Critical conditions | Application component unavailable |
| ALERT | $logger->alert() | Action must be taken immediately | Entire website down |
| EMERGENCY | $logger->emergency() | System is unusable | Database unavailable, system crash |
Common Logging Patterns
Section titled “Common Logging Patterns”- Logging Request Information
- Logging Database Operations
- Logging API Calls
- Logging Exceptions
- Logging Authentication Events
Adding Context to Logs
Section titled “Adding Context to Logs”Monolog allows you to add contextual information to your log messages using arrays:
// Simple context.$logger->info('User logged in', ['user_id' => 123]);
// Rich context.$logger->error('Payment processing failed', [ 'user_id' => 123, 'amount' => 99.99, 'currency' => 'USD', 'error_code' => 'CARD_DECLINED', 'timestamp' => time()]);Configuring Time Zone and Log Format
Section titled “Configuring Time Zone and Log Format”Setting the Time Zone
Section titled “Setting the Time Zone”By default, Monolog uses UTC for timestamps. You can change this globally for all loggers:
use Monolog\Logger;
$logger = new Logger('access');// Set the default timezone for this logger.$logger->setTimezone(new \DateTimeZone('America/New_York'));Customizing Log Format
Section titled “Customizing Log Format”Monolog uses formatters to control how log records appear. The default LineFormatter can be customized:
use Monolog\Handler\StreamHandler;use Monolog\Formatter\LineFormatter;
$handler = new StreamHandler(__DIR__ . '/logs/app.log', Logger::INFO);
// Create a custom format.// Available placeholders: %datetime%, %channel%, %level_name%, %message%, %context%, %extra%$dateFormat = "Y-m-d H:i:s";$outputFormat = "[%datetime%] %channel%.%level_name%: %message% %context%\n";
$formatter = new LineFormatter($outputFormat, $dateFormat);$handler->setFormatter($formatter);
$logger = new Logger('app');$logger->pushHandler($handler);Example output:
[2025-11-10 14:30:45] app.INFO: User logged in {"user_id":123}[2025-11-10 14:31:12] app.ERROR: Database connection failed {"error":"Connection timeout"}