diff --git a/library/log4php/Logger.php b/library/log4php/Logger.php new file mode 100644 --- /dev/null +++ b/library/log4php/Logger.php @@ -0,0 +1,596 @@ + + *
  • {@link trace()}
  • + *
  • {@link debug()}
  • + *
  • {@link info()}
  • + *
  • {@link warn()}
  • + *
  • {@link error()}
  • + *
  • {@link fatal()}
  • + * + * + * @package log4php + * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 + * @version SVN: $Id: Logger.php 1395241 2012-10-07 08:28:53Z ihabunek $ + * @link http://logging.apache.org/log4php + */ +class Logger { + + /** + * Logger additivity. If set to true then child loggers will inherit + * the appenders of their ancestors by default. + * @var boolean + */ + private $additive = true; + + /** + * The Logger's fully qualified class name. + * TODO: Determine if this is useful. + */ + private $fqcn = 'Logger'; + + /** The assigned Logger level. */ + private $level; + + /** The name of this Logger instance. */ + private $name; + + /** The parent logger. Set to null if this is the root logger. */ + private $parent; + + /** A collection of appenders linked to this logger. */ + private $appenders = array(); + + /** + * Constructor. + * @param string $name Name of the logger. + */ + public function __construct($name) { + $this->name = $name; + } + + /** + * Returns the logger name. + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * Returns the parent Logger. Can be null if this is the root logger. + * @return Logger + */ + public function getParent() { + return $this->parent; + } + + // ****************************************** + // *** Logging methods *** + // ****************************************** + + /** + * Log a message object with the TRACE level. + * + * @param mixed $message message + * @param Exception $throwable Optional throwable information to include + * in the logging event. + */ + public function trace($message, $throwable = null) { + $this->log(LoggerLevel::getLevelTrace(), $message, $throwable); + } + + /** + * Log a message object with the DEBUG level. + * + * @param mixed $message message + * @param Exception $throwable Optional throwable information to include + * in the logging event. + */ + public function debug($message, $throwable = null) { + $this->log(LoggerLevel::getLevelDebug(), $message, $throwable); + } + + /** + * Log a message object with the INFO Level. + * + * @param mixed $message message + * @param Exception $throwable Optional throwable information to include + * in the logging event. + */ + public function info($message, $throwable = null) { + $this->log(LoggerLevel::getLevelInfo(), $message, $throwable); + } + + /** + * Log a message with the WARN level. + * + * @param mixed $message message + * @param Exception $throwable Optional throwable information to include + * in the logging event. + */ + public function warn($message, $throwable = null) { + $this->log(LoggerLevel::getLevelWarn(), $message, $throwable); + } + + /** + * Log a message object with the ERROR level. + * + * @param mixed $message message + * @param Exception $throwable Optional throwable information to include + * in the logging event. + */ + public function error($message, $throwable = null) { + $this->log(LoggerLevel::getLevelError(), $message, $throwable); + } + + /** + * Log a message object with the FATAL level. + * + * @param mixed $message message + * @param Exception $throwable Optional throwable information to include + * in the logging event. + */ + public function fatal($message, $throwable = null) { + $this->log(LoggerLevel::getLevelFatal(), $message, $throwable); + } + + /** + * Log a message using the provided logging level. + * + * @param LoggerLevel $level The logging level. + * @param mixed $message Message to log. + * @param Exception $throwable Optional throwable information to include + * in the logging event. + */ + public function log(LoggerLevel $level, $message, $throwable = null) { + if ($this->isEnabledFor($level)) { + $event = new LoggerLoggingEvent($this->fqcn, $this, $level, $message, null, $throwable); + $this->callAppenders($event); + } + + // Forward the event upstream if additivity is turned on + if (isset($this->parent) && $this->getAdditivity()) { + + // Use the event if already created + if (isset($event)) { + $this->parent->logEvent($event); + } else { + $this->parent->log($level, $message, $throwable); + } + } + } + + /** + * Logs an already prepared logging event object. + * @param LoggerLoggingEvent $event + */ + public function logEvent(LoggerLoggingEvent $event) { + if ($this->isEnabledFor($event->getLevel())) { + $this->callAppenders($event); + } + + // Forward the event upstream if additivity is turned on + if (isset($this->parent) && $this->getAdditivity()) { + $this->parent->logEvent($event); + } + } + + /** + * If assertion parameter evaluates as false, then logs the message + * using the ERROR level. + * + * @param bool $assertion + * @param string $msg message to log + */ + public function assertLog($assertion = true, $msg = '') { + if ($assertion == false) { + $this->error($msg); + } + } + + /** + * This method creates a new logging event and logs the event without + * further checks. + * + * It should not be called directly. Use {@link trace()}, {@link debug()}, + * {@link info()}, {@link warn()}, {@link error()} and {@link fatal()} + * wrappers. + * + * @param string $fqcn Fully qualified class name of the Logger + * @param Exception $throwable Optional throwable information to include + * in the logging event. + * @param LoggerLevel $level log level + * @param mixed $message message to log + */ + public function forcedLog($fqcn, $throwable, LoggerLevel $level, $message) { + $event = new LoggerLoggingEvent($fqcn, $this, $level, $message, null, $throwable); + $this->callAppenders($event); + + // Forward the event upstream if additivity is turned on + if (isset($this->parent) && $this->getAdditivity()) { + $this->parent->logEvent($event); + } + } + + /** + * Forwards the given logging event to all linked appenders. + * @param LoggerLoggingEvent $event + */ + public function callAppenders($event) { + foreach ($this->appenders as $appender) { + $appender->doAppend($event); + } + } + + // ****************************************** + // *** Checker methods *** + // ****************************************** + + /** + * Check whether this Logger is enabled for a given Level passed as parameter. + * + * @param LoggerLevel level + * @return boolean + */ + public function isEnabledFor(LoggerLevel $level) { + return $level->isGreaterOrEqual($this->getEffectiveLevel()); + } + + /** + * Check whether this Logger is enabled for the TRACE Level. + * @return boolean + */ + public function isTraceEnabled() { + return $this->isEnabledFor(LoggerLevel::getLevelTrace()); + } + + /** + * Check whether this Logger is enabled for the DEBUG Level. + * @return boolean + */ + public function isDebugEnabled() { + return $this->isEnabledFor(LoggerLevel::getLevelDebug()); + } + + /** + * Check whether this Logger is enabled for the INFO Level. + * @return boolean + */ + public function isInfoEnabled() { + return $this->isEnabledFor(LoggerLevel::getLevelInfo()); + } + + /** + * Check whether this Logger is enabled for the WARN Level. + * @return boolean + */ + public function isWarnEnabled() { + return $this->isEnabledFor(LoggerLevel::getLevelWarn()); + } + + /** + * Check whether this Logger is enabled for the ERROR Level. + * @return boolean + */ + public function isErrorEnabled() { + return $this->isEnabledFor(LoggerLevel::getLevelError()); + } + + /** + * Check whether this Logger is enabled for the FATAL Level. + * @return boolean + */ + public function isFatalEnabled() { + return $this->isEnabledFor(LoggerLevel::getLevelFatal()); + } + + // ****************************************** + // *** Configuration methods *** + // ****************************************** + + /** + * Adds a new appender to the Logger. + * @param LoggerAppender $appender The appender to add. + */ + public function addAppender($appender) { + $appenderName = $appender->getName(); + $this->appenders[$appenderName] = $appender; + } + + /** Removes all appenders from the Logger. */ + public function removeAllAppenders() { + foreach ($this->appenders as $name => $appender) { + $this->removeAppender($name); + } + } + + /** + * Remove the appender passed as parameter form the Logger. + * @param mixed $appender an appender name or a {@link LoggerAppender} instance. + */ + public function removeAppender($appender) { + if ($appender instanceof LoggerAppender) { + $appender->close(); + unset($this->appenders[$appender->getName()]); + } else if (is_string($appender) and isset($this->appenders[$appender])) { + $this->appenders[$appender]->close(); + unset($this->appenders[$appender]); + } + } + + /** + * Returns the appenders linked to this logger as an array. + * @return array collection of appender names + */ + public function getAllAppenders() { + return $this->appenders; + } + + /** + * Returns a linked appender by name. + * @return LoggerAppender + */ + public function getAppender($name) { + return $this->appenders[$name]; + } + + /** + * Sets the additivity flag. + * @param boolean $additive + */ + public function setAdditivity($additive) { + $this->additive = (bool)$additive; + } + + /** + * Returns the additivity flag. + * @return boolean + */ + public function getAdditivity() { + return $this->additive; + } + + /** + * Starting from this Logger, search the Logger hierarchy for a non-null level and return it. + * @see LoggerLevel + * @return LoggerLevel or null + */ + public function getEffectiveLevel() { + for ($logger = $this; $logger !== null; $logger = $logger->getParent()) { + if ($logger->getLevel() !== null) { + return $logger->getLevel(); + } + } + } + + /** + * Get the assigned Logger level. + * @return LoggerLevel The assigned level or null if none is assigned. + */ + public function getLevel() { + return $this->level; + } + + /** + * Set the Logger level. + * + * Use LoggerLevel::getLevelXXX() methods to get a LoggerLevel object, e.g. + * $logger->setLevel(LoggerLevel::getLevelInfo()); + * + * @param LoggerLevel $level The level to set, or NULL to clear the logger level. + */ + public function setLevel(LoggerLevel $level = null) { + $this->level = $level; + } + + /** + * Checks whether an appender is attached to this logger instance. + * + * @param LoggerAppender $appender + * @return boolean + */ + public function isAttached(LoggerAppender $appender) { + return isset($this->appenders[$appender->getName()]); + } + + /** + * Sets the parent logger. + * @param Logger $logger + */ + public function setParent(Logger $logger) { + $this->parent = $logger; + } + + // ****************************************** + // *** Static methods and properties *** + // ****************************************** + + /** The logger hierarchy used by log4php. */ + private static $hierarchy; + + /** Inidicates if log4php has been initialized */ + private static $initialized = false; + + /** + * Returns the hierarchy used by this Logger. + * + * Caution: do not use this hierarchy unless you have called initialize(). + * To get Loggers, use the Logger::getLogger and Logger::getRootLogger + * methods instead of operating on on the hierarchy directly. + * + * @return LoggerHierarchy + */ + public static function getHierarchy() { + if (!isset(self::$hierarchy)) { + self::$hierarchy = new LoggerHierarchy(new LoggerRoot()); + } + return self::$hierarchy; + } + + /** + * Returns a Logger by name. If it does not exist, it will be created. + * + * @param string $name The logger name + * @return Logger + */ + public static function getLogger($name) { + if (!self::isInitialized()) { + self::configure(); + } + return self::getHierarchy()->getLogger($name); + } + + /** + * Returns the Root Logger. + * @return LoggerRoot + */ + public static function getRootLogger() { + if (!self::isInitialized()) { + self::configure(); + } + return self::getHierarchy()->getRootLogger(); + } + + /** + * Clears all Logger definitions from the logger hierarchy. + * @return boolean + */ + public static function clear() { + return self::getHierarchy()->clear(); + } + + /** + * Destroy configurations for logger definitions + */ + public static function resetConfiguration() { + self::getHierarchy()->resetConfiguration(); + self::getHierarchy()->clear(); // TODO: clear or not? + self::$initialized = false; + } + + /** + * Safely close all appenders. + * @deprecated This is no longer necessary due the appenders shutdown via + * destructors. + */ + public static function shutdown() { + return self::getHierarchy()->shutdown(); + } + + /** + * check if a given logger exists. + * + * @param string $name logger name + * @return boolean + */ + public static function exists($name) { + return self::getHierarchy()->exists($name); + } + + /** + * Returns an array this whole Logger instances. + * @see Logger + * @return array + */ + public static function getCurrentLoggers() { + return self::getHierarchy()->getCurrentLoggers(); + } + + /** + * Configures log4php. + * + * This method needs to be called before the first logging event has + * occured. If this method is not called before then the default + * configuration will be used. + * + * @param string|array $configuration Either a path to the configuration + * file, or a configuration array. + * + * @param string|LoggerConfigurator $configurator A custom + * configurator class: either a class name (string), or an object which + * implements the LoggerConfigurator interface. If left empty, the default + * configurator implementation will be used. + */ + public static function configure($configuration = null, $configurator = null) { + self::resetConfiguration(); + $configurator = self::getConfigurator($configurator); + $configurator->configure(self::getHierarchy(), $configuration); + self::$initialized = true; + } + + /** + * Creates a logger configurator instance based on the provided + * configurator class. If no class is given, returns an instance of + * the default configurator. + * + * @param string|LoggerConfigurator $configurator The configurator class + * or LoggerConfigurator instance. + */ + private static function getConfigurator($configurator = null) { + if ($configurator === null) { + return new LoggerConfiguratorDefault(); + } + + if (is_object($configurator)) { + if ($configurator instanceof LoggerConfigurator) { + return $configurator; + } else { + trigger_error("log4php: Given configurator object [$configurator] does not implement the LoggerConfigurator interface. Reverting to default configurator.", E_USER_WARNING); + return new LoggerConfiguratorDefault(); + } + } + + if (is_string($configurator)) { + if (!class_exists($configurator)) { + trigger_error("log4php: Specified configurator class [$configurator] does not exist. Reverting to default configurator.", E_USER_WARNING); + return new LoggerConfiguratorDefault(); + } + + $instance = new $configurator(); + + if (!($instance instanceof LoggerConfigurator)) { + trigger_error("log4php: Specified configurator class [$configurator] does not implement the LoggerConfigurator interface. Reverting to default configurator.", E_USER_WARNING); + return new LoggerConfiguratorDefault(); + } + + return $instance; + } + + trigger_error("log4php: Invalid configurator specified. Expected either a string or a LoggerConfigurator instance. Reverting to default configurator.", E_USER_WARNING); + return new LoggerConfiguratorDefault(); + } + + /** + * Returns true if the log4php framework has been initialized. + * @return boolean + */ + private static function isInitialized() { + return self::$initialized; + } +}