Logging in PHP

There are tons of PHP logging apps out there, but here is my take on it. This is a simple drop-in class that is 1 file and is pretty flexible. In my opinion this is about all that is required of a PHP logging class, and its been working out well for me.

<?php
/**
 * Very simple error logger
 * Set error level using bitwise OR
 * 
 * Example Usage:
 * 
 *    SimpleLogger::log_level(SimpleLogger::All);
 *    SimpleLogger::log_method(function($message, $level = 0)
 *    {
 *      printf("[LOG:%d] %s\n", $level, $message);
 *    });
 * 
 * 
 */
class SimpleLogger
{
  const Debug = 1;
  const Info = 2;
  const Error = 4;
  const All = 7;
  const None = 0;
  
  static private $_log_level = self::All;
  static private $_log_method;
  
  /**
   * Sets the log level
   * Example:
   *  SimpleLogger::log_level(SimpleLogger::Error | SimpleLogger::Info);
   * @param integer $level the log level
   */
  static public
  function log_level($level = self::All)
  {
    self::$_log_level = (int)$level;
  }
  
  /**
   * Sets the log method/callback
   * @param mixed $callback if an array/string is given we use call_user_func_array, otherwise we call __invoke() on the object
   *                        so we support closures in PHP >= 5.3.0
   * 
   */
  static public
  function log_method($callback)
  {
    self::$_log_method = $callback;
  }
  
  /**
   * Log debug messages
   * @param string $message
   */
  static public
  function debug($message)
  {
    self::log($message, self::Debug);
  }
  
  /**
   * Log info messages
   * @param string $message
   */
  static public
  function info($message)
  {
    self::log($message, self::Info);
  }
  
  /**
   * Log error messages
   * @param string $message
   */
  static public
  function error($message)
  {
    self::log($message, self::Error);
  }
  
  /**
   * Generic log wrapper, specify a level
   * @param string $message
   * @param integer $level the log level
   */
  static public
  function log($message, $level = self::All)
  {
    if((self::$_log_level & $level) && self::$_log_method && is_callable(self::$_log_method))
    {
      if(is_object(self::$_log_method))
        self::$_log_method->__invoke($message, $level);
      else
        call_user_func_array(self::$_log_method, array($message, $level));
    }
  }
}
?>

Usage

<?php

require 'simple_logger.php';

SimpleLogger::log_level(SimpleLogger::All);
SimpleLogger::log_method(function($message, $level = 0)
{
  echo $message;
});

// capture the log messages
function capture_output($callback)
{
  ob_start();
    $callback();
    $data = ob_get_contents();
  ob_end_clean();
  return $data;
}

// send the log messages
function send_messages()
{
  $data = capture_output(function()
  {
    SimpleLogger::info('Info');
    SimpleLogger::debug('Debug');
    SimpleLogger::error('Error');
  });
  return $data;
}

// test info logs
SimpleLogger::log_level(SimpleLogger::Info);
$data = send_messages();
assert($data == 'Info');

// test debug
SimpleLogger::log_level(SimpleLogger::Debug);
$data = send_messages();
assert($data == 'Debug');

// test error
SimpleLogger::log_level(SimpleLogger::Error);
$data = send_messages();
assert($data == 'Error');

// test combining
SimpleLogger::log_level(SimpleLogger::Info | SimpleLogger::Error);
$data = send_messages();
assert($data == 'InfoError');

// test all
SimpleLogger::log_level(SimpleLogger::All);
$data = send_messages();
assert($data == 'InfoDebugError');

// test none
SimpleLogger::log_level(SimpleLogger::None);
$data = send_messages();
assert($data == '');

// test no method
SimpleLogger::log_level(SimpleLogger::All);
SimpleLogger::log_method(null);
$data = send_messages();
assert($data == '');

?>

View Gist