rendered paste body/** * File contains strictly only Logger singleton class. * * Please check {@link Logger} for more information. * * This file is onften required. * @author James PIC <is_null@devangels.org> * @copyright James PIC * @version 1.0 * @package Logger *//** * Logging API. * <p>This is a singleton class, this means that you can access the instance with : Logger::GetInstance().</p> * <p>For example :</p> * {@example /mnt/data/workspace/TemplateShop/examples/logger.example.php} * <p>Note that this class is used in NiceLogin to take care of the user interface, and to assure security in {@element NiceLogin::SecureClass()}.</p> * @author James PIC <is_null@devangels.org> * @copyright James PIC * @version 1.0 * @global array $aLoggerConfig * @uses DBLayer * @uses NiceLogin * @todo Remove the line argumnent */function get_microtime(){ list($usec, $sec) = explode(' ', microtime()); return ((float)$usec + (float)$sec);}class Logger{ /** * Logger instance * @access private * @var object */ private static $_instance; /** * Instance of the database abstraction layer * @access private * @var object */ private $_oDBLayer; /** * NiceLogin instance * @access private * @var object */ public $_oUserLayer; /** * Event counter * @access public * @var integer */ public $iEvent = 0; /** * Array where messages are stored in chronological order * @access public * @var array */ public $aLogChrono; /** * Array where messages are stored in levels order * @access public * @var array */ public $aLogLevels; /** * Array where messages are stored by function * @access public * @var array */ public $aLogFunction; /** * Local microtimestamp * @access public * @var integer */ public $micronow; /** * Local timestamp * @access private * @var integer */ public $now; /** * User possible Ip * @access public * @var string */ public $sUserIP; /** * Class constructor * @uses DBLayer * @uses NiceLogin * @uses $now */ function __construct() { global $db, $now, $aLoggerConfig; $this->_oDBLayer =& $db; list($usec, $sec) = explode(' ', microtime()); $this->micronow = ((float)$usec + (float)$sec); $this->now =& time(); $now =& $this->now; $this->sUserIP = (!empty($_SERVER['X_FORWARDED_FOR'])) ? $_SERVER['X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; // Error id ir used in databse, because this kind of table grow very fast $aLoggerConfig['aErrorLevelIds'] = array_flip($aLoggerConfig['aErrorLevels']); } /** * Return the logger instance * @uses Logger::$_instance */ public static function GetInstance() { if (!isset(self::$_instance)) { self::$_instance = new Logger() ; } return self::$_instance; } /** * Main method to log messages and data. * If the title of the event level to log is in $aLoggerConfig['aLogLevels'], database log occurs. * Logger::$aLogChrono is increment * @param array Executed function arguments * @param string Event label (for example function name) * @param integer Line Number * @param string Additionnal description * @param int|string Level id or label (default : debug_notice) * @uses $aLoggerConfig * @uses DBLayer * @uses Logger::$aLogChrono * @uses Logger::$aLogLevels * @uses Logger::$aLogFunction * @uses Logger::$iEvent * @uses Logger::$_instance */ public function Log($r_func_args, $s_event_label, $str_line, $str_description='Begin', $m_level=NULL) { global $aLoggerConfig, $NLC; if (is_null($m_level)) $i_level = $aLoggerConfig['aErrorLevelIds']['debug_notice']; elseif (!is_numeric($m_level)) $i_level = $aLoggerConfig['aErrorLevelIds'][$m_level]; else $i_level = $m_level; if (in_array($aLoggerConfig['aErrorLevels'][$i_level], $aLoggerConfig['aLogLevels'])) $this->_oDBLayer->query('INSERT INTO `'.$this->_oDBLayer->prefix.'log` SET `sUserIP` = \''.$this->_oDBLayer->escape($this->sUserIP).'\' , `iDateEvent` = '.$this->_oDBLayer->escape($this->now).' , `sFunction` = \''.$this->_oDBLayer->escape($s_event_label).'\' , `iLevel` = \''.$this->_oDBLayer->escape($i_level).'\' , `sDescription` = \''.$str_description.'\'') or $this->Log(func_get_args(), __FUNCTION__, __LINE__, $this->_oDBLayer->error()); $this->aLogChrono[$this->iEvent][$s_event_label][$i_level]['description'] = $str_description; $this->aLogChrono[$this->iEvent][$s_event_label][$i_level]['level'] = $aLoggerConfig['aErrorLevels'][$i_level]; if ($str_description=='Begin' && $r_func_args) $this->aLogChrono[$this->iEvent][$s_event_label][$i_level]['arguments'] = $r_func_args; if (is_object($NLC)&&$NLC->aUserData) $this->aLogChrono[$this->iEvent][$s_event_label][$i_level]['user data'] = $this->_oUserLayer->aUserData; if (is_object($NLC)&&$NLC->aCookie) $this->aLogChrono[$this->iEvent][$s_event_label][$i_level]['cookie data'] = $this->_oUserLayer->aCookie; $this->aLogChrono[$this->iEvent][$s_event_label][$i_level]['time'] = $this->now; $this->aLogChrono[$this->iEvent][$s_event_label][$i_level]['microtime'] = get_microtime(); if ($this->iEvent) { $a = array_keys($this->aLogChrono[$this->iEvent-1]); $this->aLogChrono[$this->iEvent][$s_event_label][$i_level]['microtime_since_previous'] = $this->aLogChrono[$this->iEvent][$s_event_label][$i_level]['microtime'] -$this->aLogChrono[$this->iEvent-1][$a][$i_level]['microtime']; } if ($this->iEvent) $this->aLogChrono[$this->iEvent][$s_event_label][$i_level]['microtime_since_beginning'] = $this->micronow-$this->aLogChrono[$this->iEvent-1][$s_event_label][$i_level]['microtime']; if (!isset($this->aLogLevels[$i_level]) || !isset($this->aLogLevels[$i_level][$s_event_label]) || !in_array($str_description, $this->aLogLevels[$i_level][$s_event_label])) $this->aLogLevels[$i_level][$s_event_label][] = $str_description; $this->aLogFunction[$s_event_label][$i_level][] = $str_description; $this->iEvent++; } /** * Returns true if $str_function casted a log with level $i_level * @param integer Level Id * @param string Function name * @uses Logger::$aLogFunction * @return bool */ public function ErrorLogged($i_level, $str_function) { if (isset($this->aLogFunction[$str_function])&&isset($this->aLogFunction[$str_function][$i_level])&&is_array($this->aLogFunction[$str_function][$i_level])) return true; else return false; } /** * Prints chronologic log * @param string Error level string * @uses Logger::$aLogFunction * @return bool */ public function ShowLog($s_error_level='any') { $i_total_time = get_microtime() - $this->micronow; $str_output = ''; $str_output .= "<font size='1'><table border='1' width='700px' cellspacing='0' cellpadding='1'><tr><th align='left' bgcolor='#f57900' colspan='5'><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>Logger</th></tr>"; $str_output .= "<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>"; $str_output .= "<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Percent of script</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>"; foreach ($this->aLogChrono as $i_event => $a_events) { foreach ($a_events as $s_event => $a_event) { foreach ($a_event as $i_level => $a_logged) { if ($a_logged['microtime_since_previous']!=$i_total_time) $str_output .= "<tr><td bgcolor='#eeeeec' align='center'>".$i_event."</td><td bgcolor='#eeeeec' align='center'>".(round(($a_logged['microtime_since_previous']/$i_total_time)*100,2))."</td><td bgcolor='#eeeeec' align='right'>".$a_logged['microtime_since_previous']." : ".$a_logged['microtime_since_previous']."</td><td bgcolor='#eeeeec'>".$a_logged['description']."</td><td title='/mnt/data/workspace/TemplateShop/examples/logger.example.php' bgcolor='#eeeeec'>".$s_event."</td></tr>"; } } } $str_output .= '</table></font>'; echo $str_output; //print_r($this->aLogChrono); } /** * Function to return notices if there are any. * If function returns false, it's a good idea to to use Logger::ReturnSuccessNotices(). * Default : [ error, user_notice, user_error ], all functions * @param array Array of interresting levels, default are error levels * @uses Logger::$aLogLevels * @uses $aLoggerConfig * @return bool */ public function ReturnNotices($r_levels = NULL) { global $aLoggerConfig; if (!is_null($r_levels) && is_numeric($r_levels)) $r_levels = array($r_levels); if (is_null($r_levels) || !is_array($r_levels) || (is_array($r_levels) && count($r_levels)<1)) $r_levels = array($aLoggerConfig['aErrorLevelIds']['error'], $aLoggerConfig['aErrorLevelIds']['user_notice'], $aLoggerConfig['aErrorLevelIds']['user_error']); $a_logs = array(); foreach ($r_levels as $i_level) { if (isset($this->aLogLevels[$i_level])) $a_logs += $this->aLogLevels[$i_level]; } if (is_array($a_logs) && count($a_logs)>0) return $a_logs; return false; } /** * Function to return success notices if there are any. * @uses Logger::$aLogLevels * @uses $aLoggerConfig * @return bool */ public function ReturnSuccessNotices() { global $aLoggerConfig; return $this->ReturnNotices($aLoggerConfig['aErrorLevelIds']['success_notice']); }}?>