| <?php |
| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| namespace Apache\Log4php; |
| |
| /** |
| * This is the central class in the log4php package. All logging operations |
| * are done through this class. |
| * |
| * The main logging methods are: |
| * <ul> |
| * <li>{@link trace()}</li> |
| * <li>{@link debug()}</li> |
| * <li>{@link info()}</li> |
| * <li>{@link warn()}</li> |
| * <li>{@link error()}</li> |
| * <li>{@link fatal()}</li> |
| * </ul> |
| * |
| * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 |
| * @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(Level::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(Level::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(Level::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(Level::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(Level::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(Level::getLevelFatal(), $message, $throwable); |
| } |
| |
| /** |
| * Log a message using the provided logging level. |
| * |
| * @param Level $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(Level $level, $message, $throwable = null) |
| { |
| if ($this->isEnabledFor($level)) { |
| $event = new LoggingEvent($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 LoggingEvent $event |
| */ |
| public function logEvent(LoggingEvent $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 Level $level log level |
| * @param mixed $message message to log |
| */ |
| public function forcedLog($fqcn, $throwable, Level $level, $message) |
| { |
| $event = new LoggingEvent($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 LoggingEvent $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 Level level |
| * @return boolean |
| */ |
| public function isEnabledFor(Level $level) |
| { |
| return $level->isGreaterOrEqual($this->getEffectiveLevel()); |
| } |
| |
| /** |
| * Check whether this Logger is enabled for the TRACE Level. |
| * @return boolean |
| */ |
| public function isTraceEnabled() |
| { |
| return $this->isEnabledFor(Level::getLevelTrace()); |
| } |
| |
| /** |
| * Check whether this Logger is enabled for the DEBUG Level. |
| * @return boolean |
| */ |
| public function isDebugEnabled() |
| { |
| return $this->isEnabledFor(Level::getLevelDebug()); |
| } |
| |
| /** |
| * Check whether this Logger is enabled for the INFO Level. |
| * @return boolean |
| */ |
| public function isInfoEnabled() |
| { |
| return $this->isEnabledFor(Level::getLevelInfo()); |
| } |
| |
| /** |
| * Check whether this Logger is enabled for the WARN Level. |
| * @return boolean |
| */ |
| public function isWarnEnabled() |
| { |
| return $this->isEnabledFor(Level::getLevelWarn()); |
| } |
| |
| /** |
| * Check whether this Logger is enabled for the ERROR Level. |
| * @return boolean |
| */ |
| public function isErrorEnabled() |
| { |
| return $this->isEnabledFor(Level::getLevelError()); |
| } |
| |
| /** |
| * Check whether this Logger is enabled for the FATAL Level. |
| * @return boolean |
| */ |
| public function isFatalEnabled() |
| { |
| return $this->isEnabledFor(Level::getLevelFatal()); |
| } |
| |
| // ****************************************** |
| // *** Configuration methods *** |
| // ****************************************** |
| |
| /** |
| * Adds a new appender to the Logger. |
| * @param Appender $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 Appender} instance. |
| */ |
| public function removeAppender($appender) |
| { |
| if ($appender instanceof Appender) { |
| $appender->close(); |
| unset($this->appenders[$appender->getName()]); |
| } elseif (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 Appender |
| */ |
| 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 Level |
| * @return Level 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 Level The assigned level or null if none is assigned. |
| */ |
| public function getLevel() |
| { |
| return $this->level; |
| } |
| |
| /** |
| * Set the Logger level. |
| * |
| * Use Level::getLevelXXX() methods to get a Level object, e.g. |
| * <code>$logger->setLevel(Level::getLevelInfo());</code> |
| * |
| * @param Level $level The level to set, or NULL to clear the logger level. |
| */ |
| public function setLevel(Level $level = null) |
| { |
| $this->level = $level; |
| } |
| |
| /** |
| * Checks whether an appender is attached to this logger instance. |
| * |
| * @param Appender $appender |
| * @return boolean |
| */ |
| public function isAttached(Appender $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 Hierarchy |
| */ |
| public static function getHierarchy() |
| { |
| if (!isset(self::$hierarchy)) { |
| self::$hierarchy = new Hierarchy(new RootLogger()); |
| } |
| |
| 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 RootLogger |
| */ |
| 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|Configurator $configurator A custom |
| * configurator class: either a class name (string) , or an object which |
| * implements the Configurator 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|Configurator $configurator The configurator class |
| * or Configurator instance. |
| */ |
| private static function getConfigurator($configurator = null) |
| { |
| if ($configurator === null) { |
| return new Configuration\DefaultConfigurator(); |
| } |
| |
| if (is_object($configurator)) { |
| if ($configurator instanceof Configurator) { |
| return $configurator; |
| } else { |
| trigger_error( |
| "log4php: Given configurator object [$configurator] does not implement Configurator interface. " . |
| "Reverting to default configurator.", |
| E_USER_WARNING |
| ); |
| |
| return new Configuration\DefaultConfigurator(); |
| } |
| } |
| |
| if (is_string($configurator)) { |
| if (!class_exists($configurator)) { |
| trigger_error( |
| "log4php: Given configurator class [$configurator] does not exist. " . |
| "Reverting to default configurator.", |
| E_USER_WARNING |
| ); |
| |
| return new Configuration\DefaultConfigurator(); |
| } |
| |
| $instance = new $configurator(); |
| |
| if (!($instance instanceof Configurator)) { |
| trigger_error( |
| "log4php: Specified configurator class [$configurator] does not implement Configurator interface." . |
| " Reverting to default configurator.", |
| E_USER_WARNING |
| ); |
| |
| return new Configuration\DefaultConfigurator(); |
| } |
| |
| return $instance; |
| } |
| |
| trigger_error( |
| "log4php: Invalid configurator specified. Expected either a string or a Configurator instance. " . |
| "Reverting to default configurator.", |
| E_USER_WARNING |
| ); |
| |
| return new Configuration\DefaultConfigurator(); |
| } |
| |
| /** |
| * Returns true if the log4php framework has been initialized. |
| * @return boolean |
| */ |
| private static function isInitialized() |
| { |
| return self::$initialized; |
| } |
| } |