Browse Source

#74 Added the configuration of logging (errors, web service usage, etc.), and improved a little the error logging (both in a file and into the database + new format for additional information such as the callstack)

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@403 a333f486-631f-4898-b8df-5754b55c2be0
romainq 15 năm trước cách đây
mục cha
commit
11594c6f7f

+ 42 - 40
core/action.class.inc.php

@@ -291,53 +291,55 @@ class ActionEmail extends ActionNotification
 			$this->m_aMailErrors[] = $e->getMessage();
 		}
 
-		$oLog = new EventNotificationEmail();
-		if (empty($this->m_aMailErrors))
+		if (MetaModel::IsLogEnabledNotification())
 		{
-			if ($this->IsBeingTested())
-			{
-				$oLog->Set('message', 'TEST - Notification sent ('.$this->Get('test_recipient').')');
-			}
-			else
-			{
-				$oLog->Set('message', 'Notification sent');
-			}
-		}
-		else
-		{
-			if (is_array($this->m_aMailErrors) && count($this->m_aMailErrors) > 0)
-			{
-				$sError = implode(', ', $this->m_aMailErrors);
-			}
-			else
-			{
-				$sError = 'Unknown reason';
-			}
-			if ($this->IsBeingTested())
+			$oLog = new EventNotificationEmail();
+			if (empty($this->m_aMailErrors))
 			{
-				$oLog->Set('message', 'TEST - Notification was not sent: '.$sError);
+				if ($this->IsBeingTested())
+				{
+					$oLog->Set('message', 'TEST - Notification sent ('.$this->Get('test_recipient').')');
+				}
+				else
+				{
+					$oLog->Set('message', 'Notification sent');
+				}
 			}
 			else
 			{
-				$oLog->Set('message', 'Notification was not sent: '.$sError);
+				if (is_array($this->m_aMailErrors) && count($this->m_aMailErrors) > 0)
+				{
+					$sError = implode(', ', $this->m_aMailErrors);
+				}
+				else
+				{
+					$sError = 'Unknown reason';
+				}
+				if ($this->IsBeingTested())
+				{
+					$oLog->Set('message', 'TEST - Notification was not sent: '.$sError);
+				}
+				else
+				{
+					$oLog->Set('message', 'Notification was not sent: '.$sError);
+				}
 			}
-		}
+			$oLog->Set('userinfo', UserRights::GetUser());
+			$oLog->Set('trigger_id', $oTrigger->GetKey());
+			$oLog->Set('action_id', $this->GetKey());
+			$oLog->Set('object_id', $aContextArgs['this->id']);
 
-		$oLog->Set('userinfo', UserRights::GetUser());
-		$oLog->Set('trigger_id', $oTrigger->GetKey());
-		$oLog->Set('action_id', $this->GetKey());
-		$oLog->Set('object_id', $aContextArgs['this->id']);
-
-		// Note: we have to secure this because those values are calculated
-		// inside the try statement, and we would like to keep track of as
-		// many data as we could while some variables may still be undefined
-		if (isset($sTo))       $oLog->Set('to', $sTo);
-		if (isset($sCC))       $oLog->Set('cc', $sCC);
-		if (isset($sBCC))      $oLog->Set('bcc', $sBCC);
-		if (isset($sFrom))     $oLog->Set('from', $sFrom);
-		if (isset($sSubject))  $oLog->Set('subject', $sSubject);
-		if (isset($sBody))     $oLog->Set('body', $sBody);
-		$oLog->DBInsertNoReload();
+			// Note: we have to secure this because those values are calculated
+			// inside the try statement, and we would like to keep track of as
+			// many data as we could while some variables may still be undefined
+			if (isset($sTo))       $oLog->Set('to', $sTo);
+			if (isset($sCC))       $oLog->Set('cc', $sCC);
+			if (isset($sBCC))      $oLog->Set('bcc', $sBCC);
+			if (isset($sFrom))     $oLog->Set('from', $sFrom);
+			if (isset($sSubject))  $oLog->Set('subject', $sSubject);
+			if (isset($sBody))     $oLog->Set('body', $sBody);
+			$oLog->DBInsertNoReload();
+		}
 	}
 }
 ?>

