<?php
/**
 * File containing the ezcLog class.
 *
 * 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.
 *
 * @package EventLog
 * @version //autogentag//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * The ezcLog class records log messages and audit trails to one or multiple
 * writers.
 *
 * Available writers are:
 * - {@link ezcLogUnixFileWriter Unix File} writer
 * - {@link ezcLogDatabaseWriter Database} writer
 *
 * Extra writers can be added by implementing the {@link ezcLogWriter} interface.
 *
 * Use the {@link getMapper()} method to get an instance of the ezcLogMapper.
 * The ezcLogMapper classes specifies incoming log messages with the {@link ezcLogFilter}.
 * Log messages that are accepted, match with the filter, are sent to the
 * {@link ezcLogWriter}.
 *
 * The following example demonstrates how all log messages, except for the
 * audit trailing and debug messages, are written to a file.
 * <code>
 * $filter = new ezcLogFilter();
 * $filter->severity = ezcLog::INFO | ezcLog::NOTICE | ezcLog::WARNING | ezcLog::ERROR | ezcLog::FATAL;
 *
 * $log = ezcLog::getInstance();
 * $log->getMapper()->appendRule( new ezcLogFilterRule( $filter, new ezcLogUnixFileWriter( "/tmp/logs/", "error.log" ), true ) );
 * </code>
 *
 * The log messages with the severity: INFO, NOTICE, WARNING, ERROR, and FATAL will
 * be written to the file: "/tmp/logs/error.log". See {@link ezcLogUnixFileWriter} for
 * the description of the file format.
 *
 * The following example will write the audit trails to the database:
 * <code>
 * $filter = new ezcLogFilter();
 * $filter->severity = ezcLog::SUCCESS_AUDIT | ezcLog::FAILED_AUDIT;
 *
 * $log = ezcLog::getInstance();
 * $log->getMapper()->appendRule( new ezcLogFilterRule( $filter, new ezcLogDatabaseWriter( "audits" ), true ) );
 * </code>
 *
 * The audit trails will be stored in the table "audits". See {@link ezcLogDatabaseWriter}
 * for creating the appropriate tables and setting up the database. See the {@link ezcLogFilter}
 * for more details.
 *
 * Use the {@link log()} method to log messages at the specified writers. This
 * method expects a:
 * - Message, contains a single log message.
 * - Severity, indicates the level of importance.
 * - Extra attributes (optional).
 *
 * Although the interpretation of the severity levels are up to the programmer,
 * the most common interpretations are:
 * - DEBUG: Records information about the progress in the program and references
 *   source code functions. Knowledge of the source code is needed to interpret
 *   this log message.
 * - INFO: Informative logging at a detailed level. This logging method produces a
 *   high level of logging, which is unmanageable on a production environment.
 *   Usually INFO logging is only enabled to help by analysing a problem.
 * - NOTICE: Informative logging at a lower detail level than INFO logging.
 *   Only major stages are recorded and is useful to monitor a low volume system.
 * - WARNING: Something unexpected happened, but did not cause any loss of service.
 * - ERROR: An error occured, which may cause partial loss of service. Usually the
 *   system can recover.
 * - FATAL: An serious error occured and the system is unlikely to recover.
 * - SUCCESS_AUDIT: Informative logging about a successful completion of work by
 *   a module completed. Useful to trace system changes directly or indirectly
 *   done by a user.
 * - FAILED_AUDIT: Informative logging about an action from a module
 *   with a negative result. A failed login will most likely added to this severity.
 *
 * The next example logs a fatal error and has no extra attributes:
 * <code>
 * ezcLog::getInstance()->log( "Cannot open ini file: <$file>", ezcLog::FATAL );
 * </code>
 *
 * The log message will get by default the category and source: "default". The
 * default values can be modified by changing, respectively, the properties
 * $category and $source.
 *
 * An example of a Payment checker is as follows:
 * <code>
 * // The start of the Payment module.
 * $log = ezcLog::getInstance();
 * $log->source = "Payment checker"; // Change the default source.
 *
 * $log->log( "Checking the received amount", ezcLog::INFO, array( "shop" ) );
 *
 * if ( !$eZPay->receivedAmount() != $requiredAmount )
 * {
 *     $log->log( "Received amount: <".$eZPay->receivedAmount()."> expected: <$requiredAmount>.",
 *                 ezcLog::DEBUG,
 *                 array( "category" => "shop", "file" => __FILE__, "line" => __LINE )
 *              );
 *
 *     $log->log( "Insufficient amount.",
 *                ezcLog::FAILED_AUDIT,
 *                array( "UserName" => getCurrentUser(), category => "Payment" )
 *              )
 *
 *     $log->log( "Rollback amount not implemented, cannot recover, ezcLog::FATAL );
 *     exit();
 * }
 * </code>
 *
 * Sometimes information repeats for specific severities or categories. For example that
 * for the audit trails an username is required. Convenience methods like:
 * {@link setSeverityAttributes()} and {@link setSourceAttributes()} exist to append
 * information automatically to the log message.
 *
 * The ezcLog class provides a {@link trigger_error()} log handler: {@link ezcLog::logHandler()}.
 * Using the trigger_error method makes your code less Log package dependent and
 * produces less overhead when logging is disabled.
 *
 * See the {@link ezcLog::logHandler()} method for more information about how to set up the
 * trigger_error functionality.
 *
 * See the {@link ezcDebug} package for more detailed information about writing DEBUG
 * messages.
 *
 * @property string $source
 *           Definition of the global location where the log message comes
 *           from.  Some examples are: module, source file, extension, etc. The
 *           source depends also on the severity of the message. For DEBUG
 *           messages is the source file more important whereas for a FATAL
 *           error the module is sufficient.
 * @property string $category
 *           Definition of the message group. Again the category is related to
 *           the severity. The non audit trails can group the log messages
 *           like: Database (or even the database types), Templates, etc. For
 *           audit trails it makes much sense to categorize the actions. For
 *           example: security, modified content, published content, shop, etc.
 *
 * @package EventLog
 * @version //autogentag//
 * @mainclass
 */
