PHP PSRs : PSR-3 Logger Interface
PSR-3 (PHP Standard Recommendation 3) defines a common interface for logging libraries to ensure interoperability between different logging implementations. It provides a standardized way for frameworks, libraries, and applications to log messages without being tightly coupled to a specific logging implementation. Key Concepts of PSR-3 Psr\Log\LoggerInterface Defines a standard set of logging methods. Implementations must provide these methods to handle logging at different severity levels. Log Levels (Psr\Log\LogLevel) PSR-3 defines eight severity levels: emergency: System is unusable. alert: Action must be taken immediately. critical: Critical conditions (e.g., system crash). error: Runtime errors that require attention. warning: Exceptional situations but not errors. notice: Normal but significant events. info: General information. debug: Debugging messages. log() Method The interface provides a generic log($level, $message, array $context = []) method. This allows logging messages dynamically without needing to call specific methods. Context Array The $context parameter is an associative array used to pass additional information. Supports placeholders in messages, replacing {key} with values from $context. LoggerInterface Definition namespace Psr\Log; interface LoggerInterface { public function emergency(string|\Stringable $message, array $context = []): void; public function alert(string|\Stringable $message, array $context = []): void; public function critical(string|\Stringable $message, array $context = []): void; public function error(string|\Stringable $message, array $context = []): void; public function warning(string|\Stringable $message, array $context = []): void; public function notice(string|\Stringable $message, array $context = []): void; public function info(string|\Stringable $message, array $context = []): void; public function debug(string|\Stringable $message, array $context = []): void; public function log(string $level, string|\Stringable $message, array $context = []): void; } Example Implementations Custom PSR-3 Logger Implementation If you want to create your own logger that follows PSR-3, implement LoggerInterface: use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; class FileLogger implements LoggerInterface { private string $logFile; public function __construct(string $logFile) { $this->logFile = $logFile; } public function log(string $level, string|\Stringable $message, array $context = []): void { $contextString = json_encode($context); $entry = strtoupper($level) . ': ' . $message . ' ' . $contextString . PHP_EOL; file_put_contents($this->logFile, $entry, FILE_APPEND); } public function emergency(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::EMERGENCY, $message, $context); } public function alert(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::ALERT, $message, $context); } public function critical(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::CRITICAL, $message, $context); } public function error(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::ERROR, $message, $context); } public function warning(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::WARNING, $message, $context); } public function notice(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::NOTICE, $message, $context); } public function info(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::INFO, $message, $context); } public function debug(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::DEBUG, $message, $context); } } // Usage $logger = new FileLogger(__DIR__ . '/app.log'); $logger->info('User logged in', ['user_id' => 123]); $logger->error('Database connection failed'); Using Monolog (PSR-3 Compliant) The most widely used PSR-3 logger in PHP is Monolog. Installation composer require monolog/monolog Example Usage use Monolog\Logger; use Monolog\Handler\StreamHandler; // Create a logger instance $log = new Logger('my_logger'); // Add a handler (logs to a file) $log->pushHandler(new StreamHandler(__DIR__ . '/app.log', Logger::DEBUG)); // Log messages at different levels $log->info('This is an info message'); $log->warning('This is a warning'); $log->error('An error occurred', ['exception' => 'Database connection failed']); Using PSR-3 in a Framework Most PHP frameworks (Laravel, Symfony, etc.) use PSR-3-compatible logging systems. Example: PSR-3 in Laravel Laravel’s logger (based on Monolog) is PSR-3 compliant: use Illuminate\Support\Facades\Log; Log::info('User logged in', ['user_id' => 123]); Log::error('Payment failed', ['error' =>

PSR-3 (PHP Standard Recommendation 3) defines a common interface for logging libraries to ensure interoperability between different logging implementations. It provides a standardized way for frameworks, libraries, and applications to log messages without being tightly coupled to a specific logging implementation.
Key Concepts of PSR-3
Psr\Log\LoggerInterface
- Defines a standard set of logging methods.
- Implementations must provide these methods to handle logging at different severity levels.
Log Levels (Psr\Log\LogLevel
)
- PSR-3 defines eight severity levels:
-
emergency
: System is unusable. -
alert
: Action must be taken immediately. -
critical
: Critical conditions (e.g., system crash). -
error
: Runtime errors that require attention. -
warning
: Exceptional situations but not errors. -
notice
: Normal but significant events. -
info
: General information. -
debug
: Debugging messages.
-
log()
Method
- The interface provides a generic
log($level, $message, array $context = [])
method. - This allows logging messages dynamically without needing to call specific methods.
Context Array
- The
$context
parameter is an associative array used to pass additional information. - Supports placeholders in messages, replacing
{key}
with values from$context
.
LoggerInterface Definition
namespace Psr\Log;
interface LoggerInterface {
public function emergency(string|\Stringable $message, array $context = []): void;
public function alert(string|\Stringable $message, array $context = []): void;
public function critical(string|\Stringable $message, array $context = []): void;
public function error(string|\Stringable $message, array $context = []): void;
public function warning(string|\Stringable $message, array $context = []): void;
public function notice(string|\Stringable $message, array $context = []): void;
public function info(string|\Stringable $message, array $context = []): void;
public function debug(string|\Stringable $message, array $context = []): void;
public function log(string $level, string|\Stringable $message, array $context = []): void;
}
Example Implementations
Custom PSR-3 Logger Implementation
If you want to create your own logger that follows PSR-3, implement LoggerInterface
:
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
class FileLogger implements LoggerInterface {
private string $logFile;
public function __construct(string $logFile) {
$this->logFile = $logFile;
}
public function log(string $level, string|\Stringable $message, array $context = []): void {
$contextString = json_encode($context);
$entry = strtoupper($level) . ': ' . $message . ' ' . $contextString . PHP_EOL;
file_put_contents($this->logFile, $entry, FILE_APPEND);
}
public function emergency(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::EMERGENCY, $message, $context); }
public function alert(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::ALERT, $message, $context); }
public function critical(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::CRITICAL, $message, $context); }
public function error(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::ERROR, $message, $context); }
public function warning(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::WARNING, $message, $context); }
public function notice(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::NOTICE, $message, $context); }
public function info(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::INFO, $message, $context); }
public function debug(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::DEBUG, $message, $context); }
}
// Usage
$logger = new FileLogger(__DIR__ . '/app.log');
$logger->info('User logged in', ['user_id' => 123]);
$logger->error('Database connection failed');
Using Monolog (PSR-3 Compliant)
The most widely used PSR-3 logger in PHP is Monolog.
Installation
composer require monolog/monolog
Example Usage
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// Create a logger instance
$log = new Logger('my_logger');
// Add a handler (logs to a file)
$log->pushHandler(new StreamHandler(__DIR__ . '/app.log', Logger::DEBUG));
// Log messages at different levels
$log->info('This is an info message');
$log->warning('This is a warning');
$log->error('An error occurred', ['exception' => 'Database connection failed']);
Using PSR-3 in a Framework
Most PHP frameworks (Laravel, Symfony, etc.) use PSR-3-compatible logging systems.
Example: PSR-3 in Laravel
Laravel’s logger (based on Monolog) is PSR-3 compliant:
use Illuminate\Support\Facades\Log;
Log::info('User logged in', ['user_id' => 123]);
Log::error('Payment failed', ['error' => 'Insufficient funds']);
Conclusion
- PSR-3 provides a standardized way to log messages across PHP applications.
- Monolog is the most popular PSR-3-compliant library.
- You can implement a custom logger by implementing
LoggerInterface
. - Frameworks like Laravel and Symfony already support PSR-3.