+ 130 - 4
core/attributedef.class.inc.php

@@ -1441,10 +1441,20 @@ class AttributeBlob extends AttributeDefinition
 		//     (temporary tables created on disk)
 		//     We will have to remove the blobs from the list of attributes when doing the select
 		//     then the use of Get() should finalize the load
-		$aValues = array();
-		$aValues[$this->GetCode().'_data'] = $value->GetData();
-		$aValues[$this->GetCode().'_mimetype'] = $value->GetMimeType();
-		$aValues[$this->GetCode().'_filename'] = $value->GetFileName();
+		if ($value instanceOf ormDocument)
+		{
+			$aValues = array();
+			$aValues[$this->GetCode().'_data'] = $value->GetData();
+			$aValues[$this->GetCode().'_mimetype'] = $value->GetMimeType();
+			$aValues[$this->GetCode().'_filename'] = $value->GetFileName();
+		}
+		else
+		{
+			$aValues = array();
+			$aValues[$this->GetCode().'_data'] = '';
+			$aValues[$this->GetCode().'_mimetype'] = '';
+			$aValues[$this->GetCode().'_filename'] = '';
+		}
 		return $aValues;
 	}
 
@@ -1490,5 +1500,121 @@ class AttributeBlob extends AttributeDefinition
 	}
 }
 
+// Indexed array having two dimensions
+class AttributeTable extends AttributeText
+{
+	public function GetType() {return "Table";}
+	public function GetTypeDesc() {return "Array with 2 dimensions";}
+	public function GetEditClass() {return "Text";}
+	protected function GetSQLCol() {return "TEXT";}
+
+
+	// Facilitate things: allow the user to Set the value from a string
+	public function MakeRealValue($proposedValue)
+	{
+		if (!is_array($proposedValue))
+		{
+			return array(0 => array(0 => $proposedValue));
+		}
+		return $proposedValue;
+	}
+
+	public function FromSQLToValue($aCols, $sPrefix = '')
+	{
+		try
+		{
+			$value = @unserialize($aCols[$sPrefix.'']);
+			if ($value === false)
+			{
+				$value = $this->MakeRealValue($aCols[$sPrefix.'']);
+			}
+		}
+		catch(Exception $e)
+		{
+			$value = $this->MakeRealValue($aCols[$sPrefix.'']);
+		}
+
+		return $value;
+	}
+
+	public function GetSQLValues($value)
+	{
+		$aValues = array();
+		$aValues[$this->Get("sql")] = serialize($value);
+		return $aValues;
+	}
+
+	public function GetAsHTML($value)
+	{
+		if (!is_array($value))
+		{
+			throw new CoreException('Expecting an array', array('found' => get_class($value)));
+		}
+		if (count($value) == 0)
+		{
+			return "";
+		}
+
+		$sRes = "<TABLE class=\"listResults\">";
+		$sRes .= "<TBODY>";
+		foreach($value as $iRow => $aRawData)
+		{
+			$sRes .= "<TR>";
+			foreach ($aRawData as $iCol => $cell)
+			{
+				$sCell = str_replace("\n", "<br>\n", Str::pure2html((string)$cell));
+				$sRes .= "<TD>$sCell</TD>";
+			}
+			$sRes .= "</TR>";
+		}
+		$sRes .= "</TBODY>";
+		$sRes .= "</TABLE>";
+		return $sRes;
+	}
+}
+
+// The PHP value is a hash array, it is stored as a TEXT column
+class AttributePropertySet extends AttributeTable
+{
+	public function GetType() {return "PropertySet";}
+	public function GetTypeDesc() {return "List of properties (name and value)";}
+	public function GetEditClass() {return "Text";}
+	protected function GetSQLCol() {return "TEXT";}
+
+	// Facilitate things: allow the user to Set the value from a string
+	public function MakeRealValue($proposedValue)
+	{
+		if (!is_array($proposedValue))
+		{
+			return array('?' => (string)$proposedValue);
+		}
+		return $proposedValue;
+	}
+
+	public function GetAsHTML($value)
+	{
+		if (!is_array($value))
+		{
+			throw new CoreException('Expecting an array', array('found' => get_class($value)));
+		}
+		if (count($value) == 0)
+		{
+			return "";
+		}
+
+		$sRes = "<TABLE class=\"listResults\">";
+		$sRes .= "<TBODY>";
+		foreach($value as $sProperty => $sValue)
+		{
+			$sRes .= "<TR>";
+			$sCell = str_replace("\n", "<br>\n", Str::pure2html((string)$sValue));
+			$sRes .= "<TD class=\"label\">$sProperty</TD><TD>$sCell</TD>";
+			$sRes .= "</TR>";
+		}
+		$sRes .= "</TBODY>";
+		$sRes .= "</TABLE>";
+		return $sRes;
+	}
+}
 
 ?>