class ezcLog
{
    /**
     * Debug severity constant.
     */
     const DEBUG          = 1;

    /**
     * Success audit severity constant.
     */
     const SUCCESS_AUDIT  = 2;

    /**
     * Failed audit severity constant.
     */
     const FAILED_AUDIT   = 4;

     /**
      * Info severity constant.
      */
     const INFO           = 8;

     /**
      * Notice severity constant.
      */
     const NOTICE         = 16;

     /**
      * Warning severity constant.
      */
     const WARNING        = 32;

     /**
      * Error severity constant.
      */
     const ERROR          = 64;

     /**
      * Fatal severity constant.
      */
     const FATAL          = 128;

    /**
     * Holds the properties of this class.
     *
     * @var array(string=>mixed)
     */
    private $properties = array();

    /**
     * Contains the logic of mapping an incoming log message to the writer.
     *
     * @var ezcLogFilterSet
     */
    protected $writers;

    /**
     * Stores the attributes from the eventTypes and eventSources.
     *
     * $var ezcLogContext
     */
    protected $context;

    /**
     * Stores the instance of this class.
     *
     * @var ezcLog
     */
    private static $instance = null;

    /**
     * Stores the setting whether writer exceptions should be thrown.
     *
     * @var bool
     */
    private $throwWriterExceptions = true;

    /**
     * Constructs an empty ezcLog instance.
     *
     * This constructor is private as this class should be used as a
     * singleton. Use the getInstance() method instead to get an ezcLog instance.
     */
    private function __construct()
    {
        $this->reset();
    }

    /**
     * Returns the instance of the class.
     *
     * @return ezcLog
     */
    public static function getInstance()
    {
        if ( is_null( self::$instance ) )
        {
            self::$instance = new self();
            ezcBaseInit::fetchConfig( 'ezcInitLog', self::$instance );
        }
        return self::$instance;
    }

    /**
     * Sets the property $name to $value.
     *
     * @throws ezcBasePropertyNotFoundException
     *         If the property $name does not exist
     * @param string $name
     * @param mixed $value
     * @ignore
     */
    public function __set( $name, $value )
    {
        switch ( $name )
        {
            case "source":
            case "category":
                $this->properties[$name] = $value;
                return;
        }

        throw new ezcBasePropertyNotFoundException( $name );
    }

    /**
     * Returns the property $name.
     *
     * @throws ezcBasePropertyNotFoundException
     *         If the property $name does not exist
     * @param string $name
     * @return mixed
     * @ignore
     */
    public function __get( $name )
    {
        switch ( $name )
        {
            case "source":
            case "category":
                return $this->properties[$name];
        }

        throw new ezcBasePropertyNotFoundException( $name );
    }

    /**
     * Returns true if the property $name is set, otherwise false.
     *
     * @param string $name
     * @return bool
     * @ignore
     */
    public function __isset( $name )
    {
        switch ( $name )
        {
            case 'source':
            case 'category':
                return isset( $this->properties[$name] );

            default:
                return false;
        }
    }

    /**
     * Resets the log instance to its initial state.
     *
     * All sourceAttributes, severityAttributes, and writers will be removed.
     * The default source and category are also reset.
     */
    public function reset()
    {
        $this->writers = new ezcLogFilterSet();
        $this->context = new ezcLogContext();

        $this->setDefaults();
    }

