Update loging to match (proposed) logging PSR.

This commit is contained in:
Justin Hileman
2012-11-30 19:01:47 -08:00
parent d1fb1d86c5
commit 7522e2206d
5 changed files with 307 additions and 212 deletions
+7 -3
View File
@@ -341,17 +341,21 @@ class Mustache_Engine
/** /**
* Set the Mustache Logger instance. * Set the Mustache Logger instance.
* *
* @param Mustache_Logger $logger * @param Mustache_Logger|Psr\Log\LoggerInterface $logger
*/ */
public function setLogger(Mustache_Logger $logger) public function setLogger($logger = null)
{ {
if ($logger !== null && !($logger instanceof Mustache_Logger || is_a($logger, 'Psr\\Log\\LoggerInterface'))) {
throw new InvalidArgumentException('Expected an instance of Mustache_Logger or Psr\\Log\\LoggerInterface.');
}
$this->logger = $logger; $this->logger = $logger;
} }
/** /**
* Get the current Mustache Logger instance. * Get the current Mustache Logger instance.
* *
* @return Mustache_Logger * @return Mustache_Logger|Psr\Log\LoggerInterface
*/ */
public function getLogger() public function getLogger()
{ {
+98 -38
View File
@@ -10,66 +10,126 @@
*/ */
/** /**
* The Mustache Logger interface. * Describes a Mustache logger instance
*
* This is identical to the Psr\Log\LoggerInterface.
*
* The message MUST be a string or object implementing __toString().
*
* The message MAY contain placeholders in the form: %foo% where foo
* will be replaced by the context data in key "foo".
*
* The context array can contain arbitrary data, the only assumption that
* can be made by implementors is that if an Exception instance is given
* to produce a stack trace, it MUST be in a key named "exception".
*
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
* for the full interface specification.
*/ */
interface Mustache_Logger interface Mustache_Logger
{ {
/** /**
* Detailed debug information * Psr\Log compatible log levels
*/ */
const DEBUG = 100; const EMERGENCY = 'emergency';
const ALERT = 'alert';
const CRITICAL = 'critical';
const ERROR = 'error';
const WARNING = 'warning';
const NOTICE = 'notice';
const INFO = 'info';
const DEBUG = 'debug';
/** /**
* Interesting events * System is unusable.
* *
* Examples: User logs in, SQL logs. * @param string $message
* @param array $context
* @return null
*/ */
const INFO = 200; public function emergency($message, array $context = array());
/** /**
* Uncommon events * Action must be taken immediately.
*/
const NOTICE = 250;
/**
* Exceptional occurrences that are not errors
* *
* Examples: Use of deprecated APIs, poor use of an API, * Example: Entire website down, database unavailable, etc. This should
* undesirable things that are not necessarily wrong. * trigger the SMS alerts and wake you up.
*
* @param string $message
* @param array $context
* @return null
*/ */
const WARNING = 300; public function alert($message, array $context = array());
/** /**
* Runtime errors * Critical conditions.
*/
const ERROR = 400;
/**
* Critical conditions
* *
* Example: Application component unavailable, unexpected exception. * Example: Application component unavailable, unexpected exception.
*/
const CRITICAL = 500;
/**
* Action must be taken immediately
* *
* Example: Entire website down, database unavailable, etc. * @param string $message
* This should trigger the SMS alerts and wake you up. * @param array $context
* @return null
*/ */
const ALERT = 550; public function critical($message, array $context = array());
/** /**
* Urgent alert. * Runtime errors that do not require immediate action but should typically
*/ * be logged and monitored.
const EMERGENCY = 600;
/**
* Adds a log record.
* *
* @param integer $level The logging level * @param string $message
* @param string $message The log message * @param array $context
* @param array $context The log context * @return null
*/
public function error($message, array $context = array());
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string $message
* @param array $context
* @return null
*/
public function warning($message, array $context = array());
/**
* Normal but significant events.
*
* @param string $message
* @param array $context
* @return null
*/
public function notice($message, array $context = array());
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
* @return null
*/
public function info($message, array $context = array());
/**
* Detailed debug information.
*
* @param string $message
* @param array $context
* @return null
*/
public function debug($message, array $context = array());
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return null
*/ */
public function log($level, $message, array $context = array()); public function log($level, $message, array $context = array());
} }
-120
View File
@@ -1,120 +0,0 @@
<?php
/*
* This file is part of Mustache.php.
*
* (c) 2012 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* An abstract Mustache Logger implementation.
*/
abstract class Mustache_Logger_AbstractLogger implements Mustache_Logger
{
protected static $levels = array(
100 => 'DEBUG',
200 => 'INFO',
250 => 'NOTICE',
300 => 'WARNING',
400 => 'ERROR',
500 => 'CRITICAL',
550 => 'ALERT',
600 => 'EMERGENCY',
);
/**
* Abstract Logger constructor.
*
* @throws InvalidArgumentException if the logging level is unknown.
*
* @param integer $level The minimum logging level which will be written
*/
public function __construct($level = self::ERROR)
{
$this->setLevel($level);
}
/**
* Set the minimum logging level.
*
* @throws InvalidArgumentException if the logging level is unknown.
*
* @param integer $level The minimum logging level which will be written
*/
public function setLevel($level)
{
if (!array_key_exists($level, self::$levels)) {
throw new InvalidArgumentException('Unexpected logging level: ' . $level);
}
$this->level = $level;
}
/**
* Get the current minimum logging level.
*
* @return integer
*/
public function getLevel()
{
return $this->level;
}
/**
* Adds a log record.
*
* @see Mustache_Logger_AbstractLogger::write
*
* @param integer $level The logging level
* @param string $message The log message
* @param array $context The log context
*/
public function log($level, $message, array $context = array())
{
if ($level >= $this->level) {
$this->writeLog($level, $message, $context);
}
}
/**
* Gets the name of the logging level.
*
* @throws InvalidArgumentException if the logging level is unknown.
*
* @param integer $level
*
* @return string
*/
public static function getLevelName($level)
{
if (!array_key_exists($level, self::$levels)) {
throw new InvalidArgumentException('Unexpected logging level: ' . $level);
}
return self::$levels[$level];
}
/**
* Format a log line for output.
*
* @param integer $level The logging level
* @param string $message The log message
* @param array $context The log context
*/
public static function formatLine($level, $message, array $context = array())
{
return sprintf('%s: %s %s', self::getLevelName($level), (string) $message, json_encode($context));
}
/**
* Write a record to the log. Implemented by subclasses.
*
* @param integer $level The logging level
* @param string $message The log message
* @param array $context The log context
*/
abstract protected function write($level, $message, array $context = array());
}
-47
View File
@@ -1,47 +0,0 @@
<?php
/*
* This file is part of Mustache.php.
*
* (c) 2012 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* A Mustache Monolog Logger adapter.
*/
class MonologLogger implements Mustache_Logger
{
protected $logger;
/**
* @param \Monolog\Logger $logger
*/
public function __construct($logger)
{
// not typehinting this because PHP 5.2 that's why.
if (!is_a($logger, 'Monolog\\Logger')) {
throw new InvalidArgumentException('MonologLogger requires a Monolog\\Logger instance.');
}
$this->logger = $logger;
}
/**
* Adds a log record.
*
* Overload the AbstractLogger::log method, because all log messages should
* be passed through to Monolog regardless of the log level. Monolog will
* handle ignoring the messages it doesn't care about.
*
* @param integer $level The logging level
* @param string $message The log message
* @param array $context The log context
*/
public function log($level, $message, array $context = array())
{
$this->logger->addRecord($level, $message, $context);
}
}
+201 -3
View File
@@ -18,8 +18,19 @@
* *
* Hint: Try `php://stderr` for your stream URL. * Hint: Try `php://stderr` for your stream URL.
*/ */
class StreamLogger extends Mustache_Logger_AbstractLogger class StreamLogger implements Mustache_Logger
{ {
protected static $levels = array(
self::DEBUG => 100,
self::INFO => 200,
self::NOTICE => 250,
self::WARNING => 300,
self::ERROR => 400,
self::CRITICAL => 500,
self::ALERT => 550,
self::EMERGENCY => 600,
);
protected $stream = null; protected $stream = null;
protected $url = null; protected $url = null;
@@ -29,7 +40,7 @@ class StreamLogger extends Mustache_Logger_AbstractLogger
*/ */
public function __construct($stream, $level = Mustache_Logger::ERROR) public function __construct($stream, $level = Mustache_Logger::ERROR)
{ {
parent::__construct($level); $this->setLevel($level);
if (is_resource($stream)) { if (is_resource($stream)) {
$this->stream = $stream; $this->stream = $stream;
@@ -38,6 +49,158 @@ class StreamLogger extends Mustache_Logger_AbstractLogger
} }
} }
/**
* Set the minimum logging level.
*
* @throws InvalidArgumentException if the logging level is unknown.
*
* @param integer $level The minimum logging level which will be written
*/
public function setLevel($level)
{
if (!array_key_exists($level, self::$levels)) {
throw new InvalidArgumentException('Unexpected logging level: ' . $level);
}
$this->level = $level;
}
/**
* Get the current minimum logging level.
*
* @return integer
*/
public function getLevel()
{
return $this->level;
}
/**
* System is unusable.
*
* @param string $message
* @param array $context
* @return null
*/
public function emergency($message, array $context = array())
{
$this->log(self::EMERGENCY, $message, $context);
}
/**
* Action must be taken immediately.
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string $message
* @param array $context
* @return null
*/
public function alert($message, array $context = array())
{
$this->log(self::ALERT, $message, $context);
}
/**
* Critical conditions.
*
* Example: Application component unavailable, unexpected exception.
*
* @param string $message
* @param array $context
* @return null
*/
public function critical($message, array $context = array())
{
$this->log(self::CRITICAL, $message, $context);
}
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string $message
* @param array $context
* @return null
*/
public function error($message, array $context = array())
{
$this->log(self::ERROR, $message, $context);
}
/**
* Exceptional occurrences that are not errors.
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string $message
* @param array $context
* @return null
*/
public function warning($message, array $context = array())
{
$this->log(self::WARNING, $message, $context);
}
/**
* Normal but significant events.
*
* @param string $message
* @param array $context
* @return null
*/
public function notice($message, array $context = array())
{
$this->log(self::NOTICE, $message, $context);
}
/**
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string $message
* @param array $context
* @return null
*/
public function info($message, array $context = array())
{
$this->log(self::INFO, $message, $context);
}
/**
* Detailed debug information.
*
* @param string $message
* @param array $context
* @return null
*/
public function debug($message, array $context = array())
{
$this->log(self::DEBUG, $message, $context);
}
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return null
*/
public function log($level, $message, array $context = array())
{
if (!array_key_exists($level, self::$levels)) {
throw new InvalidArgumentException('Unexpected logging level: ' . $level);
}
if (self::$levels[$level] >= $this->level) {
$this->writeLog($level, $message, $context);
}
}
/** /**
* Write a record to the log. * Write a record to the log.
* *
@@ -45,7 +208,7 @@ class StreamLogger extends Mustache_Logger_AbstractLogger
* @param string $message The log message * @param string $message The log message
* @param array $context The log context * @param array $context The log context
*/ */
protected function write($level, $message, array $context = array()) protected function writeLog($level, $message, array $context = array())
{ {
if (!is_resource($this->stream)) { if (!is_resource($this->stream)) {
if (!isset($this->url)) { if (!isset($this->url)) {
@@ -60,4 +223,39 @@ class StreamLogger extends Mustache_Logger_AbstractLogger
fwrite($this->stream, self::formatLine($level, $message, $context)); fwrite($this->stream, self::formatLine($level, $message, $context));
} }
/**
* Gets the name of the logging level.
*
* @throws InvalidArgumentException if the logging level is unknown.
*
* @param integer $level
*
* @return string
*/
protected static function getLevelName($level)
{
if (!array_key_exists($level, self::$levels)) {
throw new InvalidArgumentException('Unexpected logging level: ' . $level);
}
return strtoupper($level);
}
/**
* Format a log line for output.
*
* @param integer $level The logging level
* @param string $message The log message
* @param array $context The log context
*/
protected static function formatLine($level, $message, array $context = array())
{
$message = (string) $message;
foreach ($context as $key => $val) {
$message = str_replace('%'.$key.'%', $val, $message);
}
return sprintf('%s: %s %s', self::getLevelName($level), (string) $message, json_encode($context));
}
} }