+ 1 - 0
core/cmdbobject.class.inc.php

@@ -16,6 +16,7 @@
 require_once('coreexception.class.inc.php');
 
 require_once('config.class.inc.php');
+require_once('log.class.inc.php');
 
 require_once('dict.class.inc.php');
 

+ 65 - 0
core/config.class.inc.php

@@ -16,6 +16,11 @@ class ConfigException extends CoreException
 {
 }
 
+define ('DEFAULT_LOG_GLOBAL', true);
+define ('DEFAULT_LOG_NOTIFICATION', true);
+define ('DEFAULT_LOG_ISSUE', true);
+define ('DEFAULT_LOG_WEB_SERVICE', true);
+
 define ('DEFAULT_MIN_DISPLAY_LIMIT', 10);
 define ('DEFAULT_MAX_DISPLAY_LIMIT', 15);
 define ('DEFAULT_STANDARD_RELOAD_INTERVAL', 5*60);
@@ -39,6 +44,14 @@ class Config
 	protected $m_sDBSubname;
 
 	/**
+	 * @var integer Event log options (see LOG_... definition)
+	 */	 	
+	protected $m_bLogGlobal;
+	protected $m_bLogNotification;
+	protected $m_bLogIssue;
+	protected $m_bLogWebService;
+
+	/**
 	 * @var integer Number of elements to be displayed when there are more than m_iMaxDisplayLimit elements
 	 */	 	
 	protected $m_iMinDisplayLimit;
@@ -79,6 +92,10 @@ class Config
 		$this->m_sDBPwd = '';
 		$this->m_sDBName = '';
 		$this->m_sDBSubname = '';
+		$this->m_bLogGlobal = DEFAULT_LOG_GLOBAL;
+		$this->m_bLogNotification = DEFAULT_LOG_NOTIFICATION;
+		$this->m_bLogIssue = DEFAULT_LOG_ISSUE;
+		$this->m_bLogWebService = DEFAULT_LOG_WEB_SERVICE;
 		$this->m_iMinDisplayLimit = DEFAULT_MIN_DISPLAY_LIMIT;
 		$this->m_iMaxDisplayLimit = DEFAULT_MAX_DISPLAY_LIMIT;
 		$this->m_iStandardReloadInterval = DEFAULT_STANDARD_RELOAD_INTERVAL;
@@ -167,6 +184,10 @@ class Config
 		$this->m_sDBName = trim($MySettings['db_name']);
 		$this->m_sDBSubname = trim($MySettings['db_subname']);
 