    /**
     * Sets the given ezcLogMapper $mapper as the log message to writer map.
     *
     * By default the ezcLogFilterSet is the default writer map. The default
     * ezcLogMapper can be replaced with this method.
     *
     * @param ezcLogMapper $mapper
     */
    public function setMapper( ezcLogMapper $mapper )
    {
        $this->writers = $mapper;
    }

    /**
     * Returns an instance of the current ezcLogMapper.
     *
     * @return ezcLogMapper
     */
    public function getMapper()
    {
        return $this->writers;
    }

    /**
     * Sets the source and category defaults to "default".
     */
    protected function setDefaults()
    {
        $this->properties['source'] = "default";
        $this->properties['category'] = "default";
    }

    /**
     * Enables or disables writer exceptions with the boolean $enable.
     *
     * Typically you want to have exceptions enabled while developing your application
     * in order to catch potential problems. A live server however, should not throw
     * a deadly exception when a relatively unimportant debug message could not be written to
     * the log file. For these setups you can disable writer exceptions.
     *
     * @param bool $enable
     */
    public function throwWriterExceptions( $enable )
    {
        $this->throwWriterExceptions = $enable;
    }

    /**
     * Write the message $message with additional information to one or multiple log writers.
     *
     * The log message $message, severity $severity, and extra attributes $attributes are sent to
     * the writers that matches with the {@link ezcLogFilter}. The following parameters are
     * taken in the comparation with the ezcLogFilter:
     * - $severity: the severity of the log message.
     * - $attributes[ "source" ]: the source from where the log message comes.
     * - $attributes[ "category" ]: the category of the log message.
     *
     * See for more information about filter matching the classes {@link ezcLog} and
     * {@link ezcLogFilter}.
     *
     * The message $message describes what happened. The severity $severity is one of the ezcLog constants:
     * - DEBUG: Records information about the progress in the program and references
     *   source code functions. Knowledge of the source code is needed to interpret
     *   this log message.
     * - INFO: Informative logging at a detailed level. This logging method produces a
     *   high level of logging, which is unmanageable on a production environment.
     *   Usually INFO logging is only enabled to help by analysing a problem.
     * - NOTICE: Informative logging at a lower detail level than INFO logging.
     *   Only major stages are recorded and is useful to monitor a low volume system.
     * - WARNING: Something unexpected happened, but did not cause any loss of service.
     * - ERROR: An error occured, which may cause partial loss of service. Usually the
     *   system can recover.
     * - FATAL: An serious error occured and the system is unlikely to recover.
     * - SUCCESS_AUDIT: Informative logging about a successful completion of work by
     *   a module completed. Useful to trace system changes directly or indirectly
     *   done by a user.
     * - FAILED_AUDIT: Informative logging about an action from a module
     *   with a negative result. A failed login will most likely added to this severity.
     *
     * The attributes array $attributes can have one or multiple attributes that will
     * be added to the log. If source and category are given, they will override the default
     * source or category given as property to this object. Further more it is up to the
     * application what to include in the log. It may be useful to add the
     * file and linenumber to the attributes array. Use the magic PHP constants: {@link __FILE__}
     * and {@link __LINE__}  for this purpose. The next example adds an warning to the log.
     *
     * <code>
     * ezcLog::getInstance()->source = "templateEngine"; // Set the default source.
     * ezcLog::getInstance()->log( "ezcPersistentObject <$obj> does not exist.",
     *     ezcLog::WARNING,
     *     array( "category" => "Database", "line" => __LINE__, "file" => __FILE__, "code" => 123 )
     *     );
     * </code>
     *
     * The methods {@link setSeverityAttributes()} and {@link setSourceAttributes()} can automatically
     * add attributes to log messages based on, respectively, the severity and source.
     *
     * See also {@link logHandler()} on how to use {@link trigger_error()} to write log messages.
     *
     * @throws ezcLogWriterException if {@link throwWriterExceptions} are enabled and a log entry
     *                               could not be written.
     *
     * @param string $message
     * @param int $severity  One of the following severity constants:
     *                       DEBUG, SUCCES_AUDIT, FAIL_AUDIT, INFO, NOTICE, WARNING, ERROR, or FATAL.
     * @param array(string=>string) $attributes
     */
    public function log( $message, $severity, array $attributes = array() )
    {
        $source = ( isset( $attributes["source"] ) ? $attributes["source"] : $this->properties["source"] );
        $category = ( isset( $attributes["category"] ) ? $attributes["category"] : $this->properties["category"] );

        unset( $attributes["source"] );
        unset( $attributes["category"] );

        $attributes = array_merge( $this->context->getContext( $severity, $source ), $attributes );

        $writers = $this->writers->get( $severity, $source, $category );
        foreach ( $writers as $writer )
        {
            try
            {
                $writer->writeLogMessage( $message, $severity, $source, $category, $attributes );
            }
            catch ( ezcLogWriterException $e )
            {
                if ( $this->throwWriterExceptions )
                {
                    throw $e;
                }
            }
        }
    }

