Bug fixes to reduce logging-related crashes

* Provide a method for plugins to report failure to initialise
* Check plugins initialised properly before adding to list of logging
backends
* Check the logger is available before trying to log a message
(might cause bugs if errors are logged very early in initialisation)
This commit is contained in:
2011-08-20 11:34:29 +01:00
parent fc33112097
commit 2781b63b68
4 changed files with 47 additions and 7 deletions

View File

@@ -30,5 +30,8 @@ class SihnonFramework_Exception_CacheObjectNotFound extends SihnonFramework_E
class SihnonFramework_Exception_InvalidPluginName extends SihnonFramework_Exception {}; class SihnonFramework_Exception_InvalidPluginName extends SihnonFramework_Exception {};
class SihnonFramework_Exception_LogException extends SihnonFramework_Exception {};
class SihnonFramework_Exception_LogFileNotWriteable extends SihnonFramework_Exception_LogException {};
class SihnonFramework_Exception_InvalidLog extends SihnonFramework_Exception_LogException {};
?> ?>

View File

@@ -15,6 +15,8 @@ class SihnonFramework_Log {
protected $plugins = array(); protected $plugins = array();
public function __construct(SihnonFramework_Config $config) { public function __construct(SihnonFramework_Config $config) {
$log = SihnonFramework_Main::instance()->log();
// Get a list of the logging plugins to be used // Get a list of the logging plugins to be used
$plugins = $config->get('logging.plugins'); $plugins = $config->get('logging.plugins');
@@ -22,12 +24,16 @@ class SihnonFramework_Log {
// Get a list of all the instances of this plugin to be used // Get a list of all the instances of this plugin to be used
$instances = $config->get("logging.{$plugin}"); $instances = $config->get("logging.{$plugin}");
foreach ($instances as $instance) { foreach ($instances as $instance) {
$this->plugins[$plugin][] = array( try {
'name' => $instance, $this->plugins[$plugin][] = array(
'backend' => Sihnon_Log_PluginFactory::create($config, $plugin, $instance), 'name' => $instance,
'severity' => $config->get("logging.{$plugin}.{$instance}.severity"), 'backend' => Sihnon_Log_PluginFactory::create($config, $plugin, $instance),
'category' => $config->get("logging.{$plugin}.{$instance}.category"), 'severity' => $config->get("logging.{$plugin}.{$instance}.severity"),
); 'category' => $config->get("logging.{$plugin}.{$instance}.category"),
);
} catch(SihnonFramework_Exception_LogException $e) {
SihnonFramework_LogEntry::warning($log, $e->getMessage());
}
} }
} }

View File

@@ -18,6 +18,9 @@ class SihnonFramework_Log_Plugin_FlatFile extends SihnonFramework_Log_PluginBase
$this->filename = $filename; $this->filename = $filename;
$this->format = $format; $this->format = $format;
// Verify the given log file can be written to
$this->verifyLogfile();
$this->fp = fopen($this->filename, 'a'); $this->fp = fopen($this->filename, 'a');
} }
@@ -32,6 +35,26 @@ class SihnonFramework_Log_Plugin_FlatFile extends SihnonFramework_Log_PluginBase
return new self($instance, $filename, $format); return new self($instance, $filename, $format);
} }
protected function verifyLogfile() {
// Check that the file exists, or can be created
$file_ok = false;
if (preg_match('#php://(stderr|stdout)#', $this->filename)) {
$file_ok = true;
} else if (file_exists($this->filename) && is_writable($this->filename)) {
$file_ok = true;
} else {
$directory = dirname($this->filename);
if (file_exists($directory) && is_writeable($directory)) {
$file_ok = true;
}
}
if (!$file_ok) {
throw new SihnonFramework_Exception_LogFileNotWriteable($this->filename);
}
}
/** /**
* Records a new entry in the storage backend used by this logging plugin * Records a new entry in the storage backend used by this logging plugin
* *

View File

@@ -125,13 +125,21 @@ class SihnonFramework_LogEntry {
} }
protected static function log($logger, $severity, $message, $category = SihnonFramework_Log::CATEGORY_DEFAULT) { protected static function log($logger, $severity, $message, $category = SihnonFramework_Log::CATEGORY_DEFAULT) {
if (!$logger) {
throw new SihnonFramework_Exception_InvalidLog();
}
$backtrace = debug_backtrace(false); $backtrace = debug_backtrace(false);
$entry = new static($severity, $category, time(), static::$localHostname, static::$localProgname, getmypid(), $backtrace[1]['file'], $backtrace[1]['line'], $message); $entry = new static($severity, $category, time(), static::$localHostname, static::$localProgname, getmypid(), $backtrace[1]['file'], $backtrace[1]['line'], $message);
$logger->log($entry); $logger->log($entry);
} }
public static function logInternal($logger, $severity, $file, $line, $message, $category = SihnonFramework_Log::CATEGORY_DEFAULT) { public static function logInternal($logger, $severity, $file, $line, $message, $category = SihnonFramework_Log::CATEGORY_DEFAULT) {
if (!$logger) {
throw new SihnonFramework_Exception_InvalidLog();
}
$entry = new static($severity, $category, time(), static::$localHostname, static::$localProgname, getmypid(), $file, $line, $message); $entry = new static($severity, $category, time(), static::$localHostname, static::$localProgname, getmypid(), $file, $line, $message);
$logger->log($entry); $logger->log($entry);
} }