+		$this->m_bLogGlobal = isset($MySettings['log_global']) ? trim($MySettings['log_global']) : DEFAULT_LOG_GLOBAL;
+		$this->m_bLogNotification = isset($MySettings['log_notification']) ? trim($MySettings['log_notification']) : DEFAULT_LOG_NOTIFICATION;
+		$this->m_bLogIssue = isset($MySettings['log_issue']) ? trim($MySettings['log_issue']) : DEFAULT_LOG_ISSUE;
+		$this->m_bLogWebService = isset($MySettings['log_web_service']) ? trim($MySettings['log_web_service']) : DEFAULT_LOG_WEB_SERVICE;
 		$this->m_iMinDisplayLimit = isset($MySettings['min_display_limit']) ? trim($MySettings['min_display_limit']) : DEFAULT_MIN_DISPLAY_LIMIT;
 		$this->m_iMaxDisplayLimit = isset($MySettings['max_display_limit']) ? trim($MySettings['max_display_limit']) : DEFAULT_MAX_DISPLAY_LIMIT;
 		$this->m_iStandardReloadInterval = isset($MySettings['standard_reload_interval']) ? trim($MySettings['standard_reload_interval']) : DEFAULT_STANDARD_RELOAD_INTERVAL;
@@ -241,6 +262,26 @@ class Config
 		return $this->m_sDBPwd;
 	}
 
+	public function GetLogGlobal()
+	{
+		return $this->m_bLogGlobal;
+	}
+
+	public function GetLogNotification()
+	{
+		return $this->m_bLogNotification;
+	}
+
+	public function GetLogIssue()
+	{
+		return $this->m_bLogIssue;
+	}
+
+	public function GetLogWebService()
+	{
+		return $this->m_bLogWebService;
+	}
+
 	public function GetMinDisplayLimit()
 	{
 		return $this->m_iMinDisplayLimit;
@@ -296,6 +337,26 @@ class Config
 		$this->m_sDBPwd = $sPwd;
 	}
 
+	public function SetLogGlobal($iLogGlobal)
+	{
+		$this->m_iLogGlobal = $iLogGlobal;
+	}
+
+	public function SetLogNotification($iLogNotification)
+	{
+		$this->m_iLogNotification = $iLogNotification;
+	}
+
+	public function SetLogIssue($iLogIssue)
+	{
+		$this->m_iLogIssue = $iLogIssue;
+	}
+
+	public function SetLogWebService($iLogWebService)
+	{
+		$this->m_iLogWebService = $iLogWebService;
+	}
+
 	public function SetMinDisplayLimit($iMinDisplayLimit)
 	{
 		$this->m_iMinDisplayLimit = $iMinDisplayLimit;
@@ -363,6 +424,10 @@ class Config
 			fwrite($hFile, "\t'db_name' => '{$this->m_sDBName}',\n");
 			fwrite($hFile, "\t'db_subname' => '{$this->m_sDBSubname}',\n");
 			fwrite($hFile, "\n");
+			fwrite($hFile, "\t'log_global' => {$this->m_bLogGlobal},\n");
+			fwrite($hFile, "\t'log_notification' => {$this->m_bLogNotification},\n");
+			fwrite($hFile, "\t'log_issue' => {$this->m_bLogIssue},\n");
+			fwrite($hFile, "\t'log_web_service' => {$this->m_bLogWebService},\n");
 			fwrite($hFile, "\t'min_display_limit' => {$this->m_iMinDisplayLimit},\n");
 			fwrite($hFile, "\t'max_display_limit' => {$this->m_iMaxDisplayLimit},\n");
 			fwrite($hFile, "\t'standard_reload_interval' => {$this->m_iStandardReloadInterval},\n");

+ 13 - 0
core/coreexception.class.inc.php

@@ -64,6 +64,19 @@ class CoreException extends Exception
 	{
 		$this->m_aContextData[$sKey] = $value;
 	}
+
+	public function getIssue()
+	{
+		return $this->m_sIssue;
+	}
+	public function getImpact()
+	{
+		return $this->m_sImpact;
+	}
+	public function getContextData()
+	{
+		return $this->m_aContextData;
+	}
 }
 
 class CoreWarning extends CoreException

+ 41 - 4
core/event.class.inc.php

