Vorheriges Thema: Fallstudie 13: Umgang mit dynamischen KomponentengruppenNächstes Thema: Beispiele für das Schreiben einer effektiven Business-Logik


Fallstudie 14: Umgang mit der Zeitakkumulationsuhr

Das in diesem Abschnitt beschriebene Designmuster ist immer dann geeignet, wenn das erforderliche Ergebnis eine Funktion eines Zeitraums ist, der zwischen Events verstrichen ist, wie z. B.:

Bei der Akkumulationszeit muss eine Variable, in der die Zeit akkumuliert werden kann (in Sekunden), zugewiesen und eine Funktion implementiert werden, die sowohl die Bedingungen als auch die seit der letzten Aktualisierungszeit akkumulierte Zeit überprüfen. Diese Funktion wird dann für jedes Event, das von der Formel empfangen wird, ausgeführt.

Die folgende Abbildung stellt die Akkumulation der Uhr-Betriebszeit dar.

Die Variable "LastUpdateTime" speichert die letzte Zeit, zu der die Aktualisierung ausgeführt wurde, unabhängig davon, ob der Zeitzähler aktualisiert wurde oder nicht. Die Funktion enthält die Bedingung, die bestimmt, ob die Zeit aktualisiert und akkumuliert werden sollte. Die Zeit sollte zum Beispiel nicht berücksichtigt werden, wenn sie das Zeitfenster überschreitet, der Systemstatus "Abwärts" lautet oder der Incident einen ausstehenden Status hat.

Obwohl in der hier ausführlich behandelten Situation häufig die Funktion "Tools.NetTime()" verwendet wird, um die Dauer zu berechnen, kann es in einigen Fällen sinnvoller sein, die VB-Funktion "DateDiff()" zu verwenden.

Die Funktion "Tools.NetTime" bedingt jedes Mal, wenn sie verwendet wird, einen zusätzlichen Aufwand für das Prüfen des Zeitfensters. Es wird empfohlen, zu vermeiden, die Funktion "NetTime" im Daten-Event zu verwenden, da diese Verfahren für jedes neue eingehende Event abgerufen werden und daher den "NetTime" -Abruf aktivieren. Wenn Sie ein Zeitfenster von "24/7" haben, wird empfohlen, dass Sie die Funktion "DateDiff" einsetzen, um einen zusätzlichen Aufwand für das Prüfen des Zeitfensters zu vermeiden.

Beispiel 1:

Die folgende Routine "Zähler aktualisieren" akkumuliert den Gesamtzeitraum in der Variablen "PeriodNetTime". Bei "AvailabilityTime" akkumuliert die Routine die Zeit, in der das System den Status "Aufwärts" hatte, d. h. in der das System verfügbar war.

Das Tools-Objekt enthält die "NetTime"-Methode - NetTime(beginTime, endTime)0. Diese Methode gibt die Anzahl von Sekunden zwischen "beginTime" und "endTime" aus, die sich innerhalb des Zeitfensters der aktuellen Metrik befinden. Jede Zeit zwischen diesen beiden Variablen ist Teil eines ausgeschlossenen Zeitfensters, daher wird sie häufig für die Berechnung der Dauer, bei der ein Zeitfenster verwendet wird, eingesetzt. (Zum Beispiel: bei Tickets der Priorität 1, die innerhalb von vier Geschäftsstunden gelöst werden sollen, wurde ein Ticket am Ende eines Geschäftstages erstellt, das möglicherweise erst am nächsten Morgen gelöst wird. Dennoch wird die SLA eingehalten, da die Stunden des Zeitfensters ausgeschlossen wurden.)

Sub UpdateCounters (time)
   PeriodNetTime = PeriodNetTime + tools.NetTime (LastUpdateTime, time)
   If SystemStatus = UP Then
      AvailabilityTime = AvailabilityTime + tools.NetTime (LastUpdateTime, time)
   End If
   LastUpdateTime = time
End Sub

Beispiel 2:

Im folgenden Beispiel wird die Anwendungsverfügbarkeit berechnet, in dem die "Aufwärts"- und "Abwärts"-Events von verschiedenen wichtigen Komponenten sowie die Wartungsevents dieser Komponenten verarbeitet werden. Wenn alle Komponenten gewartet werden, wird die Zeit nicht als erwartete Verfügbarkeitszeit angesehen.

Die Subroutine "UpdateCounters" erhöht die Zeitzähler, wenn dies notwendig sein sollte, und wird bei jedem Event, das von der Formel empfangen wird, ausgeführt (Rohdaten-Event/Engine-Event). Sie aktualisiert auch die erwartete Verfügbarkeitszeit in Fällen, in denen die Zeit im Zeitfenster liegt und sich die Komponenten nicht in einem Zeitraum für einen geplanten Ausfall befinden. Die Formel aktualisiert die tatsächliche Verfügbarkeitszeit nur, wenn sie auch einen Systemstatus "Aufwärts" erfasst.

"DateDiff" ist eine standardmäßige VB-Funktion, die die Zeit zwischen zwei Daten ausgibt, jedoch keine Zeitfenster-Informationen ausschließt.

'Force variable declaration
Option Explicit

