/vendor/monolog/monolog/src/Monolog/Logger.php |
@@ -0,0 +1,700 @@ |
<?php |
|
/* |
* This file is part of the Monolog package. |
* |
* (c) Jordi Boggiano <j.boggiano@seld.be> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Monolog; |
|
use Monolog\Handler\HandlerInterface; |
use Monolog\Handler\StreamHandler; |
use Psr\Log\LoggerInterface; |
use Psr\Log\InvalidArgumentException; |
|
/** |
* Monolog log channel |
* |
* It contains a stack of Handlers and a stack of Processors, |
* and uses them to store records that are added to it. |
* |
* @author Jordi Boggiano <j.boggiano@seld.be> |
*/ |
class Logger implements LoggerInterface |
{ |
/** |
* Detailed debug information |
*/ |
const DEBUG = 100; |
|
/** |
* Interesting events |
* |
* Examples: User logs in, SQL logs. |
*/ |
const INFO = 200; |
|
/** |
* Uncommon events |
*/ |
const NOTICE = 250; |
|
/** |
* Exceptional occurrences that are not errors |
* |
* Examples: Use of deprecated APIs, poor use of an API, |
* undesirable things that are not necessarily wrong. |
*/ |
const WARNING = 300; |
|
/** |
* Runtime errors |
*/ |
const ERROR = 400; |
|
/** |
* Critical conditions |
* |
* Example: Application component unavailable, unexpected exception. |
*/ |
const CRITICAL = 500; |
|
/** |
* Action must be taken immediately |
* |
* Example: Entire website down, database unavailable, etc. |
* This should trigger the SMS alerts and wake you up. |
*/ |
const ALERT = 550; |
|
/** |
* Urgent alert. |
*/ |
const EMERGENCY = 600; |
|
/** |
* Monolog API version |
* |
* This is only bumped when API breaks are done and should |
* follow the major version of the library |
* |
* @var int |
*/ |
const API = 1; |
|
/** |
* Logging levels from syslog protocol defined in RFC 5424 |
* |
* @var array $levels Logging levels |
*/ |
protected static $levels = array( |
self::DEBUG => 'DEBUG', |
self::INFO => 'INFO', |
self::NOTICE => 'NOTICE', |
self::WARNING => 'WARNING', |
self::ERROR => 'ERROR', |
self::CRITICAL => 'CRITICAL', |
self::ALERT => 'ALERT', |
self::EMERGENCY => 'EMERGENCY', |
); |
|
/** |
* @var \DateTimeZone |
*/ |
protected static $timezone; |
|
/** |
* @var string |
*/ |
protected $name; |
|
/** |
* The handler stack |
* |
* @var HandlerInterface[] |
*/ |
protected $handlers; |
|
/** |
* Processors that will process all log records |
* |
* To process records of a single handler instead, add the processor on that specific handler |
* |
* @var callable[] |
*/ |
protected $processors; |
|
/** |
* @var bool |
*/ |
protected $microsecondTimestamps = true; |
|
/** |
* @param string $name The logging channel |
* @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc. |
* @param callable[] $processors Optional array of processors |
*/ |
public function __construct($name, array $handlers = array(), array $processors = array()) |
{ |
$this->name = $name; |
$this->handlers = $handlers; |
$this->processors = $processors; |
} |
|
/** |
* @return string |
*/ |
public function getName() |
{ |
return $this->name; |
} |
|
/** |
* Return a new cloned instance with the name changed |
* |
* @return static |
*/ |
public function withName($name) |
{ |
$new = clone $this; |
$new->name = $name; |
|
return $new; |
} |
|
/** |
* Pushes a handler on to the stack. |
* |
* @param HandlerInterface $handler |
* @return $this |
*/ |
public function pushHandler(HandlerInterface $handler) |
{ |
array_unshift($this->handlers, $handler); |
|
return $this; |
} |
|
/** |
* Pops a handler from the stack |
* |
* @return HandlerInterface |
*/ |
public function popHandler() |
{ |
if (!$this->handlers) { |
throw new \LogicException('You tried to pop from an empty handler stack.'); |
} |
|
return array_shift($this->handlers); |
} |
|
/** |
* Set handlers, replacing all existing ones. |
* |
* If a map is passed, keys will be ignored. |
* |
* @param HandlerInterface[] $handlers |
* @return $this |
*/ |
public function setHandlers(array $handlers) |
{ |
$this->handlers = array(); |
foreach (array_reverse($handlers) as $handler) { |
$this->pushHandler($handler); |
} |
|
return $this; |
} |
|
/** |
* @return HandlerInterface[] |
*/ |
public function getHandlers() |
{ |
return $this->handlers; |
} |
|
/** |
* Adds a processor on to the stack. |
* |
* @param callable $callback |
* @return $this |
*/ |
public function pushProcessor($callback) |
{ |
if (!is_callable($callback)) { |
throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given'); |
} |
array_unshift($this->processors, $callback); |
|
return $this; |
} |
|
/** |
* Removes the processor on top of the stack and returns it. |
* |
* @return callable |
*/ |
public function popProcessor() |
{ |
if (!$this->processors) { |
throw new \LogicException('You tried to pop from an empty processor stack.'); |
} |
|
return array_shift($this->processors); |
} |
|
/** |
* @return callable[] |
*/ |
public function getProcessors() |
{ |
return $this->processors; |
} |
|
/** |
* Control the use of microsecond resolution timestamps in the 'datetime' |
* member of new records. |
* |
* Generating microsecond resolution timestamps by calling |
* microtime(true), formatting the result via sprintf() and then parsing |
* the resulting string via \DateTime::createFromFormat() can incur |
* a measurable runtime overhead vs simple usage of DateTime to capture |
* a second resolution timestamp in systems which generate a large number |
* of log events. |
* |
* @param bool $micro True to use microtime() to create timestamps |
*/ |
public function useMicrosecondTimestamps($micro) |
{ |
$this->microsecondTimestamps = (bool) $micro; |
} |
|
/** |
* Adds a log record. |
* |
* @param int $level The logging level |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function addRecord($level, $message, array $context = array()) |
{ |
if (!$this->handlers) { |
$this->pushHandler(new StreamHandler('php://stderr', static::DEBUG)); |
} |
|
$levelName = static::getLevelName($level); |
|
// check if any handler will handle this message so we can return early and save cycles |
$handlerKey = null; |
reset($this->handlers); |
while ($handler = current($this->handlers)) { |
if ($handler->isHandling(array('level' => $level))) { |
$handlerKey = key($this->handlers); |
break; |
} |
|
next($this->handlers); |
} |
|
if (null === $handlerKey) { |
return false; |
} |
|
if (!static::$timezone) { |
static::$timezone = new \DateTimeZone(date_default_timezone_get() ?: 'UTC'); |
} |
|
// php7.1+ always has microseconds enabled, so we do not need this hack |
if ($this->microsecondTimestamps && PHP_VERSION_ID < 70100) { |
$ts = \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), static::$timezone); |
} else { |
$ts = new \DateTime(null, static::$timezone); |
} |
$ts->setTimezone(static::$timezone); |
|
$record = array( |
'message' => (string) $message, |
'context' => $context, |
'level' => $level, |
'level_name' => $levelName, |
'channel' => $this->name, |
'datetime' => $ts, |
'extra' => array(), |
); |
|
foreach ($this->processors as $processor) { |
$record = call_user_func($processor, $record); |
} |
|
while ($handler = current($this->handlers)) { |
if (true === $handler->handle($record)) { |
break; |
} |
|
next($this->handlers); |
} |
|
return true; |
} |
|
/** |
* Adds a log record at the DEBUG level. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function addDebug($message, array $context = array()) |
{ |
return $this->addRecord(static::DEBUG, $message, $context); |
} |
|
/** |
* Adds a log record at the INFO level. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function addInfo($message, array $context = array()) |
{ |
return $this->addRecord(static::INFO, $message, $context); |
} |
|
/** |
* Adds a log record at the NOTICE level. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function addNotice($message, array $context = array()) |
{ |
return $this->addRecord(static::NOTICE, $message, $context); |
} |
|
/** |
* Adds a log record at the WARNING level. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function addWarning($message, array $context = array()) |
{ |
return $this->addRecord(static::WARNING, $message, $context); |
} |
|
/** |
* Adds a log record at the ERROR level. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function addError($message, array $context = array()) |
{ |
return $this->addRecord(static::ERROR, $message, $context); |
} |
|
/** |
* Adds a log record at the CRITICAL level. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function addCritical($message, array $context = array()) |
{ |
return $this->addRecord(static::CRITICAL, $message, $context); |
} |
|
/** |
* Adds a log record at the ALERT level. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function addAlert($message, array $context = array()) |
{ |
return $this->addRecord(static::ALERT, $message, $context); |
} |
|
/** |
* Adds a log record at the EMERGENCY level. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function addEmergency($message, array $context = array()) |
{ |
return $this->addRecord(static::EMERGENCY, $message, $context); |
} |
|
/** |
* Gets all supported logging levels. |
* |
* @return array Assoc array with human-readable level names => level codes. |
*/ |
public static function getLevels() |
{ |
return array_flip(static::$levels); |
} |
|
/** |
* Gets the name of the logging level. |
* |
* @param int $level |
* @return string |
*/ |
public static function getLevelName($level) |
{ |
if (!isset(static::$levels[$level])) { |
throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels))); |
} |
|
return static::$levels[$level]; |
} |
|
/** |
* Converts PSR-3 levels to Monolog ones if necessary |
* |
* @param string|int Level number (monolog) or name (PSR-3) |
* @return int |
*/ |
public static function toMonologLevel($level) |
{ |
if (is_string($level) && defined(__CLASS__.'::'.strtoupper($level))) { |
return constant(__CLASS__.'::'.strtoupper($level)); |
} |
|
return $level; |
} |
|
/** |
* Checks whether the Logger has a handler that listens on the given level |
* |
* @param int $level |
* @return Boolean |
*/ |
public function isHandling($level) |
{ |
$record = array( |
'level' => $level, |
); |
|
foreach ($this->handlers as $handler) { |
if ($handler->isHandling($record)) { |
return true; |
} |
} |
|
return false; |
} |
|
/** |
* Adds a log record at an arbitrary level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param mixed $level The log level |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function log($level, $message, array $context = array()) |
{ |
$level = static::toMonologLevel($level); |
|
return $this->addRecord($level, $message, $context); |
} |
|
/** |
* Adds a log record at the DEBUG level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function debug($message, array $context = array()) |
{ |
return $this->addRecord(static::DEBUG, $message, $context); |
} |
|
/** |
* Adds a log record at the INFO level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function info($message, array $context = array()) |
{ |
return $this->addRecord(static::INFO, $message, $context); |
} |
|
/** |
* Adds a log record at the NOTICE level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function notice($message, array $context = array()) |
{ |
return $this->addRecord(static::NOTICE, $message, $context); |
} |
|
/** |
* Adds a log record at the WARNING level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function warn($message, array $context = array()) |
{ |
return $this->addRecord(static::WARNING, $message, $context); |
} |
|
/** |
* Adds a log record at the WARNING level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function warning($message, array $context = array()) |
{ |
return $this->addRecord(static::WARNING, $message, $context); |
} |
|
/** |
* Adds a log record at the ERROR level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function err($message, array $context = array()) |
{ |
return $this->addRecord(static::ERROR, $message, $context); |
} |
|
/** |
* Adds a log record at the ERROR level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function error($message, array $context = array()) |
{ |
return $this->addRecord(static::ERROR, $message, $context); |
} |
|
/** |
* Adds a log record at the CRITICAL level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function crit($message, array $context = array()) |
{ |
return $this->addRecord(static::CRITICAL, $message, $context); |
} |
|
/** |
* Adds a log record at the CRITICAL level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function critical($message, array $context = array()) |
{ |
return $this->addRecord(static::CRITICAL, $message, $context); |
} |
|
/** |
* Adds a log record at the ALERT level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function alert($message, array $context = array()) |
{ |
return $this->addRecord(static::ALERT, $message, $context); |
} |
|
/** |
* Adds a log record at the EMERGENCY level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function emerg($message, array $context = array()) |
{ |
return $this->addRecord(static::EMERGENCY, $message, $context); |
} |
|
/** |
* Adds a log record at the EMERGENCY level. |
* |
* This method allows for compatibility with common interfaces. |
* |
* @param string $message The log message |
* @param array $context The log context |
* @return Boolean Whether the record has been processed |
*/ |
public function emergency($message, array $context = array()) |
{ |
return $this->addRecord(static::EMERGENCY, $message, $context); |
} |
|
/** |
* Set the timezone to be used for the timestamp of log records. |
* |
* This is stored globally for all Logger instances |
* |
* @param \DateTimeZone $tz Timezone object |
*/ |
public static function setTimezone(\DateTimeZone $tz) |
{ |
self::$timezone = $tz; |
} |
} |