@@ -145,10 +145,10 @@ class EventIssue extends Event
 		MetaModel::Init_AddAttribute(new AttributeString("issue", array("allowed_values"=>null, "sql"=>"issue", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("impact", array("allowed_values"=>null, "sql"=>"impact", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("page", array("allowed_values"=>null, "sql"=>"page", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeText("arguments_post", array("allowed_values"=>null, "sql"=>"arguments_post", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeText("arguments_get", array("allowed_values"=>null, "sql"=>"arguments_get", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeText("callstack", array("allowed_values"=>null, "sql"=>"callstack", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeBlob("data", array("allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributePropertySet("arguments_post", array("allowed_values"=>null, "sql"=>"arguments_post", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributePropertySet("arguments_get", array("allowed_values"=>null, "sql"=>"arguments_get", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeTable("callstack", array("allowed_values"=>null, "sql"=>"callstack", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributePropertySet("data", array("allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
 
 		MetaModel::Init_InheritFilters();
 		MetaModel::Init_AddFilterFromAttribute("issue");
@@ -161,6 +161,43 @@ class EventIssue extends Event
 //		MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
 //		MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
 	}
+
+	public function OnInsert()
+	{
+		// Init page information: name, arguments
+		//
+		$this->Set('page', @$GLOBALS['_SERVER']['SCRIPT_NAME']);
+
+		if (array_key_exists('_GET', $GLOBALS) && is_array($GLOBALS['_GET']))
+		{
+			$this->Set('arguments_get', $GLOBALS['_GET']);
+		}
+		else
+		{
+			$this->Set('arguments_get', array());
+		}
+
+		if (array_key_exists('_POST', $GLOBALS) && is_array($GLOBALS['_POST']))
+		{
+			$aPost = array();
+			foreach($GLOBALS['_POST'] as $sKey => $sValue)
+			{
+				if (strlen($sValue) < 256)
+				{
+					$aPost[$sKey] = $sValue;
+				}
+				else
+				{
+					$aPost[$sKey] = "!long string: ".strlen($sValue). " chars";
+				}
+			}
+			$this->Set('arguments_post', $aPost);
+		}
+		else
+		{
+			$this->Set('arguments_post', array());
+		}
+	}
 }
 
 

+ 109 - 0
core/log.class.inc.php

@@ -0,0 +1,109 @@
+<?php
+/**
+ * Log
+ * logging to files
+ *
+ * @package     iTopORM
+ * @author      Romain Quetiez <romainquetiez@yahoo.fr>
+ * @author      Denis Flaven <denisflave@free.fr>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.itop.com
+ * @since       1.0
+ * @version     1.1.1.1 $
+ */
+
+class FileLog
+{
+	protected $m_sFile = ''; // log is disabled if this is empty
+
+	public function __construct($sFileName = '')
+	{
+		$this->m_sFile = $sFileName;
+	}
+
+	public function Error($sText)
+	{
+		self::Write("Error | ".$sText);
+	}
+
+	public function Warning($sText)
+	{
+		self::Write("Warning | ".$sText);
+	}
+
+	public function Info($sText)
+	{
+		self::Write("Info | ".$sText);
+	}
+
+	public function Ok($sText)
+	{
+		self::Write("Ok | ".$sText);
+	}
+
+	protected function Write($sText)
+	{
+		if (strlen($this->m_sFile) == 0) return;
+
+		$hLogFile = @fopen($this->m_sFile, 'a');
+		if ($hLogFile !== false)
+		{
+			$sDate = date('Y-m-d H:i:s');
+			fwrite($hLogFile, "$sDate | $sText\n");
+			fclose($hLogFile);
+		}
+	}
+}
+
+class SetupLog
+{
+	protected static $m_oFileLog; 
+
+	public static function Enable($sTargetFile)
+	{
+		self::$m_oFileLog = new FileLog($sTargetFile);
+	}
+	public static function Error($sText)
+	{
+		self::$m_oFileLog->Error($sText);
+	}
+	public static function Warning($sText)
+	{
+		self::$m_oFileLog->Warning($sText);
+	}
+	public static function Info($sText)
+	{
+		self::$m_oFileLog->Info($sText);
+	}
+	public static function Ok($sText)
+	{
+		self::$m_oFileLog->Ok($sText);
+	}
+}
+
+class IssueLog
+{
+	protected static $m_oFileLog; 
+
+	public static function Enable($sTargetFile)
+	{
+		self::$m_oFileLog = new FileLog($sTargetFile);
+	}
+	public static function Error($sText)
+	{
+		self::$m_oFileLog->Error($sText);
+	}
+	public static function Warning($sText)
+	{
+		self::$m_oFileLog->Warning($sText);
+	}
+	public static function Info($sText)
+	{
+		self::$m_oFileLog->Info($sText);
+	}
+	public static function Ok($sText)
+	{
+		self::$m_oFileLog->Ok($sText);
+	}
+}
+?>

+ 34 - 0
core/metamodel.class.php

@@ -167,6 +167,22 @@ abstract class MetaModel
 	private static $m_bTraceQueries = true;
 	private static $m_aQueriesLog = array();
 	
+	private static $m_bLogIssue = false;
+	private static $m_bLogNotification = false;
+	private static $m_bLogWebService = false;
+
+	public static function IsLogEnabledIssue()
+	{
+		return self::$m_bLogIssue;
+	}
+	public static function IsLogEnabledNotification()
+	{
+		return self::$m_bLogNotification;
+	}
+	public static function IsLogEnabledWebService()
+	{
+		return self::$m_bLogWebService;
+	}
 
 	private static $m_sDBName = "";
 	private static $m_sTablePrefix = ""; // table prefix for the current application instance (allow several applications on the same DB)
@@ -2839,6 +2855,24 @@ abstract class MetaModel
 	{
 		$oConfig = new Config($sConfigFile);
 
+		// Set log ASAP
+		if ($oConfig->GetLogGlobal())
+		{
+			if ($oConfig->GetLogIssue())
+			{
+				self::$m_bLogIssue = true;
+				IssueLog::Enable('../error.log');
+			}
+			self::$m_bLogNotification = $oConfig->GetLogNotification();
+			self::$m_bLogWebService = $oConfig->GetLogWebService();
+		}
+		else
+		{
+			self::$m_bLogIssue = false;
+			self::$m_bLogNotification = false;
+			self::$m_bLogWebService = false;
+		}
+
 		foreach ($oConfig->GetAppModules() as $sModule => $sToInclude)
 		{
 			self::Plugin($sConfigFile, 'application', $sToInclude);

+ 2 - 0
core/test.class.inc.php

@@ -10,6 +10,8 @@ require_once('expression.class.inc.php');
 require_once('cmdbsource.class.inc.php');
 require_once('sqlquery.class.inc.php');
 
+require_once('log.class.inc.php');
+
 require_once('dbobject.class.php');
 require_once('dbobjectsearch.class.php');
 require_once('dbobjectset.class.php');

+ 45 - 5
pages/UI.php

@@ -290,7 +290,7 @@ function DeleteObjects(WebPage $oP, $sClass, $aObjects, $bDeleteConfirmed)
 		{
 			if (count($aObjects) == 1)
 			{
-				$oObj = $aObjects[0];
+				$oObj = $aObjects[0];
 				$id = $oObj->GetKey();
 				$oP->p("Please confirm that you want to delete ".$oObj->GetHyperLink());
 				$oP->add("<form method=\"post\">\n");
@@ -337,6 +337,7 @@ try
 	$oContext = new UserContext();
 	$oAppContext = new ApplicationContext();
 	$iActiveNodeId = utils::ReadParam('menu', '');
+
 	if (empty($iActiveNodeId) && !is_numeric($iActiveNodeId))
 	{
 		// No menu specified, let's get the default one:
@@ -1301,20 +1302,59 @@ try
 	////MetaModel::ShowQueryTrace();
 	$oP->output();
 }
-catch(Exception $e)
+catch(CoreException $e)
 {
 	require_once('../setup/setuppage.class.inc.php');
 	$oP = new SetupWebPage('iTop - fatal error');
 	$oP->add("<h1>Fatal Error, iTop cannot continue</h1>\n");	
-	$oP->error("Error: '".$e->getMessage()."'");	
+	$oP->error("Error: '".$e->getHtmlDesc()."'");	
 	$oP->output();
+
+	if (MetaModel::IsLogEnabledIssue())
+	{
+		if (class_exists('EventIssue'))
+		{
+			$oLog = new EventIssue();
+
+			$oLog->Set('message', $e->getMessage());
+			$oLog->Set('userinfo', '');
+			$oLog->Set('issue', $e->GetIssue());
+			$oLog->Set('impact', 'Page could not be displayed');
+			$oLog->Set('callstack', $e->getTrace());
+			$oLog->Set('data', $e->getContextData());
+			$oLog->DBInsertNoReload();
+		}
+
+		IssueLog::Error($e->getMessage());
+	}
+
+	// For debugging only
+	//throw $e;
 }
-catch(CoreException $e)
+catch(Exception $e)
 {
 	require_once('../setup/setuppage.class.inc.php');
 	$oP = new SetupWebPage('iTop - fatal error');
 	$oP->add("<h1>Fatal Error, iTop cannot continue</h1>\n");	
-	$oP->error("Error: '".$e->getHtmlDesc()."'");	
+	$oP->error("Error: '".$e->getMessage()."'");	
 	$oP->output();
+
+	if (MetaModel::IsLogEnabledIssue())
+	{
+		if (class_exists('EventIssue'))
+		{
+			$oLog = new EventIssue();
+
+			$oLog->Set('message', $e->getMessage());
+			$oLog->Set('userinfo', '');
+			$oLog->Set('issue', 'PHP Exception');
+			$oLog->Set('impact', 'Page could not be displayed');
+			$oLog->Set('callstack', $e->getTrace());
+			$oLog->Set('data', array());
+			$oLog->DBInsertNoReload();
+		}
+
+		IssueLog::Error($e->getMessage());
+	}
 }
 ?>

+ 1 - 0
setup/ajax.dataloader.php

@@ -64,6 +64,7 @@ ini_set('error_append_string', '</phpfatalerror>');
 ob_start('FatalErrorCatcher'); // Start capturing the output, and pass it through the fatal error catcher
 
 require_once('../core/config.class.inc.php');
+require_once('../core/log.class.inc.php');
 require_once('../core/cmdbsource.class.inc.php');
 require_once('./xmldataloader.class.inc.php');
 

+ 2 - 0
setup/index.php

@@ -4,6 +4,7 @@
  */
 require_once('../application/utils.inc.php');
 require_once('../core/config.class.inc.php');
+require_once('../core/log.class.inc.php');
 require_once('../core/cmdbsource.class.inc.php');
 require_once('./setuppage.class.inc.php');
 define('TMP_CONFIG_FILE', '../tmp-config-itop.php');
@@ -243,6 +244,7 @@ function CheckServerConnection(SetupWebPage $oP, $sDBServer, $sDBUser, $sDBPwd)
  */    
 function InitDataModel(SetupWebPage $oP, $sConfigFileName, $bAllowMissingDatabase = true)
 {
+	require_once('../core/log.class.inc.php');
 	require_once('../core/coreexception.class.inc.php');
 	require_once('../core/attributedef.class.inc.php');
 	require_once('../core/filterdef.class.inc.php');

+ 1 - 0
setup/xmldataloader.class.inc.php

@@ -63,6 +63,7 @@ class XMLDataLoader
 	 */	 	
 	protected function InitDataModel($sConfigFileName, $bAllowMissingDatabase = true)
 	{
+		require_once('../core/log.class.inc.php');
 		require_once('../core/coreexception.class.inc.php');
 		require_once('../core/attributedef.class.inc.php');
 		require_once('../core/filterdef.class.inc.php');

+ 2 - 0
webservices/webservices.class.inc.php

@@ -222,6 +222,8 @@ class WebServices
 	 */
 	protected function LogUsage($sVerb, $oRes)
 	{
+		if (!MetaModel::IsLogEnabledWebService()) return;
+
 		$oLog = new EventWebService();
 		if ($oRes->IsOk())
 		{