'Global variables
Dim ExpectedAvailabilityTime
Dim ActualAvailabilityTime
Dim LastUpdateTime
Dim AvailabilityIndicators
Dim MonitoredComponents
Dim DowntimeStatuses

'Map objects creation
Set AvailabilityIndicators=CreateObject("SlalomMap.Map")
Set MonitoredComponents=CreateObject("SlalomMap.Map")
Set DowntimeStatuses=CreateObject("SlalomMap.Map")

'After loading and whenever an infrastructure change occurs
Sub OnRegistration(dispatcher)
   dispatcher.RegisterByResourceGroup "OnComponentDownEvent","Component Down","Application Components"
   dispatcher.RegisterByResourceGroup "OnComponentUpEvent","Component Up","Application Components"
   dispatcher.RegisterByResourceGroup "OnMaintenanceStartEvent","Maintenance Start","Application Components"
   dispatcher.RegisterByResourceGroup "OnMaintenanceEndEvent","Maintenance End","Application Components"
   UpdateCounters Context.RegistrationTime

   Dim AllocatedComponents
   Set AllocatedComponents = Context.ResourcesOfResourceGroup("Application Components")

   'make sure formula is monitoring only relevant and all the relevant resources
   UpdateMonitoredComponents AllocatedComponents
End Sub

Sub OnLoad(time)
   'When system goes up for the first time - assume availability OK
   LastUpdateTime = time
End Sub

Sub OnPeriodStart(time)
   'initializing counters to renew periodic calculation
   ExpectedAvailabilityTime = 0
   ActualAvailabilityTime = 0
End Sub

Sub OnTimeslotEnter(time)
   UpdateCounters time
End Sub

Sub OnTimeslotExit(time)
   UpdateCounters time
End Sub

Sub OnComponentDownEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'write availability status of reported-on resource
   AvailabilityIndicators(eventDetails.ResourceId) = _
      AvailabilityIndicators(eventDetails.ResourceId)+1
End Sub

Sub OnComponentUpEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'write availability status of reported-on resource
   AvailabilityIndicators(eventDetails.ResourceId)= _
      AvailabilityIndicators(eventDetails.ResourceId)-1
End Sub

Sub OnMaintenanceStartEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'write availability status of reported-on resource
   DowntimeStatuses(eventDetails.ResourceId)= _
      DowntimeStatuses(eventDetails.ResourceId)+1
End Sub

Sub OnMaintenanceEndEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'write availability status of reported-on resource
   DowntimeStatuses(eventDetails.ResourceId)= _
      DowntimeStatuses(eventDetails.ResourceId)-1
End Sub

Sub OnPeriodEnd(time,isComplete)
   UpdateCounters time
End Sub

Function Result
   If ExpectedAvailabilityTime <> 0 Then
      Result = 100 * (ActualAvailabilityTime / ExpectedAvailabilityTime)
   Else
      Result = Null
   End If
End Function

Sub UpdateCounters(time)
   If Context.IsWithinTimeslot And Not AllComponentsAreInPlannedDowntime Then
      'update counter of seconds in period (when availability is expected)
      ExpectedAvailabilityTime = ExpectedAvailabilityTime + DateDiff("s",LastUpdateTime,time)
      If SystemIsAvailable Then
         'update seconds-of-availability counter
         ActualAvailabilityTime = ActualAvailabilityTime + DateDiff("s",LastUpdateTime,time)
      End If
   End If
   LastUpdateTime=time
End Sub

Sub UpdateMonitoredComponents(allocatedComponents)
   Dim Component
   'add to monitored Components map all new Components to be monitored
   For Each Component In allocatedComponents
      If Not MonitoredComponents.Exist(Component) Then
         MonitoredComponents(Component) = Component
         AvailabilityIndicators(Component) = 0
         DowntimeStatuses(Component) = 0
      End If
   Next

   'Aus der Zuordnungsgrafik für überwachte Komponenten alle nicht länger zugehörigen Komponenten entfernen
   For Each Component In MonitoredComponents
      If Not allocatedComponents.Exist(Component) Then
         MonitoredComponents.Erase Component
         AvailabilityIndicators.Erase Component
         DowntimeStatuses.Erase Component
      End If
   Next
End Sub

Function SystemIsAvailable
   Dim SystemAvailability
   SystemAvailability = True

   Dim Component
   Dim ComponentAvailability
   For Each Component In MonitoredComponents
      ComponentAvailability = AvailabilityIndicators(Component) = 0 _
         Or DowntimeStatuses(Component) > 0
      'system availability is evaluated with availability
      SystemAvailability = SystemAvailability And ComponentAvailability
   Next
   SystemIsAvailable = SystemAvailability
End Function

Function AllComponentsAreInPlannedDowntime
   Dim ComponentsInPlannedDowntime
   ComponentsInPlannedDowntime = 0
   Dim Component
   For Each Component In MonitoredComponents
      If DowntimeStatuses(Component) > 0 Then
         ComponentsInPlannedDowntime = ComponentsInPlannedDowntime + 1
      End If
   Next

   If ComponentsInPlannedDowntime = MonitoredComponents.Count Then
      AllComponentsAreInPlannedDowntime = True
   Else
      AllComponentsAreInPlannedDowntime = False
   End If
End Function