From 7f81fa72456317e9f1d800904cead5301fce917e Mon Sep 17 00:00:00 2001 From: padams Date: Mon, 24 Dec 2007 08:39:10 +0000 Subject: [PATCH] - added new owa_error class replacing old. Errors are now buffered untill an error handler is specified from DB. This now means that one can log errors without worrying about what error handler might or might not be set. - refactored caller constructor to account for new approach to logging errors and re-organized a bit - removed references to old error class factory - added new error class factory to coreAPI --- modules/base/classes/cacheFacade.php | 4 +- modules/base/classes/error.php | 410 +++++++++++++++++++++++++++ modules/base/classes/settings.php | 1 + owa_base.php | 3 +- owa_caller.php | 80 ++++-- owa_coreAPI.php | 19 ++ owa_error.php | 306 -------------------- owa_httpRequest.php | 2 +- owa_observer.php | 2 +- 9 files changed, 497 insertions(+), 330 deletions(-) create mode 100644 modules/base/classes/error.php delete mode 100644 owa_error.php diff --git a/modules/base/classes/cacheFacade.php b/modules/base/classes/cacheFacade.php index 82739a6da..2cb3504f4 100644 --- a/modules/base/classes/cacheFacade.php +++ b/modules/base/classes/cacheFacade.php @@ -37,14 +37,14 @@ class owa_cacheFacade extends owa_cache { function __construct($cache_dir) { - $this->e = &owa_error::get_instance(); + $this->e = &owa_coreAPI::errorSingleton(); return parent::__construct($cache_dir); } function owa_cacheFacade($cache_dir) { - $this->e = &owa_error::get_instance(); + $this->e = &owa_coreAPI::errorSingleton(); return $this->owa_cache($cache_dir); } diff --git a/modules/base/classes/error.php b/modules/base/classes/error.php new file mode 100644 index 000000000..b0e91fede --- /dev/null +++ b/modules/base/classes/error.php @@ -0,0 +1,410 @@ + + * @copyright Copyright © 2006 Peter Adams + * @license http://www.gnu.org/copyleft/gpl.html GPL v2.0 + * @category owa + * @package owa + * @version $Revision$ + * @since owa 1.0.0 + */ +class owa_error { + + /** + * Instance of the current logger + * + * @var object + */ + var $logger; + + /** + * Buffered Msgs + * + * @var array + */ + var $bmsgs; + + var $hasChildren = false; + + var $init = false; + + + /** + * PHP4 Constructor + * + */ + function owa_error() { + + return __construct(); + + } + + + /** + * Constructor + * + */ + function __construct() { + + // setup composit logger + + $this->logger = &Log::singleton('composite'); + $this->addLogger('null'); + + return; + + } + + function __destruct() { + + return; + } + + function setErrorLevel() { + + return; + } + + function addLogger($type, $mask = null, $config = array()) { + + // make child logger + $child = $this->loggerFactory($type, $config); + + if (!empty($child)): + //set error level mask + if (!empty($mask)): + $child->setMask($mask); + endif; + + // add child to main composite logger + $ret = $this->logger->addChild($child); + else: + $ret = false; + endif; + + //set hasChildren flag + if ($ret == true): + $this->hasChildren = true; + else: + return false; + endif; + } + + function removeLogger($type) { + return false; + } + + + function setHandler($type) { + + switch ($type) { + case "development": + $this->createDevelopmentHandler(); + break; + case "cli_development": + $this->createCliDevelopmentHandler(); + break; + case "cli_production": + $this->createCliProductionHandler(); + break; + case "production": + $this->createProductionHandler(); + break; + default: + $this->createProductionHandler(); + } + + $this->init = true; + $this->logBufferedMsgs(); + + return; + + } + + function createDevelopmentHandler() { + + $mask = PEAR_LOG_ALL; + $this->addLogger('file', $mask); + + return; + } + + function createCliDevelopmentHandler() { + + $mask = PEAR_LOG_ALL; + $this->addLogger('file', $mask); + $this->addLogger('console', $mask); + + return; + } + + function createCliProductionHandler() { + + $file_mask = PEAR_LOG_ALL ^ Log::MASK(PEAR_LOG_DEBUG) ^ Log::MASK(PEAR_LOG_INFO); + $this->addLogger('file', $file_mask); + $mail_mask = Log::MASK(PEAR_LOG_EMERG) | Log::MASK(PEAR_LOG_CRIT) | Log::MASK(PEAR_LOG_ALERT); + $this->addLogger('mail', $mail_mask); + $this->addLogger('console', $file_mask); + + return; + } + + function createProductionHandler() { + + $file_mask = PEAR_LOG_ALL ^ Log::MASK(PEAR_LOG_DEBUG) ^ Log::MASK(PEAR_LOG_INFO); + $this->addLogger('file', $file_mask); + $mail_mask = Log::MASK(PEAR_LOG_EMERG) | Log::MASK(PEAR_LOG_CRIT) | Log::MASK(PEAR_LOG_ALERT); + $this->addLogger('mail', $mail_mask); + + return; + } + + + function debug($message) { + + return $this->log($message, PEAR_LOG_DEBUG); + + } + + function info($message) { + + return $this->log($message, PEAR_LOG_INFO); + } + + function notice($message) { + + return $this->log($message, PEAR_LOG_NOTICE); + } + + function warning($message) { + + return $this->log($message, PEAR_LOG_WARNING); + } + + function err($message) { + + return $this->log($message, PEAR_LOG_ERR); + + } + + function crit() { + + return $this->log($message, PEAR_LOG_CRIT); + + } + + function alert() { + + return $this->log($message, PEAR_LOG_ALERT); + + } + + function emerg() { + + return $this->log($message, PEAR_LOG_EMERG); + + } + + function log($err, $priority) { + + // log to normal logger + if ($this->init == true): + return $this->logger->log($err, $priority); + else: + return $this->bufferMsg($err, $priority); + endif; + + return; + } + + function bufferMsg($err, $priority) { + + $this->bmsgs[] = array('error' => $err, 'priority' => $priority); + return true; + } + + function logBufferedMsgs() { + + + if (!empty($this->bmsgs)): + foreach($this->bmsgs as $msg) { + + $this->log($msg['error'], $msg['priority']); + } + + $this->bmsgs = null; + endif; + + return; + + } + + + function loggerFactory($type, $config = array()) { + + switch ($type) { + case "display": + return $this->make_display_logger($config); + break; + case "window": + return $this->make_window_logger($config); + break; + case "file": + return $this->make_file_logger($config); + break; + case "syslog": + return $this->make_syslog_logger($config); + break; + case "mail": + return $this->make_mail_logger($config); + break; + case "console": + return $this->make_console_logger($config); + break; + case "firebug": + return $this->makeFirebugLogger($config); + break; + case "null": + return $this->make_null_logger(); + break; + default: + return false; + } + + } + + function makeFirebugLogger() { + + $logger = &Log::singleton('firebug', '', getmypid()); + return $logger; + } + + + /** + * Builds a null logger + * + * @return object + */ + function make_null_logger() { + + $logger = &Log::singleton('null'); + return $logger; + } + + + /** + * Builds a console logger + * + * @return object + */ + function make_console_logger() { + define('STDOUT', fopen("php://stdout", "r")); + $conf = array('stream' => STDOUT, 'buffering' => false); + $logger = &Log::singleton('console', '', getmypid(), $conf); + return $logger; + } + + /** + * Builds a logger that writes to a file. + * + * @return unknown + */ + function make_file_logger() { + + // fetch config object + $c = &owa_coreAPI::configSingleton(); + + // test to see if file is writable + $handle = @fopen($c->get('base', 'error_log_file'), "a"); + + if ($handle != false): + fclose($handle); + $conf = array('mode' => 0600, 'timeFormat' => '%X %x'); + $logger = &Log::singleton('file', $c->get('base', 'error_log_file'), getmypid(), $conf); + return $logger; + else: + return; + endif; + } + + /** + * Builds a logger that sends lines via email + * + * @return unknown + */ + function make_mail_logger() { + + // fetch config object + $c = &owa_coreAPI::configSingleton(); + + $conf = array('subject' => 'Important Error Log Events', 'from' => 'OWA-Error-Logger'); + $logger = &Log::singleton('mail', $c->get('base', 'notice_email'), getmypid(), $conf); + + return $logger; + } + + function logPhpErrors() { + + return set_error_handler(array("owa_error", "handlePhpError")); + + } + + + /** + * Alternative error handler for PHP specific errors. + * + * @param string $errno + * @param string $errmsg + * @param string $filename + * @param string $linenum + * @param string $vars + */ + function handlePhpError($errno = null, $errmsg, $filename, $linenum, $vars) { + + $dt = date("Y-m-d H:i:s (T)"); + + // set of errors for which a var trace will be saved + $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE); + + $err = "\n"; + $err .= "\t" . $dt . "\n"; + $err .= "\t" . $errno . "\n"; + $err .= "\t" . $errmsg . "\n"; + $err .= "\t" . $filename . "\n"; + $err .= "\t" . $linenum . "\n"; + + if (in_array($errno, $user_errors)) { + $err .= "\t" . wddx_serialize_value($vars, "Variables") . "\n"; + } + + $err .= "\n\n"; + + $this->log($err, $priority); + + return; + } + +} + +?> \ No newline at end of file diff --git a/modules/base/classes/settings.php b/modules/base/classes/settings.php index 4c88a20b2..973d6df2f 100644 --- a/modules/base/classes/settings.php +++ b/modules/base/classes/settings.php @@ -360,6 +360,7 @@ function getDefaultConfig() { 'notice_email' => '', 'log_php_errors' => false, 'error_handler' => 'development', + 'error_log_level' => 0, 'error_log_file' => OWA_BASE_DIR . '/logs/errors.txt', 'browscap.ini' => OWA_BASE_DIR . '/modules/base/data/php_browscap.ini', 'search_engines.ini' => OWA_BASE_DIR . '/conf/search_engines.ini', diff --git a/owa_base.php b/owa_base.php index eb6ed52df..910522d11 100644 --- a/owa_base.php +++ b/owa_base.php @@ -17,7 +17,6 @@ // require_once('owa_env.php'); -require_once('owa_error.php'); /** * OWA Base Class @@ -75,9 +74,9 @@ class owa_base { */ function owa_base() { + $this->e = &owa_coreAPI::errorSingleton(); $this->c = &owa_coreAPI::configSingleton(); $this->config = &$this->c->fetch('base'); - $this->e = &owa_error::get_instance(); return; diff --git a/owa_caller.php b/owa_caller.php index 4f359d0a2..16143f2ac 100644 --- a/owa_caller.php +++ b/owa_caller.php @@ -72,27 +72,68 @@ function owa_caller($config) { */ function __construct($config) { + // Start time $this->start_time = owa_lib::microtime_float(); + // Sets default config and error logger + $this->owa_base(); + + // Log init debug + $this->e->debug(sprintf('*** Open Web Analytics v%s ***', OWA_VERSION)); + //$bt = debug_backtrace(); + //$this->e->debug($bt[4]); + + + /** + * Super Global Default Config Overrides + * + * These are constants that can be defined in the config file, plugin, or caller + * the will override default config values + */ + + /* DATABASE CONNECTIONS */ + //load DB constants if not set already by caller - if(!defined('OWA_DB_HOST')): + if (!defined('OWA_DB_HOST')): $file = OWA_BASE_DIR.DIRECTORY_SEPARATOR.'conf'.DIRECTORY_SEPARATOR.'owa-config.php'; if (file_exists($file)): include ($file); else: - print "Uh-oh. I can't find your configuration file..."; + $this->e->emerg("Uh-oh. I can't find your configuration file..."); exit; endif; endif; - // Sets default config and error logger - $this->owa_base(); - //$bt = debug_backtrace(); - //$this->e->debug($bt[4]); + /* OBJECT CACHING */ + + // Looks for object cache config constant + if (!defined('OWA_OBJECT_CACHING')): + $config['cache_objects'] = OWA_OBJECT_CACHING; + endif; + + /* ERROR LOGGING */ + // Looks for log level constant + if (!defined('OWA_ERROR_LOG_LEVEL')): + $config['error_log_level'] = OWA_ERROR_LOG_LEVEL; + endif; + + // log PHP warnings and errors + if (OWA_LOG_PHP_ERRORS === true): + $this->e->logPhpErrors(); + endif; + + + /** + * User Settings Config Overrides + * + * These overrides come from user settings stored in the database + */ + + // sets config ID is not already set if (empty($config['configuration_id'])): $config['configuration_id'] = 1; endif; @@ -103,26 +144,29 @@ function __construct($config) { $this->c->load($config['configuration_id']); endif; + /** + * Run-time Config Overrides + * + */ + // Applies run time config overrides $this->c->applyModuleOverrides('base', $config); - $this->e->debug('applying caller config overrides.'); + $this->e->debug('caller config overrides applied.'); // re-fetch the array now that overrides have been applied. // needed for backwards compatability $this->config = $this->c->fetch('base'); - // log PHP warnings and errors - if (OWA_LOG_PHP_ERRORS === true): - set_error_handler(array("owa_error", "handlePhpError")); - endif; - - // reloads error logger now that final config values are in place - $this->e = null; - $this->e = owa_error::get_instance(); - // Log init debug - $this->e->debug(sprintf('*** Open Web Analytics v%s ***', OWA_VERSION)); - + /** + * Post Config Framework Setup + * + */ + + // Sets the correct mode of the error logger now that final config values are in place + // This will flush buffered msgs that were thrown up untill this point + $this->e->setHandler($this->c->get('base', 'error_handler')); + // Create Request Container $this->params = &owa_requestContainer::getInstance(); diff --git a/owa_coreAPI.php b/owa_coreAPI.php index 6ea03ee37..e700dbc44 100644 --- a/owa_coreAPI.php +++ b/owa_coreAPI.php @@ -126,6 +126,25 @@ function &configSingleton($params = array()) { return $config; } + function &errorSingleton() { + + static $e; + + if(!isset($e)): + + if (!class_exists('owa_error')): + require_once(OWA_BASE_CLASS_DIR.'error.php'); + endif; + + $e = owa_coreAPI::supportClassFactory('base', 'error'); + + endif; + + return $e; + } + + + function &cacheSingleton($params = array()) { static $cache; diff --git a/owa_error.php b/owa_error.php deleted file mode 100644 index ffcc377ea..000000000 --- a/owa_error.php +++ /dev/null @@ -1,306 +0,0 @@ - - * @copyright Copyright © 2006 Peter Adams - * @license http://www.gnu.org/copyleft/gpl.html GPL v2.0 - * @category owa - * @package owa - * @version $Revision$ - * @since owa 1.0.0 - */ -class owa_error { - - /** - * Configuration - * - * @var array - */ - var $config = array(); - - /** - * Instance of the current logger - * - * @var object - */ - var $logger; - - /** - * Error priority - * - * @var unknown_type - */ - var $priority; - - /** - * Gets instance of error logger - * - * @return object $logger - */ - function &get_instance() { - - static $logger; - - if (!isset($logger)): - - $c = &owa_coreAPI::configSingleton(); - $config = $c->fetch('base'); - - switch ($config['error_handler']) { - - case "development": - - //$config['debug_to_screen'] = true; - //$window = owa_error::make_window_logger(); - $logger = &Log::singleton('composite'); - $file = owa_error::make_file_logger(); - - if (!empty($file)): - $file_mask = PEAR_LOG_ALL; - $file->setMask($file_mask); - $logger->addChild($file); - endif; - - //$logger->addChild($window); - - break; - - case "async_development": - - $logger = &Log::singleton('composite'); - - $file = owa_error::make_file_logger(); - - if (!empty($file)): - $logger->addChild($file); - endif; - - $console = owa_error::make_console_logger(); - $logger->addChild($console); - - break; - - case "production": - - $logger = &Log::singleton('composite'); - - $mail = owa_error::make_mail_logger(); - $mail_mask = Log::MASK(PEAR_LOG_EMERG) | Log::MASK(PEAR_LOG_CRIT) | Log::MASK(PEAR_LOG_ALERT); - //$mail_mask = PEAR_LOG_ALL; - $mail->setMask($mail_mask); - $logger->addChild($mail); - - $file = owa_error::make_file_logger(); - - if (!empty($file)): - $file_mask = PEAR_LOG_ALL ^ Log::MASK(PEAR_LOG_DEBUG) ^ Log::MASK(PEAR_LOG_INFO); - $file->setMask($file_mask); - $logger->addChild($file); - endif; - - break; - - default: - $file = owa_error::make_file_logger(); - $file_mask = PEAR_LOG_ALL ^ Log::MASK(PEAR_LOG_DEBUG); - $file->setMask($file_mask); - $mail = owa_error::make_mail_logger(); - $mail_mask = Log::MASK(PEAR_LOG_EMERG) | Log::MASK(PEAR_LOG_CRIT) | Log::MASK(PEAR_LOG_ALERT); - $mail_mask = PEAR_LOG_ALL; - $mail->setMask($mail_mask); - $logger = &Log::singleton('composite'); - $logger->addChild($mail); - $logger->addChild($file); - - } - - endif; - - return $logger; - } - - /** - * Returns the buffered error output - * - * @return unknown - */ - function &get_msgs() { - - static $msgs; - return $msgs; - } - - /** - * Interface to build various loggers - * - * @param unknown_type $type - */ - function make_logger($type) { - - switch ($type) { - case "display": - $this->make_display_logger(); - break; - case "window": - $this->make_window_logger(); - break; - case "file": - $this->make_file_logger(); - break; - case "syslog": - $this->make_syslog_logger(); - break; - case "mail": - $this->make_mail_logger(); - break; - case "console": - $this->make_console_logger(); - break; - } - - return; - } - - /** - * Builds a logger that writes to a seperate browser window. - * This uses a custom log handler that writes output to a temp static variable. - * - * @return object - */ - function make_window_logger() { - - $conf = array('title' => 'Error Log Output'); - $logger = &Log::singleton('winstatic', 'LogWindow', getmypid(), $conf); - return $logger; - } - /** - * Builds a logger that writes to the browser window. - * - * @todo build a custom handler that writes output ot temp static varibale - * @return object - */ - function make_display_logger() { - - $conf = array('error_prepend' => '', 'error_append' => ''); - $logger = &Log::singleton('display', '', getmypid(), $conf); - return $logger; - } - - function make_console_logger() { - define('STDOUT', fopen("php://stdout", "r")); - $conf = array('stream' => STDOUT, 'buffering' => false); - $logger = &Log::singleton('console', '', getmypid(), $conf); - return $logger; - } - - /** - * Builds a logger that writes to a file. - * - * @return unknown - */ - function make_file_logger() { - - $handle = @fopen($this->config['error_log_file'], "a"); - - if ($handle != false): - fclose($handle); - $conf = array('mode' => 0600, 'timeFormat' => '%X %x'); - $logger = &Log::singleton('file', $this->config['error_log_file'], getmypid(), $conf); - return $logger; - else: - return; - endif; - } - - /** - * Builds a logger that sends lines via email - * - * @return unknown - */ - function make_mail_logger() { - - $conf = array('subject' => 'Important Error Log Events', 'from' => 'OWA-Error-Logger'); - $logger = &Log::singleton('mail', $this->config['notice_email'], getmypid(), $conf); - return $logger; - } - - /** - * Builds a composite logger object - * - * @param array $loggers - * @return object - */ - function make_composite_logger($loggers) { - - $logger = &Log::singleton('composite'); - - foreach ($loggers as $key) { - - $this->logger->addChild($key); - } - - return $logger; - } - - /** - * Alternative error handler for PHP specific errors. - * - * @param string $errno - * @param string $errmsg - * @param string $filename - * @param string $linenum - * @param string $vars - */ - function handlePhpError($errno = null, $errmsg, $filename, $linenum, $vars) { - - $dt = date("Y-m-d H:i:s (T)"); - - // set of errors for which a var trace will be saved - $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE); - - $err = "\n"; - $err .= "\t" . $dt . "\n"; - $err .= "\t" . $errno . "\n"; - $err .= "\t" . $errmsg . "\n"; - $err .= "\t" . $filename . "\n"; - $err .= "\t" . $linenum . "\n"; - - if (in_array($errno, $user_errors)) { - $err .= "\t" . wddx_serialize_value($vars, "Variables") . "\n"; - } - - $err .= "\n\n"; - $conf = array('mode' => 0600, 'timeFormat' => '%X %x'); - $c = &owa_coreAPI::configSingleton(); - $config = $c->fetch('base'); - $logger = &Log::singleton('file', $config['error_log_file'], getmypid(), $conf); - $file_mask = PEAR_LOG_ALL; - $logger->setMask($file_mask); - $logger->log($err, $priority); - - return; - } - -} - -?> \ No newline at end of file diff --git a/owa_httpRequest.php b/owa_httpRequest.php index 51b565d5a..40d5ae987 100644 --- a/owa_httpRequest.php +++ b/owa_httpRequest.php @@ -74,7 +74,7 @@ function owa_http() { $c = &owa_coreAPI::configSingleton(); $this->config = $c->fetch('base'); - $this->e = &owa_error::get_instance(); + $this->e = &owa_coreAPI::errorSingleton(); $this->agent = $this->config['owa_user_agent']; return; diff --git a/owa_observer.php b/owa_observer.php index 6c30a2323..efa829102 100644 --- a/owa_observer.php +++ b/owa_observer.php @@ -78,7 +78,7 @@ function owa_observer($priority = PEAR_LOG_INFO) $c = &owa_coreAPI::configSingleton(); $this->config = $c->fetch('base'); - $this->e = &owa_error::get_instance(); + $this->e = &owa_coreAPI::errorSingleton(); $this->api = &owa_coreAPI::singleton(); return; }