DEV Community

Cover image for PHP PSRs : PSR-3 Logger Interface
Antonio Silva
Antonio Silva

Posted on

2

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:
    1. emergency: System is unusable.
    2. alert: Action must be taken immediately.
    3. critical: Critical conditions (e.g., system crash).
    4. error: Runtime errors that require attention.
    5. warning: Exceptional situations but not errors.
    6. notice: Normal but significant events.
    7. info: General information.
    8. 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;
}
Enter fullscreen mode Exit fullscreen mode

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');
Enter fullscreen mode Exit fullscreen mode

Using Monolog (PSR-3 Compliant)

The most widely used PSR-3 logger in PHP is Monolog.

Installation

composer require monolog/monolog
Enter fullscreen mode Exit fullscreen mode

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']);
Enter fullscreen mode Exit fullscreen mode

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']);
Enter fullscreen mode Exit fullscreen mode

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.

AWS Q Developer image

Build your favorite retro game with Amazon Q Developer CLI in the Challenge & win a T-shirt!

Feeling nostalgic? Build Games Challenge is your chance to recreate your favorite retro arcade style game using Amazon Q Developer’s agentic coding experience in the command line interface, Q Developer CLI.

Participate Now

Top comments (0)

DevCycle image

Ship Faster, Stay Flexible.

DevCycle is the first feature flag platform with OpenFeature built-in to every open source SDK, designed to help developers ship faster while avoiding vendor-lock in.

Start shipping

👋 Kindness is contagious

Explore this practical breakdown on DEV’s open platform, where developers from every background come together to push boundaries. No matter your experience, your viewpoint enriches the conversation.

Dropping a simple “thank you” or question in the comments goes a long way in supporting authors—your feedback helps ideas evolve.

At DEV, shared discovery drives progress and builds lasting bonds. If this post resonated, a quick nod of appreciation can make all the difference.

Okay