/Debug/src/debug.php
PHP | 466 lines | 169 code | 36 blank | 261 comment | 11 complexity | 06cd962a540fdc461acc4a3ccaf68ff2 MD5 | raw file
- <?php
- /**
- * File containing the ezcDebug 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 Debug
- * @version //autogentag//
- * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
- */
- /**
- * The ezcDebug class provides functionality to format and store debug messages and timers.
- *
- * The functionality of the Debug component is two folded:
- * - Debug log messages
- * - Timers
- *
- * The log messages are heavily based on the {@link EventLog} log messages. In fact
- * internally the EventLog is used with its own log writer. The {@link log()} method
- * is almost the same as from the EventLog. The next example demonstrates how to instantiate the
- * ezcDebug class and write some log messages:
- * <code>
- * $debug = ezcDebug::getInstance();
- * $debug->log( "Connecting with the paynet server", 2 );
- * // ...
- * $debug->log( "Connection failed, retrying in 5 seconds", 1 );
- * // ...
- * $debug->log( "Could not connect with the server", 0 );
- * </code>
- *
- * The second parameter of the log method is the verbosity. This is a number that
- * specifies the importance of the log message. That makes it easier to sort out messages of less importance.
- * In this example, we assumed the more important the message, the lower the
- * verbosity number.
- *
- * The ezcDebug timer is designed to allow the next two timing methods:
- * - Timers, the time between two points in the program.
- * - Accumulators, gets the relative time after the script started.
- *
- * The "Timers" are simply set with the methods {@link startTimer()} and {@link stopTimer()}. The next example
- * demonstrates the timing of a simple calculation:
- * <code>
- * $debug = ezcDebug::getInstance();
- * $debug->startTimer( "Simple calculation" );
- *
- * // Simple calculation
- * $result = 4 + 6;
- *
- * $debug->stopTimer( "Simple calculation" ); // Parameter can be omitted.
- * </code>
- *
- * To get timing points, accumulators, use the {@link switchTimer()} method. This is shown in the next example:
- * <code>
- * $debug = ezcDebug::getInstance();
- * $debug->startTimer( "My script" );
- * // ...
- * $debug->switchTimer( "Reading ini file" );
- * // ...
- * $debug->switchTimer( "Initializing template parser" );
- * // ...
- * $debug->switchTimer( "Parsing" );
- * // ...
- * $debug->stopTimer();
- * </code>
- *
- * @property ezcDebugOptions $options
- * Options to configure the behaviour of ezcDebug, including stack
- * trace behaviours.
- *
- * @package Debug
- * @version //autogentag//
- * @mainclass
- */
- class ezcDebug
- {
- /**
- * Properties.
- *
- * @var array(string=>mixed)
- */
- protected $properties = array();
- /**
- * Instance of the singleton ezcDebug object.
- *
- * Use the getInstance() method to retrieve the instance.
- *
- * @var ezcDebug
- */
- private static $instance = null;
- /**
- * The formatter that generates the debug output.
- *
- * @var ezcDebugFormatter
- */
- private $formatter = null;
- /**
- * A pointer to the logging system.
- *
- * @var ezcLog
- */
- private $log = null;
- /**
- * The timing object used to store timing information.
- *
- * @var ezcDebugTimer
- */
- private $timer = null;
- /**
- * The writer that holds debug output.
- *
- * @var ezcLogWriter
- */
- private $writer = null;
- /**
- * Constructs a new debug object and attaches it to the log object.
- *
- * This method is private because the getInstance() should be called.
- */
- private function __construct()
- {
- $this->options = new ezcDebugOptions();
- $original = ezcLog::getInstance();
- $this->log = clone( $original );
- $this->log->reset();
- $this->log->setMapper( new ezcLogFilterSet() );
- // Set the writer.
- $this->writer = new ezcDebugMemoryWriter();
- $filter = new ezcLogFilter();
- $filter->severity = ezcLog::DEBUG;
- $this->log->getMapper()->appendRule( new ezcLogFilterRule( $filter, $this->writer, true ) );
- $this->reset();
- }
- /**
- * Property get access.
- *
- * @throws ezcBasePropertyNotFoundException
- * If the given property could not be found.
- * @param string $propertyName
- * @ignore
- */
- public function __get( $propertyName )
- {
- if ( $this->__isset( $propertyName ) )
- {
- return $this->properties[$propertyName];
- }
- throw new ezcBasePropertyNotFoundException( $propertyName );
- }
- /**
- * Property set access.
- *
- * @throws ezcBasePropertyNotFoundException
- * @param string $propertyName
- * @param string $propertyValue
- * @ignore
- */
- public function __set( $propertyName, $propertyValue )
- {
- switch ( $propertyName )
- {
- case 'options':
- if ( !( $propertyValue instanceof ezcDebugOptions ) )
- {
- throw new ezcBaseValueException(
- $propertyName,
- $propertyValue,
- 'ezcDebugOptions'
- );
- }
- break;
- default:
- throw new ezcBasePropertyNotFoundException( $propertyName );
- }
- $this->properties[$propertyName] = $propertyValue;
- }
- /**
- * Property isset access.
- *
- * @param string $propertyName
- * @return bool
- * @ignore
- */
- public function __isset( $propertyName )
- {
- return array_key_exists( $propertyName, $this->properties );
- }
- /**
- * Resets the log messages and timer information.
- *
- * @return void
- */
- public function reset()
- {
- $this->writer->reset();
- $this->timer = new ezcDebugTimer();
- }
- /**
- * Returns the instance of this class.
- *
- * When the ezcDebug instance is created it is automatically added to the instance
- * of ezcLog.
- *
- * @return ezcDebug
- */
- public static function getInstance()
- {
- if ( is_null( self::$instance ))
- {
- self::$instance = new ezcDebug();
- ezcBaseInit::fetchConfig( 'ezcInitDebug', self::$instance );
- }
- return self::$instance;
- }
- /**
- * Returns the instance of the EventLog used in this class.
- *
- * The returned instance is not the same as retrieved via the
- * ezcLog::getInstance() method.
- *
- * @return ezcLog
- */
- public function getEventLog()
- {
- return $this->log;
- }
- /**
- * Sets the formatter $reporter for the output.
- *
- * If no formatter is set {@link ezcDebugHtmlReporter} will be used by default.
- *
- * @param ezcDebugOutputFormatter $formatter
- * @return void
- */
- public function setOutputFormatter( ezcDebugOutputFormatter $formatter )
- {
- $this->formatter = $formatter;
- }
- /**
- * Returns the formatted debug output.
- *
- * @return string
- */
- public function generateOutput()
- {
- if ( is_null( $this->formatter ) )
- $this->formatter = new ezcDebugHtmlFormatter();
- return $this->formatter->generateOutput( $this->writer->getStructure(), $this->timer->getTimeData() );
- }
- /**
- * Starts the timer with the identifier $name.
- *
- * Optionally, a timer group can be given with the $group parameter.
- *
- * @param string $name
- * @param string $group
- */
- public function startTimer( $name, $group = null )
- {
- $this->timer->startTimer( $name, $group );
- }
- /**
- * Stores the time from the running timer, and starts a new timer.
- *
- * Stores the time for $oldTimer (maybe omitted if only 1 timer is running)
- * and starts a new timer with $newName.
- *
- * @param string $newName
- * @param string|bool $oldName
- */
- public function switchTimer( $newName, $oldName = false )
- {
- $this->timer->switchTimer( $newName, $oldName );
- }
- /**
- * Stops the timer identified by $name.
- *
- * $name can be omitted (false) if only one timer is running.
- *
- * @param string|bool $name
- */
- public function stopTimer( $name = false )
- {
- $this->timer->stopTimer( $name );
- }
- /**
- * Writes the debug message $message with verbosity $verbosity.
- *
- * Arbitrary $extraInfo can be submitted. If $stackTrace is set to true, a
- * stack trace will be stored at the current program position.
- *
- * @param string $message
- * @param int $verbosity
- * @param array(string=>string) $extraInfo
- * @param bool $stackTrace
- */
- public function log( $message, $verbosity, array $extraInfo = array(), $stackTrace = false )
- {
- // Add the verbosity
- $extraInfo = array_merge( array( "verbosity" => $verbosity ), $extraInfo );
- if ( $this->options->stackTrace === true || $stackTrace === true )
- {
- $extraInfo['stackTrace'] = $this->getStackTrace();
- }
- $this->log->log( $message, ezcLog::DEBUG, $extraInfo );
- }
- /**
- * Returns a stack trace iterator for the current call.
- *
- * Returns a
- * - {@link ezcDebugXdebugStacktraceIterator} if Xdebug is available
- * - {@link ezcDebugPhpStacktraceIterator} otherwise
- * representing a stack trace of the current function environment.
- *
- * @return ezcDebugStacktraceIterator
- */
- private function getStackTrace()
- {
- if ( extension_loaded( 'xdebug' ) )
- {
- return new ezcDebugXdebugStacktraceIterator(
- xdebug_get_function_stack(),
- 2,
- $this->options
- );
- }
- else
- {
- return new ezcDebugPhpStacktraceIterator(
- debug_backtrace(),
- 2,
- $this->options
- );
- }
- }
- /**
- * Dispatches the message and error type to the correct debug or log
- * function.
- *
- * This function should be used as the set_error_handler from the
- * trigger_error function.
- *
- * Use for example the following code in your application:
- *
- * <code>
- * function debugHandler( $a, $b, $c, $d )
- * {
- * ezcDebug::debugHandler( $a, $b, $c, $d );
- * }
- *
- * set_error_handler( "debugHandler" );
- * </code>
- *
- * Use trigger_error() to log warning, error, etc:
- *
- * <code>
- * trigger_error( "[Paynet, templates] Cannot load template", E_USER_WARNING );
- * </code>
- *
- * See the PHP documentation of
- * {@link http://php.net/trigger_error trigger_error} for more information.
- *
- * @param int $errno
- * @param string $errstr
- * @param string $errfile
- * @param int $errline
- * @return void
- */
- public static function debugHandler( $errno, $errstr, $errfile, $errline )
- {
- $debug = ezcDebug::getInstance();
- $log = $debug->getEventLog();
-
- preg_match(
- '/^\s*(?:\[([^,\]]*)(?:,\s(.*))?\])?\s*(?:(\d+):)?\s*(.*)$/',
- $errstr,
- $matches
- );
-
- $message = ( $matches[4] === '' ? false : $matches[4] );
- $verbosity = ( $matches[3] === '' ? false : $matches[3] );
- if ( strlen( $matches[2] ) == 0 )
- {
- $category = ( $matches[1] === '' ? $log->category : $matches[1] );
- $source = $log->source;
- }
- else
- {
- $category = $matches[2];
- $source = $matches[1];
- }
-
- $severity = false;
- switch ( $errno )
- {
- case E_USER_NOTICE:
- $severity = ezcLog::NOTICE;
- break;
- case E_USER_WARNING:
- $severity = ezcLog::WARNING;
- break;
- case E_USER_ERROR:
- $severity = ezcLog::ERROR;
- break;
- }
- $debug->log(
- $message,
- $severity,
- array(
- 'source' => $source,
- 'category' => $category,
- 'verbosity' => $verbosity,
- 'file' => $errfile,
- 'line' => $errline
- )
- );
- }
- }
- ?>