library/log4php/Logger.php
changeset 0 4869aea77e21
equal deleted inserted replaced
-1:000000000000 0:4869aea77e21
       
     1 <?php
       
     2 /**
       
     3  * Licensed to the Apache Software Foundation (ASF) under one or more
       
     4  * contributor license agreements. See the NOTICE file distributed with
       
     5  * this work for additional information regarding copyright ownership.
       
     6  * The ASF licenses this file to You under the Apache License, Version 2.0
       
     7  * (the "License"); you may not use this file except in compliance with
       
     8  * the License. You may obtain a copy of the License at
       
     9  *
       
    10  *        http://www.apache.org/licenses/LICENSE-2.0
       
    11  *
       
    12  * Unless required by applicable law or agreed to in writing, software
       
    13  * distributed under the License is distributed on an "AS IS" BASIS,
       
    14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    15  * See the License for the specific language governing permissions and
       
    16  * limitations under the License.
       
    17  *
       
    18  * @package log4php
       
    19  */
       
    20 
       
    21 require dirname(__FILE__) . '/LoggerAutoloader.php';
       
    22 
       
    23 /**
       
    24  * This is the central class in the log4php package. All logging operations
       
    25  * are done through this class.
       
    26  *
       
    27  * The main logging methods are:
       
    28  *    <ul>
       
    29  *        <li>{@link trace()}</li>
       
    30  *        <li>{@link debug()}</li>
       
    31  *        <li>{@link info()}</li>
       
    32  *        <li>{@link warn()}</li>
       
    33  *        <li>{@link error()}</li>
       
    34  *        <li>{@link fatal()}</li>
       
    35  *    </ul>
       
    36  *
       
    37  * @package    log4php
       
    38  * @license       http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
       
    39  * @version       SVN: $Id: Logger.php 1395241 2012-10-07 08:28:53Z ihabunek $
       
    40  * @link       http://logging.apache.org/log4php
       
    41  */
       
    42 class Logger {
       
    43 
       
    44     /**
       
    45      * Logger additivity. If set to true then child loggers will inherit
       
    46      * the appenders of their ancestors by default.
       
    47      * @var boolean
       
    48      */
       
    49     private $additive = true;
       
    50 
       
    51     /**
       
    52      * The Logger's fully qualified class name.
       
    53      * TODO: Determine if this is useful.
       
    54      */
       
    55     private $fqcn = 'Logger';
       
    56 
       
    57     /** The assigned Logger level. */
       
    58     private $level;
       
    59 
       
    60     /** The name of this Logger instance. */
       
    61     private $name;
       
    62 
       
    63     /** The parent logger. Set to null if this is the root logger. */
       
    64     private $parent;
       
    65 
       
    66     /** A collection of appenders linked to this logger. */
       
    67     private $appenders = array();
       
    68 
       
    69     /**
       
    70      * Constructor.
       
    71      * @param string $name Name of the logger.
       
    72      */
       
    73     public function __construct($name) {
       
    74         $this->name = $name;
       
    75     }
       
    76 
       
    77     /**
       
    78      * Returns the logger name.
       
    79      * @return string
       
    80      */
       
    81     public function getName() {
       
    82         return $this->name;
       
    83     }
       
    84 
       
    85     /**
       
    86      * Returns the parent Logger. Can be null if this is the root logger.
       
    87      * @return Logger
       
    88      */
       
    89     public function getParent() {
       
    90         return $this->parent;
       
    91     }
       
    92 
       
    93     // ******************************************
       
    94     // *** Logging methods                    ***
       
    95     // ******************************************
       
    96 
       
    97     /**
       
    98      * Log a message object with the TRACE level.
       
    99      *
       
   100      * @param mixed $message message
       
   101      * @param Exception $throwable Optional throwable information to include
       
   102      *   in the logging event.
       
   103      */
       
   104     public function trace($message, $throwable = null) {
       
   105         $this->log(LoggerLevel::getLevelTrace(), $message, $throwable);
       
   106     }
       
   107 
       
   108     /**
       
   109      * Log a message object with the DEBUG level.
       
   110      *
       
   111      * @param mixed $message message
       
   112      * @param Exception $throwable Optional throwable information to include
       
   113      *   in the logging event.
       
   114      */
       
   115     public function debug($message, $throwable = null) {
       
   116         $this->log(LoggerLevel::getLevelDebug(), $message, $throwable);
       
   117     }
       
   118 
       
   119     /**
       
   120      * Log a message object with the INFO Level.
       
   121      *
       
   122      * @param mixed $message message
       
   123      * @param Exception $throwable Optional throwable information to include
       
   124      *   in the logging event.
       
   125      */
       
   126     public function info($message, $throwable = null) {
       
   127         $this->log(LoggerLevel::getLevelInfo(), $message, $throwable);
       
   128     }
       
   129 
       
   130     /**
       
   131      * Log a message with the WARN level.
       
   132      *
       
   133      * @param mixed $message message
       
   134      * @param Exception $throwable Optional throwable information to include
       
   135      *   in the logging event.
       
   136      */
       
   137     public function warn($message, $throwable = null) {
       
   138         $this->log(LoggerLevel::getLevelWarn(), $message, $throwable);
       
   139     }
       
   140 
       
   141     /**
       
   142      * Log a message object with the ERROR level.
       
   143      *
       
   144      * @param mixed $message message
       
   145      * @param Exception $throwable Optional throwable information to include
       
   146      *   in the logging event.
       
   147      */
       
   148     public function error($message, $throwable = null) {
       
   149         $this->log(LoggerLevel::getLevelError(), $message, $throwable);
       
   150     }
       
   151 
       
   152     /**
       
   153      * Log a message object with the FATAL level.
       
   154      *
       
   155      * @param mixed $message message
       
   156      * @param Exception $throwable Optional throwable information to include
       
   157      *   in the logging event.
       
   158      */
       
   159     public function fatal($message, $throwable = null) {
       
   160         $this->log(LoggerLevel::getLevelFatal(), $message, $throwable);
       
   161     }
       
   162 
       
   163     /**
       
   164      * Log a message using the provided logging level.
       
   165      *
       
   166      * @param LoggerLevel $level The logging level.
       
   167      * @param mixed $message Message to log.
       
   168      * @param Exception $throwable Optional throwable information to include
       
   169      *   in the logging event.
       
   170      */
       
   171     public function log(LoggerLevel $level, $message, $throwable = null) {
       
   172         if ($this->isEnabledFor($level)) {
       
   173             $event = new LoggerLoggingEvent($this->fqcn, $this, $level, $message, null, $throwable);
       
   174             $this->callAppenders($event);
       
   175         }
       
   176 
       
   177         // Forward the event upstream if additivity is turned on
       
   178         if (isset($this->parent) && $this->getAdditivity()) {
       
   179 
       
   180             // Use the event if already created
       
   181             if (isset($event)) {
       
   182                 $this->parent->logEvent($event);
       
   183             } else {
       
   184                 $this->parent->log($level, $message, $throwable);
       
   185             }
       
   186         }
       
   187     }
       
   188 
       
   189     /**
       
   190      * Logs an already prepared logging event object.
       
   191      * @param LoggerLoggingEvent $event
       
   192      */
       
   193     public function logEvent(LoggerLoggingEvent $event) {
       
   194         if ($this->isEnabledFor($event->getLevel())) {
       
   195             $this->callAppenders($event);
       
   196         }
       
   197 
       
   198         // Forward the event upstream if additivity is turned on
       
   199         if (isset($this->parent) && $this->getAdditivity()) {
       
   200             $this->parent->logEvent($event);
       
   201         }
       
   202     }
       
   203 
       
   204     /**
       
   205      * If assertion parameter evaluates as false, then logs the message
       
   206      * using the ERROR level.
       
   207      *
       
   208      * @param bool $assertion
       
   209      * @param string $msg message to log
       
   210      */
       
   211     public function assertLog($assertion = true, $msg = '') {
       
   212         if ($assertion == false) {
       
   213             $this->error($msg);
       
   214         }
       
   215     }
       
   216 
       
   217     /**
       
   218      * This method creates a new logging event and logs the event without
       
   219      * further checks.
       
   220      *
       
   221      * It should not be called directly. Use {@link trace()}, {@link debug()},
       
   222      * {@link info()}, {@link warn()}, {@link error()} and {@link fatal()}
       
   223      * wrappers.
       
   224      *
       
   225      * @param string $fqcn Fully qualified class name of the Logger
       
   226      * @param Exception $throwable Optional throwable information to include
       
   227      *   in the logging event.
       
   228      * @param LoggerLevel $level log level
       
   229      * @param mixed $message message to log
       
   230      */
       
   231     public function forcedLog($fqcn, $throwable, LoggerLevel $level, $message) {
       
   232         $event = new LoggerLoggingEvent($fqcn, $this, $level, $message, null, $throwable);
       
   233         $this->callAppenders($event);
       
   234 
       
   235         // Forward the event upstream if additivity is turned on
       
   236         if (isset($this->parent) && $this->getAdditivity()) {
       
   237             $this->parent->logEvent($event);
       
   238         }
       
   239     }
       
   240 
       
   241     /**
       
   242      * Forwards the given logging event to all linked appenders.
       
   243      * @param LoggerLoggingEvent $event
       
   244      */
       
   245     public function callAppenders($event) {
       
   246         foreach ($this->appenders as $appender) {
       
   247             $appender->doAppend($event);
       
   248         }
       
   249     }
       
   250 
       
   251     // ******************************************
       
   252     // *** Checker methods                    ***
       
   253     // ******************************************
       
   254 
       
   255     /**
       
   256      * Check whether this Logger is enabled for a given Level passed as parameter.
       
   257      *
       
   258      * @param LoggerLevel level
       
   259      * @return boolean
       
   260      */
       
   261     public function isEnabledFor(LoggerLevel $level) {
       
   262         return $level->isGreaterOrEqual($this->getEffectiveLevel());
       
   263     }
       
   264 
       
   265     /**
       
   266      * Check whether this Logger is enabled for the TRACE Level.
       
   267      * @return boolean
       
   268      */
       
   269     public function isTraceEnabled() {
       
   270         return $this->isEnabledFor(LoggerLevel::getLevelTrace());
       
   271     }
       
   272 
       
   273     /**
       
   274      * Check whether this Logger is enabled for the DEBUG Level.
       
   275      * @return boolean
       
   276      */
       
   277     public function isDebugEnabled() {
       
   278         return $this->isEnabledFor(LoggerLevel::getLevelDebug());
       
   279     }
       
   280 
       
   281     /**
       
   282      * Check whether this Logger is enabled for the INFO Level.
       
   283      * @return boolean
       
   284      */
       
   285     public function isInfoEnabled() {
       
   286         return $this->isEnabledFor(LoggerLevel::getLevelInfo());
       
   287     }
       
   288 
       
   289     /**
       
   290      * Check whether this Logger is enabled for the WARN Level.
       
   291      * @return boolean
       
   292      */
       
   293     public function isWarnEnabled() {
       
   294         return $this->isEnabledFor(LoggerLevel::getLevelWarn());
       
   295     }
       
   296 
       
   297     /**
       
   298      * Check whether this Logger is enabled for the ERROR Level.
       
   299      * @return boolean
       
   300      */
       
   301     public function isErrorEnabled() {
       
   302         return $this->isEnabledFor(LoggerLevel::getLevelError());
       
   303     }
       
   304 
       
   305     /**
       
   306      * Check whether this Logger is enabled for the FATAL Level.
       
   307      * @return boolean
       
   308      */
       
   309     public function isFatalEnabled() {
       
   310         return $this->isEnabledFor(LoggerLevel::getLevelFatal());
       
   311     }
       
   312 
       
   313     // ******************************************
       
   314     // *** Configuration methods              ***
       
   315     // ******************************************
       
   316 
       
   317     /**
       
   318      * Adds a new appender to the Logger.
       
   319      * @param LoggerAppender $appender The appender to add.
       
   320      */
       
   321     public function addAppender($appender) {
       
   322         $appenderName = $appender->getName();
       
   323         $this->appenders[$appenderName] = $appender;
       
   324     }
       
   325 
       
   326     /** Removes all appenders from the Logger. */
       
   327     public function removeAllAppenders() {
       
   328         foreach ($this->appenders as $name => $appender) {
       
   329             $this->removeAppender($name);
       
   330         }
       
   331     }
       
   332 
       
   333     /**
       
   334      * Remove the appender passed as parameter form the Logger.
       
   335      * @param mixed $appender an appender name or a {@link LoggerAppender} instance.
       
   336      */
       
   337     public function removeAppender($appender) {
       
   338         if ($appender instanceof LoggerAppender) {
       
   339             $appender->close();
       
   340             unset($this->appenders[$appender->getName()]);
       
   341         } else if (is_string($appender) and isset($this->appenders[$appender])) {
       
   342             $this->appenders[$appender]->close();
       
   343             unset($this->appenders[$appender]);
       
   344         }
       
   345     }
       
   346 
       
   347     /**
       
   348      * Returns the appenders linked to this logger as an array.
       
   349      * @return array collection of appender names
       
   350      */
       
   351     public function getAllAppenders() {
       
   352         return $this->appenders;
       
   353     }
       
   354 
       
   355     /**
       
   356      * Returns a linked appender by name.
       
   357      * @return LoggerAppender
       
   358      */
       
   359     public function getAppender($name) {
       
   360         return $this->appenders[$name];
       
   361     }
       
   362 
       
   363     /**
       
   364      * Sets the additivity flag.
       
   365      * @param boolean $additive
       
   366      */
       
   367     public function setAdditivity($additive) {
       
   368         $this->additive = (bool)$additive;
       
   369     }
       
   370 
       
   371     /**
       
   372      * Returns the additivity flag.
       
   373      * @return boolean
       
   374      */
       
   375     public function getAdditivity() {
       
   376         return $this->additive;
       
   377     }
       
   378 
       
   379     /**
       
   380      * Starting from this Logger, search the Logger hierarchy for a non-null level and return it.
       
   381      * @see LoggerLevel
       
   382      * @return LoggerLevel or null
       
   383      */
       
   384     public function getEffectiveLevel() {
       
   385         for ($logger = $this; $logger !== null; $logger = $logger->getParent()) {
       
   386             if ($logger->getLevel() !== null) {
       
   387                 return $logger->getLevel();
       
   388             }
       
   389         }
       
   390     }
       
   391 
       
   392     /**
       
   393      * Get the assigned Logger level.
       
   394      * @return LoggerLevel The assigned level or null if none is assigned.
       
   395      */
       
   396     public function getLevel() {
       
   397         return $this->level;
       
   398     }
       
   399 
       
   400     /**
       
   401      * Set the Logger level.
       
   402      *
       
   403      * Use LoggerLevel::getLevelXXX() methods to get a LoggerLevel object, e.g.
       
   404      * <code>$logger->setLevel(LoggerLevel::getLevelInfo());</code>
       
   405      *
       
   406      * @param LoggerLevel $level The level to set, or NULL to clear the logger level.
       
   407      */
       
   408     public function setLevel(LoggerLevel $level = null) {
       
   409         $this->level = $level;
       
   410     }
       
   411 
       
   412     /**
       
   413      * Checks whether an appender is attached to this logger instance.
       
   414      *
       
   415      * @param LoggerAppender $appender
       
   416      * @return boolean
       
   417      */
       
   418     public function isAttached(LoggerAppender $appender) {
       
   419         return isset($this->appenders[$appender->getName()]);
       
   420     }
       
   421 
       
   422     /**
       
   423      * Sets the parent logger.
       
   424      * @param Logger $logger
       
   425      */
       
   426     public function setParent(Logger $logger) {
       
   427         $this->parent = $logger;
       
   428     }
       
   429 
       
   430     // ******************************************
       
   431     // *** Static methods and properties      ***
       
   432     // ******************************************
       
   433 
       
   434     /** The logger hierarchy used by log4php. */
       
   435     private static $hierarchy;
       
   436 
       
   437     /** Inidicates if log4php has been initialized */
       
   438     private static $initialized = false;
       
   439 
       
   440     /**
       
   441      * Returns the hierarchy used by this Logger.
       
   442      *
       
   443      * Caution: do not use this hierarchy unless you have called initialize().
       
   444      * To get Loggers, use the Logger::getLogger and Logger::getRootLogger
       
   445      * methods instead of operating on on the hierarchy directly.
       
   446      *
       
   447      * @return LoggerHierarchy
       
   448      */
       
   449     public static function getHierarchy() {
       
   450         if (!isset(self::$hierarchy)) {
       
   451             self::$hierarchy = new LoggerHierarchy(new LoggerRoot());
       
   452         }
       
   453         return self::$hierarchy;
       
   454     }
       
   455 
       
   456     /**
       
   457      * Returns a Logger by name. If it does not exist, it will be created.
       
   458      *
       
   459      * @param string $name The logger name
       
   460      * @return Logger
       
   461      */
       
   462     public static function getLogger($name) {
       
   463         if (!self::isInitialized()) {
       
   464             self::configure();
       
   465         }
       
   466         return self::getHierarchy()->getLogger($name);
       
   467     }
       
   468 
       
   469     /**
       
   470      * Returns the Root Logger.
       
   471      * @return LoggerRoot
       
   472      */
       
   473     public static function getRootLogger() {
       
   474         if (!self::isInitialized()) {
       
   475             self::configure();
       
   476         }
       
   477         return self::getHierarchy()->getRootLogger();
       
   478     }
       
   479 
       
   480     /**
       
   481      * Clears all Logger definitions from the logger hierarchy.
       
   482      * @return boolean
       
   483      */
       
   484     public static function clear() {
       
   485         return self::getHierarchy()->clear();
       
   486     }
       
   487 
       
   488     /**
       
   489      * Destroy configurations for logger definitions
       
   490      */
       
   491     public static function resetConfiguration() {
       
   492         self::getHierarchy()->resetConfiguration();
       
   493         self::getHierarchy()->clear(); // TODO: clear or not?
       
   494         self::$initialized = false;
       
   495     }
       
   496 
       
   497     /**
       
   498      * Safely close all appenders.
       
   499      * @deprecated This is no longer necessary due the appenders shutdown via
       
   500      * destructors.
       
   501      */
       
   502     public static function shutdown() {
       
   503         return self::getHierarchy()->shutdown();
       
   504     }
       
   505 
       
   506     /**
       
   507      * check if a given logger exists.
       
   508      *
       
   509      * @param string $name logger name
       
   510      * @return boolean
       
   511      */
       
   512     public static function exists($name) {
       
   513         return self::getHierarchy()->exists($name);
       
   514     }
       
   515 
       
   516     /**
       
   517      * Returns an array this whole Logger instances.
       
   518      * @see Logger
       
   519      * @return array
       
   520      */
       
   521     public static function getCurrentLoggers() {
       
   522         return self::getHierarchy()->getCurrentLoggers();
       
   523     }
       
   524 
       
   525     /**
       
   526      * Configures log4php.
       
   527      *
       
   528      * This method needs to be called before the first logging event has
       
   529      * occured. If this method is not called before then the default
       
   530      * configuration will be used.
       
   531      *
       
   532      * @param string|array $configuration Either a path to the configuration
       
   533      *   file, or a configuration array.
       
   534      *
       
   535      * @param string|LoggerConfigurator $configurator A custom
       
   536      * configurator class: either a class name (string), or an object which
       
   537      * implements the LoggerConfigurator interface. If left empty, the default
       
   538      * configurator implementation will be used.
       
   539      */
       
   540     public static function configure($configuration = null, $configurator = null) {
       
   541         self::resetConfiguration();
       
   542         $configurator = self::getConfigurator($configurator);
       
   543         $configurator->configure(self::getHierarchy(), $configuration);
       
   544         self::$initialized = true;
       
   545     }
       
   546 
       
   547     /**
       
   548      * Creates a logger configurator instance based on the provided
       
   549      * configurator class. If no class is given, returns an instance of
       
   550      * the default configurator.
       
   551      *
       
   552      * @param string|LoggerConfigurator $configurator The configurator class
       
   553      * or LoggerConfigurator instance.
       
   554      */
       
   555     private static function getConfigurator($configurator = null) {
       
   556         if ($configurator === null) {
       
   557             return new LoggerConfiguratorDefault();
       
   558         }
       
   559 
       
   560         if (is_object($configurator)) {
       
   561             if ($configurator instanceof LoggerConfigurator) {
       
   562                 return $configurator;
       
   563             } else {
       
   564                 trigger_error("log4php: Given configurator object [$configurator] does not implement the LoggerConfigurator interface. Reverting to default configurator.", E_USER_WARNING);
       
   565                 return new LoggerConfiguratorDefault();
       
   566             }
       
   567         }
       
   568 
       
   569         if (is_string($configurator)) {
       
   570             if (!class_exists($configurator)) {
       
   571                 trigger_error("log4php: Specified configurator class [$configurator] does not exist. Reverting to default configurator.", E_USER_WARNING);
       
   572                 return new LoggerConfiguratorDefault();
       
   573             }
       
   574 
       
   575             $instance = new $configurator();
       
   576 
       
   577             if (!($instance instanceof LoggerConfigurator)) {
       
   578                 trigger_error("log4php: Specified configurator class [$configurator] does not implement the LoggerConfigurator interface. Reverting to default configurator.", E_USER_WARNING);
       
   579                 return new LoggerConfiguratorDefault();
       
   580             }
       
   581 
       
   582             return $instance;
       
   583         }
       
   584 
       
   585         trigger_error("log4php: Invalid configurator specified. Expected either a string or a LoggerConfigurator instance. Reverting to default configurator.", E_USER_WARNING);
       
   586         return new LoggerConfiguratorDefault();
       
   587     }
       
   588 
       
   589     /**
       
   590      * Returns true if the log4php framework has been initialized.
       
   591      * @return boolean
       
   592      */
       
   593     private static function isInitialized() {
       
   594         return self::$initialized;
       
   595     }
       
   596 }