Bootstrap: Safe application start

Log exceptions and inform user if something goes wrong.

refs #4625
refs #4592
This commit is contained in:
Marius Hein 2013-08-23 09:57:32 +02:00 committed by Matthias Jentsch
parent 2debc7826b
commit afc302d45c
5 changed files with 432 additions and 212 deletions

View File

@ -101,6 +101,7 @@ class PreferenceController extends BasePreferenceController
$this->view->exceptionMessage = $e->getMessage(); $this->view->exceptionMessage = $e->getMessage();
} }
} }
$this->view->form = $form; $this->view->form = $form;
} }
} }

View File

@ -30,14 +30,14 @@ namespace Icinga\Application;
use \DateTimeZone; use \DateTimeZone;
use \Exception; use \Exception;
use Zend_Loader_Autoloader; use \Zend_Loader_Autoloader;
use Icinga\Application\Modules\Manager as ModuleManager; use \Icinga\Application\Modules\Manager as ModuleManager;
use Icinga\Application\Platform; use \Icinga\Application\Platform;
use \Icinga\Application\Config; use \Icinga\Application\Config;
use Icinga\Exception\ProgrammingError; use \Icinga\Exception\ProgrammingError;
use \Icinga\Application\DbAdapterFactory; use \Icinga\Application\DbAdapterFactory;
use Icinga\Exception\ConfigurationError; use \Icinga\Exception\ConfigurationError;
use Icinga\Util\DateTimeFactory; use \Icinga\Util\DateTimeFactory;
/** /**
* This class bootstraps a thin Icinga application layer * This class bootstraps a thin Icinga application layer
@ -121,8 +121,6 @@ abstract class ApplicationBootstrap
/** /**
* Constructor * Constructor
*
* The constructor is protected to avoid incorrect usage
*/ */
protected function __construct($configDir) protected function __construct($configDir)
{ {
@ -212,7 +210,8 @@ abstract class ApplicationBootstrap
* *
* Optional append sub directory * Optional append sub directory
* *
* @param null|string $subdir optional subdir * @param string $subdir optional subdir
*
* @return string * @return string
*/ */
public function getApplicationDir($subdir = null) public function getApplicationDir($subdir = null)
@ -222,7 +221,9 @@ abstract class ApplicationBootstrap
/** /**
* Getter for config dir * Getter for config dir
* @param string|null $subdir *
* @param string $subdir
*
* @return string * @return string
*/ */
public function getConfigDir($subdir = null) public function getConfigDir($subdir = null)
@ -234,7 +235,8 @@ abstract class ApplicationBootstrap
* Helper to glue directories together * Helper to glue directories together
* *
* @param string $dir * @param string $dir
* @param string|null $subdir * @param string $subdir
*
* @return string * @return string
*/ */
private function getDirWithSubDir($dir, $subdir = null) private function getDirWithSubDir($dir, $subdir = null)
@ -250,19 +252,51 @@ abstract class ApplicationBootstrap
* Starting concrete bootstrap classes * Starting concrete bootstrap classes
* *
* @param string $configDir * @param string $configDir
*
* @return ApplicationBootstrap * @return ApplicationBootstrap
*/ */
public static function start($configDir) public static function start($configDir)
{ {
$class = get_called_class(); $class = get_called_class();
/** @var ApplicationBootstrap $obj */ /** @var ApplicationBootstrap $obj */
$obj = new $class($configDir); $application = new $class($configDir);
$obj->bootstrap(); $application->bootstrap();
return $obj;
if (Logger::hasErrorsOccurred()) {
$application->stopApplication(Logger::getQueue());
}
return $application;
} }
/** /**
* Setup icinga auto loader * Stop application and show information about errors
*
* @param array $errors
*/
public function stopApplication(array $errors = array())
{
$msg = "Application could not be started!\n\n";
if (count($errors)) {
foreach ($errors as $error) {
$msg .= $error[0]. "\n";
}
} else {
$msg .= "Further information about the error may have been written to the application's log file.\n"
. 'Please check it in order to analyse the problem.';
}
if ($this->isWeb()) {
$msg = nl2br($msg);
}
echo $msg;
die();
}
/**
* Setup Icinga auto loader
* *
* @return self * @return self
*/ */

View File

@ -28,53 +28,74 @@
namespace Icinga\Application; namespace Icinga\Application;
use Icinga\Exception\ConfigurationError; use \Zend_Config;
use \Zend_Log;
use \Zend_Log_Filter_Priority;
use \Zend_Log_Writer_Abstract;
use \Zend_Log_Exception;
use \Icinga\Exception\ConfigurationError;
/** /**
* Class Logger * Singleton logger
* @package Icinga\Application
*/ */
class Logger final class Logger
{ {
/** /**
* * Default log type
*/ */
const DEFAULT_LOG_TYPE = "stream"; const DEFAULT_LOG_TYPE = "stream";
/** /**
* * Default log target
*/ */
const DEFAULT_LOG_TARGET = "./var/log/icinga.log"; const DEFAULT_LOG_TARGET = "./var/log/icinga.log";
/** /**
* * Default debug target
*/ */
const DEFAULT_DEBUG_TARGET = "./var/log/icinga.debug.log"; const DEFAULT_DEBUG_TARGET = "./var/log/icinga.debug.log";
/** /**
* Array of writers
*
* @var array * @var array
*/ */
private $writers = array(); private $writers = array();
/** /**
* @var null * Instance of Zend_Log
*
* @var Zend_Log
*/ */
private $logger = null; private $logger;
/** /**
* @var * Singleton instance
*
* @var Logger
*/ */
private static $instance; private static $instance;
/** /**
* Queue of unwritten messages
*
* @var array * @var array
*/ */
private static $queue = array(); private static $queue = array();
/** /**
* @param \Zend_Config $config * Flag indicate that errors occurred in the past
*
* @var bool
*/ */
public function __construct(\Zend_Config $config) private static $errorsOccurred = false;
/**
* Create a new logger object
*
* @param Zend_Config $config
*/
public function __construct(Zend_Config $config)
{ {
$this->overwrite($config); $this->overwrite($config);
} }
@ -88,9 +109,13 @@ class Logger
} }
/** /**
* @param \Zend_Config $config * Overwrite config to initiated logger
*
* @param Zend_Config $config
*
* @return self
*/ */
public function overwrite(\Zend_Config $config) public function overwrite(Zend_Config $config)
{ {
$this->clearLog(); $this->clearLog();
try { try {
@ -98,82 +123,112 @@ class Logger
$this->setupDebugLog($config); $this->setupDebugLog($config);
} }
} catch (ConfigurationError $e) { } catch (ConfigurationError $e) {
$this->warn("Could not create debug log: {$e->getMessage()}"); $this->warn('Could not create debug log: ' . $e->getMessage());
} }
$this->setupLog($config); $this->setupLog($config);
$this->flushQueue(); $this->flushQueue();
return $this;
} }
/** /**
* @param \Zend_Config $config * Configure debug log
*
* @param Zend_Config $config
*/ */
private function setupDebugLog(\Zend_Config $config) private function setupDebugLog(Zend_Config $config)
{ {
$type = $config->debug->get("type", self::DEFAULT_LOG_TYPE); $type = $config->debug->get("type", self::DEFAULT_LOG_TYPE);
$target = $config->debug->get("target", self::DEFAULT_LOG_TARGET); $target = $config->debug->get("target", self::DEFAULT_LOG_TARGET);
if ($target == self::DEFAULT_LOG_TARGET) { if ($target == self::DEFAULT_LOG_TARGET) {
$type == self::DEFAULT_LOG_TYPE; $type = self::DEFAULT_LOG_TYPE;
} }
$this->addWriter($type, $target, \Zend_Log::DEBUG); $this->addWriter($type, $target, Zend_Log::DEBUG);
} }
/** /**
* @param \Zend_Config $config * Configure log
*
* @param Zend_Config $config
*/ */
private function setupLog(\Zend_Config $config) private function setupLog(Zend_Config $config)
{ {
$type = $config->get("type", self::DEFAULT_LOG_TYPE); $type = $config->get("type", self::DEFAULT_LOG_TYPE);
$target = $config->get("target", self::DEFAULT_DEBUG_TARGET); $target = $config->get("target", self::DEFAULT_DEBUG_TARGET);
if ($target == self::DEFAULT_DEBUG_TARGET) { if ($target == self::DEFAULT_DEBUG_TARGET) {
$type == self::DEFAULT_LOG_TYPE; $type = self::DEFAULT_LOG_TYPE;
} }
$level = \Zend_Log::WARN; $level = Zend_Log::WARN;
if ($config->get("verbose", 0) == 1) { if ($config->get("verbose", 0) == 1) {
$level = \Zend_Log::INFO; $level = Zend_Log::INFO;
} }
$this->addWriter($type, $target, $level); $this->addWriter($type, $target, $level);
} }
/** /**
* @param $type * Add writer to log instance
* @param $target *
* @param $priority * @param string $type Type, e.g. stream
* @param string $target Target, e.g. filename
* @param int $priority Value of Zend::* constant
* @throws ConfigurationError * @throws ConfigurationError
*/ */
private function addWriter($type, $target, $priority) private function addWriter($type, $target, $priority)
{ {
$type[0] = strtoupper($type[0]); $type[0] = strtoupper($type[0]);
$writerClass = "\Zend_Log_Writer_" . $type; $writerClass = "Zend_Log_Writer_" . $type;
if (!class_exists($writerClass)) {
throw new ConfigurationError("Could not create log: Unknown type " . $type); if (!@class_exists($writerClass)) {
self::fatal(
'Could not add log writer of type "%s". Type does not exist.',
$type
);
return;
} }
try {
/** @var Zend_Log_Writer_Abstract $writer */
$writer = new $writerClass($target); $writer = new $writerClass($target);
$writer->addFilter(new Zend_Log_Filter_Priority($priority));
$writer->addFilter(new \Zend_Log_Filter_Priority($priority));
$this->logger->addWriter($writer); $this->logger->addWriter($writer);
$this->writers[] = $writer; $this->writers[] = $writer;
} catch (Zend_Log_Exception $e) {
self::fatal(
'Could not add log writer of type %s. An exception was thrown: %s',
$type,
$e->getMessage()
);
}
} }
/** /**
* flushQueue * Flush pending messages to writer
*/ */
public function flushQueue() public function flushQueue()
{ {
try {
foreach (self::$queue as $msgTypePair) { foreach (self::$queue as $msgTypePair) {
$this->logger->log($msgTypePair[0], $msgTypePair[1]); $this->logger->log($msgTypePair[0], $msgTypePair[1]);
} }
} catch (Zend_Log_Exception $e) {
self::fatal(
'Could not flush logs to output. An exception was thrown: %s',
$e->getMessage()
);
}
} }
/** /**
* Format output message
*
* @param array $argv * @param array $argv
*
* @return string * @return string
*/ */
public static function formatMessage(array $argv) public static function formatMessage(array $argv)
{ {
if (count($argv) == 1) { if (count($argv) == 1) {
$format = $argv[0]; $format = $argv[0];
} else { } else {
@ -192,20 +247,23 @@ class Logger
} }
/** /**
* clearLog * Reset object configuration
*/ */
public function clearLog() public function clearLog()
{ {
$this->logger = null; $this->logger = null;
$this->writers = array(); $this->writers = array();
$this->logger = new \Zend_Log(); $this->logger = new Zend_Log();
} }
/** /**
* @param \Zend_Config $config * Create an instance
*
* @param Zend_Config $config
*
* @return Logger * @return Logger
*/ */
public static function create(\Zend_Config $config) public static function create(Zend_Config $config)
{ {
if (self::$instance) { if (self::$instance) {
return self::$instance->overwrite($config); return self::$instance->overwrite($config);
@ -214,54 +272,60 @@ class Logger
} }
/** /**
* debug * Log message with severity debug
*/ */
public static function debug() public static function debug()
{ {
self::log(self::formatMessage(func_get_args()), \Zend_Log::DEBUG); self::log(self::formatMessage(func_get_args()), Zend_Log::DEBUG);
} }
/** /**
* * Log message with severity warn
*/ */
public static function warn() public static function warn()
{ {
self::log(self::formatMessage(func_get_args()), \Zend_Log::WARN); self::log(self::formatMessage(func_get_args()), Zend_Log::WARN);
} }
/** /**
* * Log message with severity info
*/ */
public static function info() public static function info()
{ {
self::log(self::formatMessage(func_get_args()), \Zend_Log::INFO); self::log(self::formatMessage(func_get_args()), Zend_Log::INFO);
} }
/** /**
* * Log message with severity error
*/ */
public static function error() public static function error()
{ {
self::log(self::formatMessage(func_get_args()), \Zend_Log::ERR); self::log(self::formatMessage(func_get_args()), Zend_Log::ERR);
} }
/** /**
* * Log message with severity fatal
*/ */
public static function fatal() public static function fatal()
{ {
self::log(self::formatMessage(func_get_args()), \Zend_Log::EMERG); self::log(self::formatMessage(func_get_args()), Zend_Log::EMERG);
} }
/** /**
* @param $msg * Log message
* @param int $level *
* @param string $msg Message
* @param int $level Log level
*/ */
private static function log($msg, $level = \Zend_Log::INFO) private static function log($msg, $level = Zend_Log::INFO)
{ {
$logger = self::$instance; $logger = self::$instance;
if (!$logger) { if ($level < Zend_Log::WARN && self::$errorsOccurred === false) {
self::$errorsOccurred =true;
}
if (!$logger || !count($logger->getWriters())) {
array_push(self::$queue, array($msg, $level)); array_push(self::$queue, array($msg, $level));
return; return;
} }
@ -270,7 +334,29 @@ class Logger
} }
/** /**
* Flag if messages > warning occurred
* *
* @return bool
*/
public static function hasErrorsOccurred()
{
return self::$errorsOccurred;
}
/**
* Access the log queue
*
* The log queue holds messages that could not be written to output
*
* @return array
*/
public static function getQueue()
{
return self::$queue;
}
/**
* Reset object state
*/ */
public static function reset() public static function reset()
{ {

View File

@ -28,15 +28,7 @@
namespace Icinga\Application; namespace Icinga\Application;
use \Icinga\Authentication\Manager as AuthenticationManager; use \Exception;
use \Icinga\Exception\ConfigurationError;
use \Icinga\User\Preferences;
use \Icinga\User;
use \Icinga\Web\Request;
use \Icinga\Web\View;
use \Icinga\User\Preferences\StoreFactory;
use \Icinga\User\Preferences\SessionStore;
use \Zend_Controller_Front;
use \Zend_Layout; use \Zend_Layout;
use \Zend_Config; use \Zend_Config;
use \Zend_Paginator; use \Zend_Paginator;
@ -44,6 +36,16 @@ use \Zend_View_Helper_PaginationControl;
use \Zend_Controller_Action_HelperBroker; use \Zend_Controller_Action_HelperBroker;
use \Zend_Controller_Router_Route; use \Zend_Controller_Router_Route;
use \Zend_Controller_Action_Helper_ViewRenderer; use \Zend_Controller_Action_Helper_ViewRenderer;
use \Zend_Controller_Front;
use \Icinga\Authentication\Manager as AuthenticationManager;
use \Icinga\Exception\ConfigurationError;
use \Icinga\User\Preferences;
use \Icinga\User\Preferences\LoadInterface;
use \Icinga\User;
use \Icinga\Web\Request;
use \Icinga\Web\View;
use \Icinga\User\Preferences\StoreFactory;
use \Icinga\User\Preferences\SessionStore;
/** /**
* Use this if you want to make use of Icinga functionality in other web projects * Use this if you want to make use of Icinga functionality in other web projects
@ -228,40 +230,73 @@ class Web extends ApplicationBootstrap
); );
if ($authenticationManager->isAuthenticated() === true) { if ($authenticationManager->isAuthenticated() === true) {
if ($this->getConfig()->preferences === null) {
throw new ConfigurationError('Preferences not configured in config.ini');
}
$user = $authenticationManager->getUser(); $user = $authenticationManager->getUser();
if (is_dir($this->getConfig()->preferences->configPath) === false) {
$this->getConfig()->preferences->configPath = Config::app()
->get('preferences', new Zend_Config(array()))
->get('configPath', $this->getConfigDir('preferences'));
}
$preferenceStore = StoreFactory::create(
$this->getConfig()->preferences,
$user
);
// Needed to update values in user session // Needed to update values in user session
$sessionStore = new SessionStore($authenticationManager->getSession()); $sessionStore = new SessionStore($authenticationManager->getSession());
// Performance: Do not ask provider if we've preferences // Performance: Do not ask provider if we've preferences
// stored in session // stored in session
$initialPreferences = array(); $initialPreferences = array();
$preferencesLoaded = false;
if (count($sessionStore->load())) { if (count($sessionStore->load())) {
$initialPreferences = $sessionStore->load(); $initialPreferences = $sessionStore->load();
} else { $preferencesLoaded = true;
$initialPreferences = $preferenceStore->load();
$sessionStore->writeAll($initialPreferences);
} }
$preferences = new Preferences($initialPreferences); $preferences = new Preferences($initialPreferences);
$preferences->attach($sessionStore); $preferences->attach($sessionStore);
if ($this->getConfig()->preferences !== null) {
if (is_dir($this->getConfig()->preferences->configPath) === false) {
Logger::error(
'Path for preferences not found (IniStore, "%s"). Using default one: "%s"',
$this->getConfig()->preferences->configPath,
$this->getConfigDir('preferences')
);
$this->getConfig()->preferences->configPath = $this->getConfigDir('preferences');
}
$preferenceStore = null;
try {
$preferenceStore = StoreFactory::create(
$this->getConfig()->preferences,
$user
);
$preferences->attach($preferenceStore); $preferences->attach($preferenceStore);
} catch (Exception $e) {
Logger::fatal(
'Could not create create preferences provider. '
. 'An exception during bootstrap was thrown: %s',
$e->getMessage()
);
}
if ($preferencesLoaded === false && $preferenceStore instanceof LoadInterface) {
try {
$initialPreferences = $preferenceStore->load();
} catch (Exception $e) {
Logger::fatal(
'%s::%s: Could not load preferences from provider. '
. 'An exception during bootstrap was thrown: %s',
__CLASS__,
__FUNCTION__,
$e->getMessage()
);
}
$sessionStore->writeAll($initialPreferences);
}
} else {
Logger::error(
'Preferences are not configured. Refer to the documentation to setup a valid provider. '
. 'We will use session store only. Preferences are not persisted after logout'
);
}
$user->setPreferences($preferences); $user->setPreferences($preferences);

View File

@ -1,24 +1,47 @@
<?php <?php
// {{{ICINGA_LICENSE_HEADER}}}
/**
* This file is part of Icinga 2 Web.
*
* Icinga 2 Web - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* @copyright 2013 Icinga Development Team <info@icinga.org>
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
* @author Icinga Development Team <info@icinga.org>
*/
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Application; namespace Tests\Icinga\Application;
require_once("Zend/Log.php"); require_once 'Zend/Log.php';
require_once("Zend/Config.php"); require_once 'Zend/Config.php';
require_once("Zend/Log/Writer/Mock.php"); require_once 'Zend/Log/Writer/Mock.php';
require_once("Zend/Log/Writer/Null.php"); require_once 'Zend/Log/Writer/Null.php';
require_once("Zend/Log/Filter/Priority.php"); require_once 'Zend/Log/Filter/Priority.php';
require_once("../../library/Icinga/Application/Logger.php"); require_once realpath(__DIR__ . '/../../../../../library/Icinga/Application/Logger.php');
require_once("../../library/Icinga/Exception/ConfigurationError.php"); require_once realpath(__DIR__ . '/../../../../../library/Icinga/Exception/ConfigurationError.php');
use \Icinga\Application\Logger;
use \Icinga\Application\Logger as Logger;
/** /**
* * Test class for Logger
* Test class for Logger **/
* Created Thu, 07 Feb 2013 10:07:13 +0000
*
**/
class LoggerTest extends \PHPUnit_Framework_TestCase class LoggerTest extends \PHPUnit_Framework_TestCase
{ {
private $timeZone; private $timeZone;
@ -28,132 +51,173 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
date_default_timezone_set('GMT'); date_default_timezone_set('GMT');
} }
public function testOverwrite() { public function testOverwrite()
$cfg1 = new \Zend_Config(array( {
"debug" => array("enable" => 0), $cfg1 = new \Zend_Config(
"type" => "mock", array(
"target" => "target2" 'debug' => array('enable' => 0),
)); 'type' => 'mock',
$cfg2 = new \Zend_Config(array( 'target' => 'target2'
"debug" => array( )
"enable" => 1, );
"type"=>"mock", $cfg2 = new \Zend_Config(
"target"=>"target3" array(
'debug' => array(
'enable' => 1,
'type'=>'mock',
'target'=>'target3'
), ),
"type" => "mock", 'type' => 'mock',
"target" => "target4" 'target' => 'target4'
)); )
);
$logger = new Logger($cfg1); $logger = new Logger($cfg1);
$writers = $logger->getWriters(); $writers = $logger->getWriters();
$this->assertEquals(1,count($writers)); $this->assertEquals(1, count($writers));
$logger = new Logger($cfg1); $logger = new Logger($cfg1);
$writers2 = $logger->getWriters(); $writers2 = $logger->getWriters();
$this->assertEquals(1,count($writers)); $this->assertEquals(1, count($writers));
$this->assertNotEquals($writers[0],$writers2[0]); $this->assertNotEquals($writers[0], $writers2[0]);
$logger = new Logger($cfg2); $logger = new Logger($cfg2);
$writers2 = $logger->getWriters(); $writers2 = $logger->getWriters();
$this->assertEquals(2,count($writers2)); $this->assertEquals(2, count($writers2));
} }
public function testFormatMessage()
{
$message = Logger::formatMessage(array('Testmessage'));
$this->assertEquals('Testmessage', $message);
public function testFormatMessage() { $message = Logger::formatMessage(array('Testmessage %s %s', 'test1', 'test2'));
$message = Logger::formatMessage(array("Testmessage")); $this->assertEquals('Testmessage test1 test2', $message);
$this->assertEquals("Testmessage",$message);
$message = Logger::formatMessage(array("Testmessage %s %s","test1","test2")); $message = Logger::formatMessage(array('Testmessage %s', array('test1', 'test2')));
$this->assertEquals("Testmessage test1 test2",$message); $this->assertEquals('Testmessage '.json_encode(array('test1', 'test2')), $message);
$message = Logger::formatMessage(array("Testmessage %s",array("test1","test2")));
$this->assertEquals("Testmessage ".json_encode(array("test1","test2")),$message);
} }
/**
* @backupStaticAttributes enabled
*/
public function testLoggingOutput()
{
$cfg1 = new \Zend_Config(
array(
'debug' => array('enable' => 0),
'type' => 'mock',
'target' => 'target2'
)
);
public function testLoggingOutput() {
$cfg1 = new \Zend_Config(array(
"debug" => array("enable" => 0),
"type" => "mock",
"target" => "target2"
));
Logger::reset();
$logger = Logger::create($cfg1); $logger = Logger::create($cfg1);
$writers = $logger->getWriters(); $writers = $logger->getWriters();
$logger->warn("Warning"); $logger->warn('Warning');
$logger->error("Error"); $logger->error('Error');
$logger->info("Info"); $logger->info('Info');
$logger->debug("Debug"); $logger->debug('Debug');
$writer = $writers[0]; $writer = $writers[0];
$this->assertEquals(2,count($writer->events)); $this->assertEquals(2, count($writer->events));
$this->assertEquals($writer->events[0]["message"],"Warning"); $this->assertEquals($writer->events[0]['message'], 'Warning');
$this->assertEquals($writer->events[1]["message"],"Error"); $this->assertEquals($writer->events[1]['message'], 'Error');
Logger::reset();
} }
public function testLogQueuing() { /**
$cfg1 = new \Zend_Config(array( * @backupStaticAttributes enabled
"debug" => array("enable" => 0), */
"type" => "mock", public function testLogQueuing()
"target" => "target2" {
)); $cfg1 = new \Zend_Config(
array(
'debug' => array('enable' => 0),
'type' => 'mock',
'target' => 'target2'
)
);
Logger::reset(); Logger::warn('Warning');
Logger::warn("Warning"); Logger::error('Error');
Logger::error("Error"); Logger::info('Info');
Logger::info("Info"); Logger::debug('Debug');
Logger::debug("Debug");
$logger = Logger::create($cfg1); $logger = Logger::create($cfg1);
$writers = $logger->getWriters(); $writers = $logger->getWriters();
$writer = $writers[0]; $writer = $writers[0];
$this->assertEquals(2,count($writer->events)); $this->assertEquals(2, count($writer->events));
$this->assertEquals($writer->events[0]["message"],"Warning"); $this->assertEquals($writer->events[0]['message'], 'Warning');
$this->assertEquals($writer->events[1]["message"],"Error"); $this->assertEquals($writer->events[1]['message'], 'Error');
Logger::reset();
} }
/**
* @backupStaticAttributes enabled
*/
public function testDebugLogErrorCatching() public function testDebugLogErrorCatching()
{ {
$cfg1 = new \Zend_Config(array( $cfg1 = new \Zend_Config(
"debug" => array( array(
"enable" => 1, 'debug' => array(
"type" => 'Invalid', 'enable' => 1,
"target" => "..." 'type' => 'Invalid',
'target' => '...'
), ),
"type" => "mock", 'type' => 'mock',
"target" => "target2" 'target' => 'target2'
)); )
Logger::reset(); );
$logger = Logger::create($cfg1); $logger = Logger::create($cfg1);
$writers = $logger->getWriters(); $writers = $logger->getWriters();
$this->assertEquals(1,count($writers)); $this->assertEquals(1, count($writers));
$this->assertEquals(1,count($writers[0]->events)); $this->assertEquals(1, count($writers[0]->events));
$exceptionStart = "Could not create debug log:"; $this->assertEquals(
$this->assertEquals(substr($writers[0]->events[0]["message"],0,strlen($exceptionStart)),$exceptionStart); 'Could not add log writer of type "Invalid". Type does not exist.',
Logger::reset(); $writers[0]->events[0]['message']
);
} }
/** /**
* @expectedException \Icinga\Exception\ConfigurationError * @backupStaticAttributes enabled
*/ */
public function testGeneralLogException() { public function testNotLoggedMessagesQueue()
$cfg1 = new \Zend_Config(array( {
"debug" => array( $cfg1 = new \Zend_Config(
"enable" => 0, array(
"type" => 'Invalid', 'debug' => array(
"target" => "..." 'enable' => 0,
'type' => 'Invalid',
'target' => '...'
), ),
"type" => "invalid", 'type' => 'invalid',
"target" => "target2" 'target' => 'target2'
)
);
));
Logger::reset();
$logger = Logger::create($cfg1); $logger = Logger::create($cfg1);
Logger::reset(); $this->assertTrue(Logger::hasErrorsOccurred());
}
$queue = Logger::getQueue();
$this->assertCount(2, $queue);
$this->assertSame(
'Could not add log writer of type "Invalid". Type does not exist.',
$queue[0][0],
'Log message of an invalid writer'
);
$this->assertSame(0, $queue[0][1], 'Log level "fatal"');
$this->assertSame(
'Could not flush logs to output. An exception was thrown: No writers were added',
$queue[1][0],
'Log message that no writer was added to logger'
);
$this->assertSame(0, $queue[1][1], 'Log level "fatal"');
}
} }