Overview of the Logger

A logger typically provides methods to log messages at different severity levels, such as DEBUG, INFO, WARNING, ERROR, and CRITICAL. Our custom logger will include the following features:

  • Support for multiple log levels.
  • File-based logging with rotation.
  • Customizable log message formatting.

Logger Class Implementation

Let’s start by creating a Logger class that encapsulates the logging logic. This class will handle writing log messages to a file and will allow us to specify the log level.

<?php

class Logger
{
    const LOG_LEVELS = [
        'DEBUG' => 0,
        'INFO' => 1,
        'WARNING' => 2,
        'ERROR' => 3,
        'CRITICAL' => 4,
    ];

    private $logFile;
    private $logLevel;

    public function __construct($logFile, $logLevel = 'DEBUG')
    {
        $this->logFile = $logFile;
        $this->logLevel = self::LOG_LEVELS[$logLevel];
    }

    public function log($level, $message)
    {
        if (self::LOG_LEVELS[$level] >= $this->logLevel) {
            $formattedMessage = $this->formatMessage($level, $message);
            file_put_contents($this->logFile, $formattedMessage, FILE_APPEND);
        }
    }

    private function formatMessage($level, $message)
    {
        $timestamp = date('Y-m-d H:i:s');
        return "[$timestamp] [$level] $message\n";
    }
}

Using the Logger

To use the Logger class, simply instantiate it with the desired log file and log level. Then, call the log method to write messages.

<?php

$logger = new Logger('app.log', 'INFO');

$logger->log('DEBUG', 'This is a debug message.');
$logger->log('INFO', 'Application started.');
$logger->log('WARNING', 'This is a warning message.');
$logger->log('ERROR', 'An error occurred.');
$logger->log('CRITICAL', 'Critical issue encountered!');

Implementing Log Rotation

Log files can grow large over time, making it essential to implement log rotation. This can be done by checking the file size before writing a new log entry. If the file exceeds a certain size, we can rename it and create a new log file.

private function rotateLogFile()
{
    if (file_exists($this->logFile) && filesize($this->logFile) > 1048576) { // 1MB limit
        rename($this->logFile, $this->logFile . '.' . date('Y-m-d_H-i-s'));
        file_put_contents($this->logFile, ""); // Create a new log file
    }
}

public function log($level, $message)
{
    $this->rotateLogFile(); // Check for rotation before logging
    if (self::LOG_LEVELS[$level] >= $this->logLevel) {
        $formattedMessage = $this->formatMessage($level, $message);
        file_put_contents($this->logFile, $formattedMessage, FILE_APPEND);
    }
}

Log Level Comparison

To better understand the log levels, here’s a comparison table:

Log LevelSeverityDescription
DEBUG0Detailed information for debugging.
INFO1General information about application flow.
WARNING2Indications of potential problems.
ERROR3Errors that occurred during execution.
CRITICAL4Severe errors that require immediate attention.

Conclusion

A custom logger in PHP can significantly enhance your application's ability to monitor and debug. By implementing features such as log levels, file rotation, and customizable formatting, you can create a logging solution tailored to your needs. This approach not only helps in maintaining code quality but also aids in troubleshooting and performance monitoring.

Learn more with useful resources