From b822cff269c8b13184a58c96d10acc9162882f73 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Tue, 25 Nov 2014 15:25:28 +0000 Subject: [PATCH] Instrumented the code to ease the troubleshooting of the computing of working hours SVN:trunk[3425] --- core/computing.inc.php | 21 ++++++++- core/dbobject.class.php | 44 ++++++++++++++++++- core/ormstopwatch.class.inc.php | 26 ++++++++++- .../main.itop-sla-computation.php | 32 ++++++++++++-- dictionaries/dictionary.itop.core.php | 15 +++---- dictionaries/fr.dictionary.itop.core.php | 6 ++- 6 files changed, 126 insertions(+), 18 deletions(-) diff --git a/core/computing.inc.php b/core/computing.inc.php index 4e4042e2c..7bb37daf6 100644 --- a/core/computing.inc.php +++ b/core/computing.inc.php @@ -1,5 +1,5 @@ format('Y-m-d H:i:s')." + $iDuration
\n"; // Default implementation: 24x7, no holidays: to compute the deadline, just add // the specified duration to the given date/time $oResult = clone $oStartDate; $oResult->modify('+'.$iDuration.' seconds'); + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::SetValues($oStartDate->format('U'), $oResult->format('U'), $iDuration, WorkingTimeRecorder::COMPUTED_END); + } return $oResult; } @@ -113,8 +121,17 @@ class DefaultWorkingTimeComputer implements iWorkingTimeComputer */ public function GetOpenDuration($oObject, DateTime $oStartDate, DateTime $oEndDate) { + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::Trace(WorkingTimeRecorder::TRACE_DEBUG, __class__.'::'.__function__); + } //echo "GetOpenDuration - default: ".$oStartDate->format('Y-m-d H:i:s')." to ".$oEndDate->format('Y-m-d H:i:s')."
\n"; - return abs($oEndDate->format('U') - $oStartDate->format('U')); + $iDuration = abs($oEndDate->format('U') - $oStartDate->format('U')); + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::SetValues($oStartDate->format('U'), $oEndDate->format('U'), $iDuration, WorkingTimeRecorder::COMPUTED_DURATION); + } + return $iDuration; } } diff --git a/core/dbobject.class.php b/core/dbobject.class.php index 7ff304c5c..535c0cf62 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -96,6 +96,7 @@ abstract class DBObject implements iDisplay protected $m_aModifiedAtt = array(); // list of (potentially) modified sAttCodes protected $m_aSynchroData = null; // Set of Synch data related to this object protected $m_sHighlightCode = null; + protected $m_aCallbacks = array(); // Use the MetaModel::NewObject to build an object (do we have to force it?) public function __construct($aRow = null, $sClassAlias = '', $aAttToLoad = null, $aExtendedDataSpec = null) @@ -1584,6 +1585,15 @@ abstract class DBObject implements iDisplay $oTrigger->DoActivate($this->ToArgs('this')); } + // Callbacks registered with RegisterCallback + if (isset($this->m_aCallbacks[self::CALLBACK_AFTERINSERT])) + { + foreach ($this->m_aCallbacks[self::CALLBACK_AFTERINSERT] as $aCallBackData) + { + call_user_func_array($aCallBackData['callback'], $aCallBackData['params']); + } + } + $this->RecordObjCreation(); return $this->m_iKey; @@ -2242,7 +2252,17 @@ abstract class DBObject implements iDisplay $iStartTime = AttributeDateTime::GetAsUnixSeconds($this->Get($sRefAttCode)); $oStartDate = new DateTime('@'.$iStartTime); // setTimestamp not available in PHP 5.2 $oEndDate = new DateTime(); // now + + if (class_exists('WorkingTimeRecorder')) + { + $sClass = get_class($this); + WorkingTimeRecorder::Start($this, time(), "DBObject-SetElapsedTime-$sAttCode-$sRefAttCode", 'Core:ExplainWTC:ElapsedTime', array("Class:$sClass/Attribute:$sAttCode")); + } $iElapsed = call_user_func($aCallSpec, $this, $oStartDate, $oEndDate); + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::End(); + } $this->Set($sAttCode, $iElapsed); return true; @@ -2800,6 +2820,28 @@ abstract class DBObject implements iDisplay } $oPage->details($aValues); } - + + + const CALLBACK_AFTERINSERT = 0; + + /** + * Register a call back that will be called when some internal event happens + * + * @param $iType string Any of the CALLBACK_x constants + * @param $callback callable Call specification like a function name, or array('', '') or array($object, '') + * @param $aParameters Array Values that will be passed to the callback, after $this + */ + public function RegisterCallback($iType, $callback, $aParameters = array()) + { + $sCallBackName = ''; + if (!is_callable($callback, false, $sCallBackName)) + { + throw new Exception('Registering an unknown/protected function or wrong syntax for the call spec: '.$sCallBackName); + } + $this->m_aCallbacks[$iType][] = array( + 'callback' => $callback, + 'params' => $aParameters + ); + } } diff --git a/core/ormstopwatch.class.inc.php b/core/ormstopwatch.class.inc.php index 8e70c605a..863512ae7 100644 --- a/core/ormstopwatch.class.inc.php +++ b/core/ormstopwatch.class.inc.php @@ -1,5 +1,5 @@ ComputeGoal($oObject, $oAttDef); + $iComputationRefTime = time(); foreach ($this->aThresholds as $iPercent => &$aThresholdData) { if (is_null($iDurationGoal)) @@ -370,9 +371,20 @@ class ormStopWatch else { $iThresholdDuration = round($iPercent * $iDurationGoal / 100); + + if (class_exists('WorkingTimeRecorder')) + { + $sClass = get_class($oObject); + $sAttCode = $oAttDef->GetCode(); + WorkingTimeRecorder::Start($oObject, $iComputationRefTime, "ormStopWatch-Deadline-$iPercent-$sAttCode", 'Core:ExplainWTC:StopWatch-Deadline', array("Class:$sClass/Attribute:$sAttCode", $iPercent)); + } $aThresholdData['deadline'] = $this->ComputeDeadline($oObject, $oAttDef, $this->iLastStart, $iThresholdDuration - $this->iTimeSpent); // OR $aThresholdData['deadline'] = $this->ComputeDeadline($oObject, $oAttDef, $this->iStarted, $iThresholdDuration); + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::End(); + } } if (is_null($aThresholdData['deadline']) || ($aThresholdData['deadline'] > time())) { @@ -402,8 +414,18 @@ class ormStopWatch return false; } + if (class_exists('WorkingTimeRecorder')) + { + $sClass = get_class($oObject); + $sAttCode = $oAttDef->GetCode(); + WorkingTimeRecorder::Start($oObject, time(), "ormStopWatch-TimeSpent-$sAttCode", 'Core:ExplainWTC:StopWatch-TimeSpent', array("Class:$sClass/Attribute:$sAttCode"), true /*cumulative*/); + } $iElapsed = $this->ComputeDuration($oObject, $oAttDef, $this->iLastStart, time()); $this->iTimeSpent = $this->iTimeSpent + $iElapsed; + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::End(); + } foreach ($this->aThresholds as $iPercent => &$aThresholdData) { diff --git a/datamodels/2.x/itop-sla-computation/main.itop-sla-computation.php b/datamodels/2.x/itop-sla-computation/main.itop-sla-computation.php index 56a84ecca..83d969df3 100755 --- a/datamodels/2.x/itop-sla-computation/main.itop-sla-computation.php +++ b/datamodels/2.x/itop-sla-computation/main.itop-sla-computation.php @@ -1,5 +1,5 @@ GetDeadline($oObject, $iDuration, $oStartDate); + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::Trace(WorkingTimeRecorder::TRACE_DEBUG, __class__.'::'.__function__); + } + $oEndDate = self::$m_oAddOn->GetDeadline($oObject, $iDuration, $oStartDate); + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::SetValues($oStartDate->format('U'), $oEndDate->format('U'), $iDuration, WorkingTimeRecorder::COMPUTED_END); + } + return $oEndDate; } /** @@ -89,7 +98,16 @@ class SLAComputation implements iWorkingTimeComputer */ public function GetOpenDuration($oObject, DateTime $oStartDate, DateTime $oEndDate) { - return self::$m_oAddOn->GetOpenDuration($oObject, $oStartDate, $oEndDate); + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::Trace(WorkingTimeRecorder::TRACE_DEBUG, __class__.'::'.__function__); + } + $iDuration = self::$m_oAddOn->GetOpenDuration($oObject, $oStartDate, $oEndDate); + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::SetValues($oStartDate->format('U'), $oEndDate->format('U'), $iDuration, WorkingTimeRecorder::COMPUTED_DURATION); + } + return $iDuration; } } @@ -119,6 +137,10 @@ class SLAComputationAddOnAPI */ public static function GetDeadline($oTicket, $iDuration, DateTime $oStartDate) { + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::Trace(WorkingTimeRecorder::TRACE_DEBUG, __class__.'::'.__function__); + } // Default implementation: 24x7, no holidays: to compute the deadline, just add // the specified duration to the given date/time $oResult = clone $oStartDate; @@ -135,6 +157,10 @@ class SLAComputationAddOnAPI */ public static function GetOpenDuration($oTicket, DateTime $oStartDate, DateTime $oEndDate) { + if (class_exists('WorkingTimeRecorder')) + { + WorkingTimeRecorder::Trace(WorkingTimeRecorder::TRACE_DEBUG, __class__.'::'.__function__); + } return abs($oEndDate->format('U') - $oStartDate->format('U')); } } diff --git a/dictionaries/dictionary.itop.core.php b/dictionaries/dictionary.itop.core.php index db522b769..ebd0b4f12 100644 --- a/dictionaries/dictionary.itop.core.php +++ b/dictionaries/dictionary.itop.core.php @@ -1,5 +1,5 @@ 'Prefs', 'Core:ExecProcess:Code1' => 'Wrong command or command finished with errors (e.g. wrong script name)', 'Core:ExecProcess:Code255' => 'PHP Error (parsing, or runtime)', -)); -// -// Attribute Duration -// -Dict::Add('EN US', 'English', 'English', array( + // Attribute Duration 'Core:Duration_Seconds' => '%1$ds', 'Core:Duration_Minutes_Seconds' =>'%1$dmin %2$ds', 'Core:Duration_Hours_Minutes_Seconds' => '%1$dh %2$dmin %3$ds', 'Core:Duration_Days_Hours_Minutes_Seconds' => '%1$sd %2$dh %3$dmin %4$ds', -)); -?> + // Explain working time computing + 'Core:ExplainWTC:ElapsedTime' => 'Time elapsed (stored as "%1$s")', + 'Core:ExplainWTC:StopWatch-TimeSpent' => 'Time spent for "%1$s"', + 'Core:ExplainWTC:StopWatch-Deadline' => 'Deadline for "%1$s" at %2$d%%' +)); diff --git a/dictionaries/fr.dictionary.itop.core.php b/dictionaries/fr.dictionary.itop.core.php index 6d1bad180..9cc561592 100644 --- a/dictionaries/fr.dictionary.itop.core.php +++ b/dictionaries/fr.dictionary.itop.core.php @@ -1,5 +1,5 @@ 'Core:Duration_Minutes_Seconds' => '%1$dmin %2$ds', 'Core:Duration_Hours_Minutes_Seconds' => '%1$dh %2$dmin %3$ds', 'Core:Duration_Days_Hours_Minutes_Seconds' => '%1$sj %2$dh %3$dmin %4$ds', + 'Core:ExplainWTC:ElapsedTime' => 'Temps écoulé (enregistré dans "%1$s")', + 'Core:ExplainWTC:StopWatch-TimeSpent' => 'Temps écoulé pour "%1$s"', + 'Core:ExplainWTC:StopWatch-Deadline' => 'Date/heure de butée pour "%1$s" à %2$d%%' )); -?>