    /**
     * Sets the attributes $attributes for a group of severities $severityMask.
     *
     * The severities are specified with a bit mask. These attributes will be
     * added to the log message when the log severity is the same as specified
     * here.
     *
     * Example:
     * <code>
     * ezcLog::getInstance()->setSeverityAttributes(
     *     ezcLog::SUCCESS_AUDIT | ezcLog::FAILED_AUDIT
     *     array( "username" => "Jan K. Doodle" )
     * );
     * </code>
     *
     * Every log message that has the severity SUCCESS_AUDIT or FAILED_AUDIT
     * includes the user name: "Jan K. Doodle".
     *
     * @param integer $severityMask Multiple severities are specified with a logic-or.
     * @param array(string=>string) $attributes
     */
    public function setSeverityAttributes( $severityMask, $attributes )
    {
        $this->context->setSeverityContext( $severityMask, $attributes );
    }

    /**
     * Sets the attributes $attributes for a group of sources $sources.
     *
     * The sources are specified in an array. These attributes will be added to the
     * log message when it matches with the given $sources.
     *
     * Example:
     * <code>
     * ezcLog::getInstance()->setSourceAttributes(
     *     array( "Paynet", "Bibit", "Paypal" ),
     *     array( "MerchantID" => $merchantID )
     * );
     * </code>
     *
     * Every log message that comes from the payment module: Paynet, Bibit, or Paypal
     * includes the Merchant ID.
     *
     * @param array(string) $sources
     * @param array(string=>string) $attributes
     */
    public function setSourceAttributes ( $sources, $attributes )
    {
        $this->context->setSourceContext( $sources, $attributes );
    }

    /**
     * This method can be set as error_handler to log using {@link trigger_error()}.
     *
     * This method can be assigned with the {@link set_error_handler()} to handle the
     * trigger_error calls. This method will get the log instance and forward the
     * message. But includes the following information:
     * - The file and linenumber are automatically added.
     * - Source and category can be 'encoded' in the message.
     *
     * The message format is as follows:
     * <pre>
     * [ source, category ] Message
     * </pre>
     *
     * When one name is given between the brackets, the category will be set and the message has a default source:
     * <pre>
     * [ category ] Message
     * </pre>
     *
     * Without any names between the brackets, the default category and source are used:
     * <pre>
     * Message
     * </pre>
     *
     * The following example creates manually an error handler and forwards the
     * ERROR, WARNING and NOTICE severities.
     * <code>
     * function myLogHandler($errno, $errstr, $errfile, $errline)
     * {
     *     switch ($errno)
     *     {
     *         case E_USER_ERROR:
     *         case E_USER_WARNING:
     *         case E_USER_NOTICE:
     *             if ( $loggingEnabled )
     *             {   // Forward the message to the log handler.
     *                 ezcLog::LogHandler( $errno, $errstr, $errfile, $errline );
     *             }
     *             break;
     *
     *         default:
     *             print( "$errstr in $errfile on line $errline\n" );
     *             break;
     *     }
     * }
     *
     * // Register myLogHandler
     * set_error_handler( "myLogHandler" );
     *
     * // Write an warning to the log.
     * trigger_error( "[paynet, transaction] Didn't get a callback from the Paynet service", E_USER_WARNING );
     *
     * // Add a notice.
     * trigger_error( "Getting paynet status information", E_USER_NOTICE );
     *
     * </code>
     *
     * Notice that the ezcLog component is not loaded at all when the logging is disabled.
     *
     * @param int $errno
     * @param int $errstr
     * @param string $errfile
     * @param int $errline
     */
     public static function logHandler( $errno, $errstr, $errfile, $errline )
     {
         $log = ezcLog::getInstance();
         $lm = new ezcLogMessage( $errstr, $errno, $log->source, $log->category );
         $log->log(
             $lm->message, $lm->severity,
             array( "source" => $lm->source, "category" => $lm->category, "file" => $errfile, "line" => $errline )
         );
     }

    /**
     * Translates the severity constant to a string and returns this.
     *
     * Null is returned when the severity constant is invalid.
     *
     * @param int $severity
     * @return string
     */
    public static function translateSeverityName( $severity )
    {
        switch ( $severity )
        {
            case self::DEBUG:           return "Debug";
            case self::SUCCESS_AUDIT:   return "Success audit";
            case self::FAILED_AUDIT:    return "Failed audit";
            case self::INFO:            return "Info";
            case self::NOTICE:          return "Notice";
            case self::WARNING:         return "Warning";
            case self::ERROR:           return "Error";
            case self::FATAL:           return "Fatal";
            default:                    return null;
        }
    }
}
?>
