Fix host recovery notifications for warning states

fixes  #10225
This commit is contained in:
Michael Friedrich 2016-03-10 14:32:57 +01:00
parent 68449c2891
commit 5b6a6f86b1
2 changed files with 42 additions and 20 deletions

View File

@ -95,6 +95,16 @@ double Checkable::GetLastCheck(void) const
return schedule_end; return schedule_end;
} }
bool Checkable::StateIsOK(CheckableType type, ServiceState state)
{
if (type == CheckableHost && Host::CalculateState(state) == HostUp)
return true;
else if (type == CheckableService && state == ServiceOK)
return true;
return false;
}
void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin) void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin)
{ {
{ {
@ -150,6 +160,7 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
long old_attempt = GetCheckAttempt(); long old_attempt = GetCheckAttempt();
bool recovery = false; bool recovery = false;
/* Ignore check results older than the current one. */
if (old_cr && cr->GetExecutionStart() < old_cr->GetExecutionStart()) if (old_cr && cr->GetExecutionStart() < old_cr->GetExecutionStart())
return; return;
@ -159,19 +170,27 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
SetLastStateType(old_stateType); SetLastStateType(old_stateType);
SetLastReachable(reachable); SetLastReachable(reachable);
Host::Ptr host;
Service::Ptr service;
tie(host, service) = GetHostService(this);
CheckableType checkableType = CheckableHost;
if (service)
checkableType = CheckableService;
long attempt = 1; long attempt = 1;
std::set<Checkable::Ptr> children = GetChildren(); std::set<Checkable::Ptr> children = GetChildren();
if (!old_cr) { if (!old_cr) {
SetStateType(StateTypeHard); SetStateType(StateTypeHard);
} else if (cr->GetState() == ServiceOK) { } else if (StateIsOK(checkableType, cr->GetState())) {
if (old_state == ServiceOK && old_stateType == StateTypeSoft) { if (StateIsOK(checkableType, old_state) && old_stateType == StateTypeSoft) {
SetStateType(StateTypeHard); // SOFT OK -> HARD OK SetStateType(StateTypeHard); // SOFT OK -> HARD OK
recovery = true; recovery = true;
} }
if (old_state != ServiceOK) if (!StateIsOK(checkableType, old_state))
recovery = true; // NOT OK -> SOFT/HARD OK recovery = true; // NOT OK -> SOFT/HARD OK
ResetNotificationNumbers(); ResetNotificationNumbers();
@ -183,17 +202,17 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
} else { } else {
if (old_attempt >= GetMaxCheckAttempts()) { if (old_attempt >= GetMaxCheckAttempts()) {
SetStateType(StateTypeHard); SetStateType(StateTypeHard);
} else if (old_stateType == StateTypeSoft && old_state != ServiceOK) { } else if (old_stateType == StateTypeSoft && !StateIsOK(checkableType, old_state)) {
SetStateType(StateTypeSoft); SetStateType(StateTypeSoft);
attempt = old_attempt + 1; //NOT-OK -> NOT-OK counter attempt = old_attempt + 1; //NOT-OK -> NOT-OK counter
} else if (old_state == ServiceOK) { } else if (StateIsOK(checkableType, old_state)) {
SetStateType(StateTypeSoft); SetStateType(StateTypeSoft);
attempt = 1; //OK -> NOT-OK transition, reset the counter attempt = 1; //OK -> NOT-OK transition, reset the counter
} else { } else {
attempt = old_attempt; attempt = old_attempt;
} }
if (cr->GetState() != ServiceOK) { if (!StateIsOK(checkableType, cr->GetState())) {
SaveLastState(cr->GetState(), Utility::GetTime()); SaveLastState(cr->GetState(), Utility::GetTime());
} }
@ -210,13 +229,20 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
ServiceState new_state = cr->GetState(); ServiceState new_state = cr->GetState();
SetStateRaw(new_state); SetStateRaw(new_state);
bool stateChange = (old_state != new_state); bool stateChange;
/* Exception on state change calculation for hosts. */
if (checkableType == CheckableService)
stateChange = (old_state != new_state);
else
stateChange = (Host::CalculateState(old_state) != Host::CalculateState(new_state));
if (stateChange) { if (stateChange) {
SetLastStateChange(now); SetLastStateChange(now);
/* remove acknowledgements */ /* remove acknowledgements */
if (GetAcknowledgement() == AcknowledgementNormal || if (GetAcknowledgement() == AcknowledgementNormal ||
(GetAcknowledgement() == AcknowledgementSticky && new_state == ServiceOK)) { (GetAcknowledgement() == AcknowledgementSticky && StateIsOK(checkableType, new_state))) {
ClearAcknowledgement(); ClearAcknowledgement();
} }
@ -247,19 +273,11 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
SetLastHardStateChange(now); SetLastHardStateChange(now);
} }
if (new_state != ServiceOK) if (!StateIsOK(checkableType, new_state))
TriggerDowntimes(); TriggerDowntimes();
Host::Ptr host;
Service::Ptr service;
tie(host, service) = GetHostService(this);
CheckableType checkable_type = CheckableHost;
if (service)
checkable_type = CheckableService;
/* statistics for external tools */ /* statistics for external tools */
Checkable::UpdateStatistics(cr, checkable_type); Checkable::UpdateStatistics(cr, checkableType);
bool in_downtime = IsInDowntime(); bool in_downtime = IsInDowntime();
bool send_notification = hardChange && notification_reachable && !in_downtime && !IsAcknowledged(); bool send_notification = hardChange && notification_reachable && !in_downtime && !IsAcknowledged();
@ -267,10 +285,10 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
if (!old_cr) if (!old_cr)
send_notification = false; /* Don't send notifications for the initial state change */ send_notification = false; /* Don't send notifications for the initial state change */
if (old_state == ServiceOK && old_stateType == StateTypeSoft) if (StateIsOK(checkableType, old_state) && old_stateType == StateTypeSoft)
send_notification = false; /* Don't send notifications for SOFT-OK -> HARD-OK. */ send_notification = false; /* Don't send notifications for SOFT-OK -> HARD-OK. */
if (is_volatile && old_state == ServiceOK && new_state == ServiceOK) if (is_volatile && StateIsOK(checkableType, old_state) && StateIsOK(checkableType, new_state))
send_notification = false; /* Don't send notifications for volatile OK -> OK changes. */ send_notification = false; /* Don't send notifications for volatile OK -> OK changes. */
bool send_downtime_notification = (GetLastInDowntime() != in_downtime); bool send_downtime_notification = (GetLastInDowntime() != in_downtime);
@ -298,8 +316,10 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
bool was_flapping, is_flapping; bool was_flapping, is_flapping;
was_flapping = IsFlapping(); was_flapping = IsFlapping();
if (GetStateType() == StateTypeHard) if (GetStateType() == StateTypeHard)
UpdateFlappingStatus(stateChange); UpdateFlappingStatus(stateChange);
is_flapping = IsFlapping(); is_flapping = IsFlapping();
olock.Unlock(); olock.Unlock();

View File

@ -92,6 +92,8 @@ public:
void UpdateNextCheck(void); void UpdateNextCheck(void);
bool HasBeenChecked(void) const; bool HasBeenChecked(void) const;
bool StateIsOK(CheckableType type, ServiceState state);
virtual double GetLastCheck(void) const override; virtual double GetLastCheck(void) const override;
virtual void SaveLastState(ServiceState state, double timestamp) = 0; virtual void SaveLastState(ServiceState state, double timestamp) = 0;