Set downtime trigger time deterministically

When triggering a downtime, the time of the causing event is now passed on as
the trigger time. That time is:

* For fixed downtimes: the later one of start and entry time.
* If a check result triggers the downtime: The execution end of the check
  result.
* If another downtime triggers the downtime: The trigger time of the first
  downtime.

This is done so two nodes in a HA setup can write consistent Icinga DB downtime
history streams.

refs #9101
This commit is contained in:
Julian Brost 2021-12-08 11:49:42 +01:00
parent 577cf94b59
commit c71029f2e8
5 changed files with 14 additions and 12 deletions

View File

@ -327,7 +327,7 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
}
if (!IsStateOK(new_state))
TriggerDowntimes();
TriggerDowntimes(cr->GetExecutionEnd());
/* statistics for external tools */
Checkable::UpdateStatistics(cr, checkableType);

View File

@ -16,10 +16,10 @@ void Checkable::RemoveAllDowntimes()
}
}
void Checkable::TriggerDowntimes()
void Checkable::TriggerDowntimes(double triggerTime)
{
for (const Downtime::Ptr& downtime : GetDowntimes()) {
downtime->TriggerDowntime();
downtime->TriggerDowntime(triggerTime);
}
}

View File

@ -139,7 +139,7 @@ public:
int GetDowntimeDepth() const final;
void RemoveAllDowntimes();
void TriggerDowntimes();
void TriggerDowntimes(double triggerTime);
bool IsInDowntime() const;
bool IsAcknowledged() const;

View File

@ -9,6 +9,7 @@
#include "base/utility.hpp"
#include "base/timer.hpp"
#include <boost/thread/once.hpp>
#include <cmath>
using namespace icinga;
@ -130,7 +131,7 @@ void Downtime::Start(bool runtimeCreated)
Log(LogNotice, "Downtime")
<< "Checkable '" << checkable->GetName() << "' already in a NOT-OK state."
<< " Triggering downtime now.";
TriggerDowntime();
TriggerDowntime(checkable->GetLastStateChange());
}
if (GetFixed() && CanBeTriggered()) {
@ -138,7 +139,7 @@ void Downtime::Start(bool runtimeCreated)
OnDowntimeStarted(this);
/* Trigger fixed downtime immediately. */
TriggerDowntime();
TriggerDowntime(std::fmax(GetStartTime(), GetEntryTime()));
}
}
@ -422,7 +423,7 @@ bool Downtime::CanBeTriggered()
return true;
}
void Downtime::TriggerDowntime()
void Downtime::TriggerDowntime(double triggerTime)
{
if (!CanBeTriggered())
return;
@ -432,8 +433,9 @@ void Downtime::TriggerDowntime()
Log(LogInformation, "Downtime")
<< "Triggering downtime '" << GetName() << "' for checkable '" << checkable->GetName() << "'.";
if (GetTriggerTime() == 0)
SetTriggerTime(Utility::GetTime());
if (GetTriggerTime() == 0) {
SetTriggerTime(triggerTime);
}
Array::Ptr triggers = GetTriggers();
@ -445,7 +447,7 @@ void Downtime::TriggerDowntime()
if (!downtime)
continue;
downtime->TriggerDowntime();
downtime->TriggerDowntime(triggerTime);
}
}
@ -475,7 +477,7 @@ void Downtime::DowntimesStartTimerHandler()
OnDowntimeStarted(downtime);
/* Trigger fixed downtime immediately. */
downtime->TriggerDowntime();
downtime->TriggerDowntime(std::fmax(downtime->GetStartTime(), downtime->GetEntryTime()));
}
}
}

View File

@ -57,7 +57,7 @@ public:
void UnregisterChild(const Downtime::Ptr& downtime);
std::set<Downtime::Ptr> GetChildren() const;
void TriggerDowntime();
void TriggerDowntime(double triggerTime);
static String GetDowntimeIDFromLegacyID(int id);