Advertisement
fruffl

Exception Logger

Feb 17th, 2012
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 15.64 KB | None | 0 0
  1. <?PHP
  2.     /**
  3.      * ILLI
  4.      *
  5.      * @category   ILLI
  6.      * @package    ILLI
  7.      * @subpackage System
  8.      * @link       http://illi.be
  9.      * @license    http://l.illi.be
  10.      * @copyright  2007-2012, ILLI Conference
  11.      */
  12.  
  13.     /**
  14.      * ILLI System Exception
  15.      *
  16.      * This exception-handler provides inner- and outer-exception-handling
  17.      * and several output-formats.
  18.      * @todo notify ILLI when we have thrown an exception
  19.      * @todo multi-level mapper
  20.      *
  21.      * @category   ILLI
  22.      * @package    ILLI
  23.      * @subpackage System
  24.      * @link       http://illi.be
  25.      * @license    http://l.illi.be
  26.      * @copyright  2007-2012, ILLI Conference
  27.      */
  28.     ABSTRACT CLASS ILLI_System_Exception EXTENDS EXCEPTION IMPLEMENTS ILLI_System_E
  29.     {
  30.         /**
  31.          * static exception counter
  32.          *
  33.          * @var int $__levelCounter
  34.          * @private
  35.          * @static
  36.          */
  37.         private static $__levelCounter = 0;
  38.        
  39.         /**
  40.          * stores the relation between instance and {@link $__levelCounter}
  41.          *
  42.          * @var array $__logLevels
  43.          * @private
  44.          * @static
  45.          */
  46.         private static $__logLevels = array();
  47.        
  48.         /**
  49.          * logger map
  50.          *
  51.          * @var ILLI_System_Exception_Logger $System_Exception_Logger
  52.          * @private
  53.          * @static
  54.          */
  55.         private static $System_Exception_Logger = NULL;
  56.        
  57.         /**
  58.          * constructor argument handler
  59.          *
  60.          * @var ILLI_System_Exception_Arguments $System_ExceptionArguments
  61.          * @private
  62.          */
  63.         private $System_ExceptionArguments = NULL;
  64.        
  65.         /**
  66.          * exception output handler
  67.          *
  68.          * @var ILLI_System_Exception_Export_Queue $System_Exception_Export_Queue
  69.          * @private
  70.          */
  71.         private $System_Exception_Export_Queue = NULL;
  72.        
  73.         /**
  74.          * exception number
  75.          *
  76.          * @var int $__level
  77.          * @private
  78.          */
  79.         private $__level = 0;
  80.        
  81.         /**
  82.          * look-up for thrown inner-exception
  83.          *
  84.          * simple query
  85.          *
  86.          * ...catch(myException $e)
  87.          * {
  88.          *  var_dump($e->hasCatched('anotherException'));
  89.          * }
  90.          *
  91.          * @param string $exceptionClass
  92.          * @return bool
  93.          * @uses ILLI_Exception_ArgumentNull
  94.          * @uses ILLI_Exception_ArgumentExpected
  95.          * @uses ILLI_System_E::ARGUMENT_EXPECTED_STRING
  96.          * @uses ILLI_System_E::ARGUMENT_EXPECTED_STRING_EMPTY
  97.          * @uses ILLI_System_Exception::$__logLevels
  98.          * @throws {@link ILLI_Exception_ArgumentNull}
  99.          * @throws {@link ILLI_Exception_ArgumentExpected}
  100.          */
  101.         public static function hasCatched($exceptionClass)
  102.         {
  103.             if(NULL === $exceptionClass)
  104.                 throw new ILLI_Exception_ArgumentNull;
  105.                
  106.             if(!is_string($exceptionClass))
  107.                 throw new ILLI_Exception_ArgumentExpected
  108.                     (ILLI_System_E::ARGUMENT_EXPECTED_STRING);
  109.                
  110.             if(empty($exceptionClass))
  111.                 throw new ILLI_Exception_ArgumentExpected
  112.                     (ILLI_System_E::ARGUMENT_EXPECTED_STRING_EMPTY);
  113.  
  114.             $e = strtolower($exceptionClass);
  115.             return array_key_exists($e, self::$__logLevels);
  116.         }
  117.        
  118.         /**
  119.          * get levels of inner exception as array
  120.          *
  121.          * @param string $exceptionClass
  122.          * @return array integer-values
  123.          * @uses ILLI_System_Exception::hasCatched()
  124.          * @uses ILLI_System_Exception::$__logLevels
  125.          */
  126.         public static function getCatchedLevel($exceptionClass)
  127.         {
  128.             if(FALSE === self::hasCatched($exceptionClass))
  129.                 return array();
  130.                
  131.             $e = strtolower($exceptionClass);
  132.                
  133.             return self::$__logLevels[$e];
  134.         }
  135.        
  136.         /**
  137.          * get all catched exceptions including levels
  138.          *
  139.          * @param string $exceptionClass
  140.          * @return array {@link $__logLevels}
  141.          * @uses ILLI_System_Exception::$__logLevels
  142.          */
  143.         public static function getCatched()
  144.         {
  145.             return self::$__logLevels;
  146.         }
  147.        
  148.         /**
  149.          * get all logger-maps
  150.          *
  151.          * @return array
  152.          * @uses ILLI_System_Exception::$System_Exception_Logger
  153.          * @uses ILLI_System_Exception_Logger
  154.          * @uses ILLI_System_Exception_Logger::getInternal()
  155.          * @uses ILLI_System_Exception_Logger::getSystem()
  156.          * @uses ILLI_System_Exception_Logger::getAll()
  157.          */
  158.         public static function getLog()
  159.         {
  160.             return array
  161.             (
  162.                 'internal'  => self::$System_Exception_Logger->getInternal(),
  163.                 'system'    => self::$System_Exception_Logger->getSystem(),
  164.                 'all'       => self::$System_Exception_Logger->getAll()
  165.             );
  166.         }
  167.        
  168.         /**
  169.          * get class-names of all catched exceptions
  170.          *
  171.          * @return array
  172.          * @uses ILLI_System_Exception::$__logLevels
  173.          */
  174.         public static function getCatchedExceptions()
  175.         {
  176.             return array_keys(self::$__logLevels);
  177.         }
  178.        
  179.         /**
  180.          * constructor
  181.          *
  182.          * @param int32 $code valid error-code
  183.          * @param ILLI_System_Exception|mixed $innerOrArray previous exception or argument(s)
  184.          * @uses ILLI_System_Exception::registerException()
  185.          * @uses ILLI_System_Exception::getMessageByCode()
  186.          * @uses ILLI_System_Exception::getErrorCode()
  187.          * @uses ILLI_System_Exception::$System_ExceptionArguments
  188.          * @uses ILLI_System_Exception_Arguments
  189.          * @uses ILLI_System_Exception_Arguments::getPreviousException()
  190.          * @uses ILLI_System_Exception_Arguments_Exception
  191.          * @uses ILLI_System_Exception_Exception_ConstructorException
  192.          * @uses ILLI_System_Exception_Exception_ConstructorException::ERROR_INVALID_CONSTRUCTOR_ARGUMENTS
  193.          * @uses ILLI_System_Exception_Exception
  194.          * @uses ILLI_System_E::INTERNAL_ERROR
  195.          * @uses ILLI_System_E::ERROR_UNKNOWN
  196.          */
  197.         public function __construct($code = self::ERROR_UNKNOWN, $innerOrArray = NULL, $innerOrArray = NULL)
  198.         {
  199.             try
  200.             {
  201.                 try
  202.                 {
  203.                        
  204.                     $this->System_ExceptionArguments =
  205.                         new ILLI_System_Exception_Arguments(func_get_args());
  206.                 }
  207.                 catch(ILLI_System_Exception_Arguments_Exception $e1)
  208.                 {
  209.                     throw new ILLI_System_Exception_Exception_ConstructorException
  210.                         (ILLI_System_Exception_Exception_ConstructorException::ERROR_INVALID_CONSTRUCTOR_ARGUMENTS, $e1);
  211.                 }
  212.                
  213.                 $this->registerException();
  214.                
  215.                 parent::__construct
  216.                 (
  217.                     $this->getMessageByCode($this->getErrorCode()),
  218.                     $this->getErrorCode(),
  219.                     $this->System_ExceptionArguments->getPreviousException()
  220.                 );
  221.             }                  
  222.             catch(ILLI_System_Exception_Exception_ConstructorException $e2)
  223.             {
  224.                 throw new ILLI_System_Exception_Exception
  225.                     (ILLI_System_E::INTERNAL_ERROR, $e2);
  226.             }
  227.            
  228.         }
  229.        
  230.         /**
  231.          * get error-code
  232.          *
  233.          * @return int
  234.          * @uses ILLI_System_Exception::$System_ExceptionArguments
  235.          * @uses ILLI_System_Exception_Arguments
  236.          * @uses ILLI_System_Exception_Arguments::getErrorCode()
  237.          */
  238.         public function getErrorCode()
  239.         {
  240.             return $this->System_ExceptionArguments->getErrorCode();
  241.         }
  242.        
  243.         /**
  244.          * get error-code as 0x-string-format
  245.          *
  246.          * @return string
  247.          * @uses ILLI_System_Exception::getErrorCode()
  248.          */
  249.         public function getErrorCodeInt32()
  250.         {
  251.             return sprintf('0x%1s', str_pad(strtoupper(dechex($this->getErrorCode())), 8, 0, STR_PAD_LEFT));
  252.         }
  253.        
  254.         /**
  255.          * get current level
  256.          *
  257.          * @return int
  258.          * @uses ILLI_System_Exception::$__level
  259.          */
  260.         public function getExceptionLevel()
  261.         {
  262.             return $this->__level;
  263.         }
  264.        
  265.         /**
  266.          * export exception
  267.          *
  268.          * @param string $exportType
  269.          * @return mixed
  270.          * @uses ILLI_System_Exception::getTrace()
  271.          * @uses ILLI_System_Exception::export()
  272.          * @uses ILLI_System_Exception::getExportQueue()
  273.          * @uses ILLI_System_Exception::getPrevious()
  274.          * @uses ILLI_System_Exception_Export
  275.          * @uses ILLI_System_Exception_Export::TEXT
  276.          * @uses ILLI_System_Exception_Export::getMessage()
  277.          * @uses ILLI_System_Exception_Export_Queue
  278.          * @uses ILLI_System_Exception_Export_Queue::addMessage()
  279.          * @uses ILLI_System_Exception_Export_Queue::addTrace()
  280.          * @uses ILLI_System_Exception_Export_Partial_Message
  281.          * @uses ILLI_System_Exception_Export_Partial_Message::setExceptionClass()
  282.          * @uses ILLI_System_Exception_Export_Partial_Message::setErrorCode()
  283.          * @uses ILLI_System_Exception_Export_Partial_Message::setErrorLevel()
  284.          * @uses ILLI_System_Exception_Export_Partial_Message::setLine()
  285.          * @uses ILLI_System_Exception_Export_Partial_Message::setFile()
  286.          * @uses ILLI_System_Exception_Export_Partial_Message::setMessage()
  287.          * @uses ILLI_System_Exception_Export_Partial_Message::setReferences()
  288.          * @uses ILLI_System_Exception_Export_Partial_Trace
  289.          * @uses ILLI_System_Exception_Export_Partial_Trace::setFile()
  290.          * @uses ILLI_System_Exception_Export_Partial_Trace::setLine()
  291.          * @uses ILLI_System_Exception_Export_Partial_Trace::setFunction()
  292.          * @uses ILLI_System_Exception_Export_Partial_Trace::setClass()
  293.          * @uses ILLI_System_Exception_Export_Partial_Trace::setType()
  294.          * @uses ILLI_System_Exception_Export_Partial_Trace::setArgs()
  295.          */
  296.         public function export($exportType = ILLI_System_Exception_Export::TEXT)
  297.         {
  298.             $message = new ILLI_System_Exception_Export_Partial_Message;
  299.            
  300.             $this->getExportQueue()->addMessage
  301.             (
  302.                 $message
  303.                 ->setExceptionClass
  304.                 (
  305.                     get_class($this)
  306.                 )
  307.                 ->setErrorCode
  308.                 (
  309.                     $this->getErrorCodeInt32()
  310.                 )
  311.                 ->setErrorLevel
  312.                 (
  313.                     $this->getExceptionLevel()
  314.                 )
  315.                 ->setLine
  316.                 (
  317.                     str_pad($this->getLine(), 8, 0, STR_PAD_LEFT)
  318.                 )
  319.                 ->setFile
  320.                 (
  321.                     $this->getFile()
  322.                 )
  323.                 ->setMessage
  324.                 (
  325.                     $this->getParsedMessage()
  326.                 )
  327.                 ->setReferences
  328.                 (
  329.                     $this->getParsedReferences()
  330.                 )
  331.             );
  332.            
  333.            
  334.             if($this->getPrevious() instanceOf ILLI_System_Exception)
  335.                 $this->getPrevious()->export();
  336.                
  337.             if(NULL === $this->getPrevious())
  338.             {
  339.                 $trace = $this->getTrace();
  340.                 $trace = array_reverse($trace);
  341.                
  342.                 foreach($trace as $line)
  343.                 {
  344.                     $traceline = new ILLI_System_Exception_Export_Partial_Trace;
  345.                     $this->getExportQueue()->addTrace
  346.                     (
  347.                         $traceline
  348.                         ->setFile
  349.                         (
  350.                             isset($line['file'])
  351.                                 ? $line['file']
  352.                                 : 'internal'
  353.                         )
  354.                         ->setLine
  355.                         (
  356.                             isset($line['line'])
  357.                                 ? $line['line']
  358.                                 : 'NaN'
  359.                         )
  360.                         ->setFunction
  361.                         (
  362.                             isset($line['function'])
  363.                                 ? $line['function']
  364.                                 : 'Unknown'
  365.                         )
  366.                         ->setClass
  367.                         (
  368.                             isset($line['class'])
  369.                                 ? $line['class']
  370.                                 : ''
  371.                         )
  372.                         ->setType
  373.                         (
  374.                             isset($line['type'])
  375.                                 ? $line['type']
  376.                                 : ''
  377.                         )
  378.                         ->setArgs
  379.                         (
  380.                             isset($line['args'])
  381.                                 ? $line['args']
  382.                                 : 'None'
  383.                         )
  384.                     );
  385.                 }
  386.             }
  387.            
  388.             $EXPORT = new ILLI_System_Exception_Export
  389.             (
  390.                 $this->getExportQueue(),
  391.                 $exportType
  392.             );
  393.            
  394.             if(!is_string($e = $EXPORT->getMessage()))
  395.                 return $e;
  396.            
  397.             return $e;
  398.         }
  399.        
  400.         /**
  401.          * remove sensitive parts from exception-message
  402.          *
  403.          * @return string
  404.          * @uses ILLI
  405.          * @uses ILLI::getInstallDir()
  406.          */
  407.         private function cleanUp($string)
  408.         {
  409.             return str_replace
  410.             (
  411.                 array
  412.                 (
  413.                     realpath(dirname($_SERVER['SCRIPT_FILENAME'])),
  414.                     realpath($_SERVER['DOCUMENT_ROOT']),
  415.                     dirname($_SERVER['SCRIPT_FILENAME']),
  416.                     $_SERVER['DOCUMENT_ROOT'],
  417.                     $_SERVER['PHP_DOCUMENT_ROOT'],
  418.                     ILLI::getInstallDir(),
  419.                 ),
  420.                 '',
  421.                 $string
  422.             );
  423.         }
  424.        
  425.         /**
  426.          * register exception as thrown instance
  427.          *
  428.          * @void
  429.          * @uses ILLI_System_Exception::$__levelCounter
  430.          * @uses ILLI_System_Exception::$__level
  431.          * @uses ILLI_System_Exception::$__logLevels
  432.          * @uses ILLI_System_Exception::$System_Exception_Logger
  433.          * @uses ILLI_System_Exception_Logger
  434.          * @uses ILLI_System_Exception_Logger::getInstance()
  435.          * @uses ILLI_System_Exception_Logger::registerException()
  436.          */
  437.         private function registerException()
  438.         {
  439.             self::$__levelCounter++;
  440.             $this->__level = self::$__levelCounter;
  441.            
  442.             $Class = get_class($this);
  443.             $class = strtolower($Class);
  444.                
  445.             if(FALSE === self::hasCatched($class))
  446.                 self::$__logLevels[$class] = array();
  447.            
  448.             self::$__logLevels[$class][] = $this->__level;
  449.            
  450.             if(NULL === self::$System_Exception_Logger)
  451.                 self::$System_Exception_Logger = ILLI_System_Exception_Logger::getInstance();
  452.            
  453.             self::$System_Exception_Logger->registerException($this);
  454.         }
  455.        
  456.         /**
  457.          * convert error-code to message
  458.          *
  459.          * @param int32 $code
  460.          * @return string
  461.          * @uses ILLI_System_E::SUCCESS
  462.          * @uses ILLI_System_E::ERROR_UNKNOWN
  463.          * @uses ILLI_System_E::INTERNAL_ERROR
  464.          */
  465.         protected function getStringByCode($code)
  466.         {
  467.             switch($code):
  468.                 case ILLI_System_E::SUCCESS:        return 'The operation completed successfully.';
  469.                 case ILLI_System_E::ERROR_UNKNOWN:  return 'Unknown Error.';
  470.                 case ILLI_System_E::INTERNAL_ERROR: return 'Internal Error.';
  471.             endswitch;
  472.         }
  473.        
  474.         /**
  475.          * convert error-code to message
  476.          *
  477.          * @return ILLI_System_Exception_Export_Queue
  478.          * @uses ILLI_System_Exception::$System_Exception_Export_Queue
  479.          * @uses ILLI_System_Exception_Export_Queue
  480.          */
  481.         private function getExportQueue()
  482.         {
  483.             return ((NULL === $this->System_Exception_Export_Queue)
  484.                 ? ($this->System_Exception_Export_Queue = new ILLI_System_Exception_Export_Queue)
  485.                 : $this->System_Exception_Export_Queue);
  486.         }
  487.        
  488.         /**
  489.          * convert error-code to message
  490.          *
  491.          * @param int32 $code
  492.          * @return string
  493.          * @uses ILLI_System_Exception::getStringByCode()
  494.          * @uses ILLI_System_E::ARGUMENT_EXPECTED_STRING
  495.          * @uses ILLI_System_E::ARGUMENT_EXPECTED_STRING_EMPTY
  496.          * @uses ILLI_System_E::ERROR_UNKNOWN
  497.          * @uses ILLI_System_E::INTERNAL_ERROR
  498.          * @uses ILLI_Exception_Argument
  499.          * @uses ILLI_Exception_ArgumentNull
  500.          * @uses ILLI_Exception_ArgumentExpected
  501.          * @uses ILLI_Exception_ArgumentOutOfRange
  502.          * @uses ILLI_Exception
  503.          * @uses ILLI_System_Exception_Exception
  504.          * @throws {@link ILLI_Exception_ArgumentNull}
  505.          * @throws {@link ILLI_Exception_ArgumentExpected}
  506.          * @throws {@link ILLI_Exception_ArgumentOutOfRange}
  507.          * @throws {@link ILLI_System_Exception_Exception}
  508.          */
  509.         private function getMessageByCode($code)
  510.         {
  511.             try
  512.             {
  513.                 $message = $this->getStringByCode($code);
  514.                
  515.                 try
  516.                 {
  517.                     if(NULL === $message)
  518.                         throw new ILLI_Exception_ArgumentNull;
  519.                        
  520.                     if(!is_string($message))
  521.                         throw new ILLI_Exception_ArgumentExpected
  522.                             (ILLI_System_E::ARGUMENT_EXPECTED_STRING);
  523.                        
  524.                     if(empty($message))
  525.                         throw new ILLI_Exception_ArgumentExpected
  526.                             (ILLI_System_E::ARGUMENT_EXPECTED_STRING_EMPTY);
  527.                        
  528.                 }
  529.                 catch(ILLI_Exception_Argument $e)
  530.                 {
  531.                     throw new ILLI_Exception_ArgumentOutOfRange;
  532.                 }
  533.                
  534.                 return $message;
  535.                
  536.             }
  537.             catch(ILLI_Exception_ArgumentOutOfRange $e)
  538.             {
  539.                 return self::getStringByCode(ILLI_System_E::ERROR_UNKNOWN);
  540.             }
  541.             catch(ILLI_Exception $e)
  542.             {
  543.                 throw new ILLI_System_Exception_Exception
  544.                     (ILLI_System_E::INTERNAL_ERROR);
  545.             }
  546.         }
  547.        
  548.         /**
  549.          * create exception-message
  550.          *
  551.          * @return string
  552.          * @uses ILLI_System_Exception::$System_ExceptionArguments
  553.          * @uses ILLI_System_Exception::getMessage()
  554.          * @uses ILLI_System_Exception_Arguments::getArguments()
  555.          */
  556.         private function getParsedMessage()
  557.         {
  558.             $message = $this->getMessage();
  559.            
  560.             foreach($this->System_ExceptionArguments->getArguments() as $i => $val)
  561.             {
  562.                 if(!is_scalar($val))
  563.                     continue;
  564.                    
  565.                 $_message = str_replace('{'.$i.'}', (($val === NULL) ? 'NULL' : $val), $message);
  566.                 if($_message != $message)
  567.                 {
  568.                     $message = $_message;
  569.                     continue;
  570.                 }
  571.                
  572.             }
  573.            
  574.             return preg_replace('#\{([0-9a-z]+)\}\s#i', '', $message);
  575.         }
  576.        
  577.         /**
  578.          * create message reference
  579.          *
  580.          * @return array
  581.          * @uses ILLI_System_Exception::$System_ExceptionArguments
  582.          * @uses ILLI_System_Exception_Arguments::getArguments()
  583.          */
  584.         private function getParsedReferences()
  585.         {
  586.             $messageinfo = array();
  587.            
  588.             foreach($this->System_ExceptionArguments->getArguments() as $i => $val)
  589.             {
  590.                 ob_start();
  591.                 var_dump($val);
  592.                 $messageinfo[$i] = ob_get_clean();
  593.             }
  594.            
  595.             return $messageinfo;
  596.         }
  597.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement