Merge pull request #5732 from Icinga/fix/flapping

Fix flapping calculation and events

fixes #5720
This commit is contained in:
Jean Flach 2017-11-08 15:10:55 +01:00 committed by GitHub
commit f4a1747e14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 40 additions and 23 deletions

View File

@ -1306,15 +1306,18 @@ Example for all downtime events:
#### <a id="icinga2-api-event-streams-type-flapping"></a> Event Stream Type: Flapping #### <a id="icinga2-api-event-streams-type-flapping"></a> Event Stream Type: Flapping
Name | Type | Description Name | Type | Description
--------------|---------------|-------------------------- ------------------|---------------|--------------------------
type | String | Event type `Flapping`. type | String | Event type `Flapping`.
timestamp | Timestamp | Unix timestamp when the event happened. timestamp | Timestamp | Unix timestamp when the event happened.
host | String | [Host](09-object-types.md#objecttype-host) name. host | String | [Host](09-object-types.md#objecttype-host) name.
service | String | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host flapping event. service | String | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host flapping event.
state | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state. state | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
state\_type | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type. state\_type | Number | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
is\_flapping | Boolean | Whether this object is flapping. is\_flapping | Boolean | Whether this object is flapping.
current\_flapping | Number | Current flapping value in percent (added in 2.8).
threshold\_low | Number | Low threshold in percent (added in 2.8).
threshold\_high | Number | High threshold in percent (added in 2.8).
#### <a id="icinga2-api-event-streams-type-acknowledgementset"></a> Event Stream Type: AcknowledgementSet #### <a id="icinga2-api-event-streams-type-acknowledgementset"></a> Event Stream Type: AcknowledgementSet

View File

@ -170,6 +170,9 @@ void ApiEvents::FlappingChangedHandler(const Checkable::Ptr& checkable, const Me
result->Set("state", service ? static_cast<int>(service->GetState()) : static_cast<int>(host->GetState())); result->Set("state", service ? static_cast<int>(service->GetState()) : static_cast<int>(host->GetState()));
result->Set("state_type", checkable->GetStateType()); result->Set("state_type", checkable->GetStateType());
result->Set("is_flapping", checkable->IsFlapping()); result->Set("is_flapping", checkable->IsFlapping());
result->Set("flapping_current", checkable->GetFlappingCurrent());
result->Set("threshold_low", checkable->GetFlappingThresholdLow());
result->Set("threshold_high", checkable->GetFlappingThresholdHigh());
for (const EventQueue::Ptr& queue : queues) { for (const EventQueue::Ptr& queue : queues) {
queue->ProcessEvent(result); queue->ProcessEvent(result);

View File

@ -332,12 +332,15 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
olock.Unlock(); olock.Unlock();
// Log(LogDebug, "Checkable") #ifdef I2_DEBUG /* I2_DEBUG */
// << "Flapping: Checkable " << GetName() Log(LogDebug, "Checkable")
// << " was: " << (was_flapping) << "Flapping: Checkable " << GetName()
// << " is: " << is_flapping) << " was: " << was_flapping
// << " threshold: " << GetFlappingThreshold() << " is: " << is_flapping
// << "% current: " + GetFlappingCurrent()) << "%."; << " threshold low: " << GetFlappingThresholdLow()
<< " threshold high: " << GetFlappingThresholdHigh()
<< "% current: " << GetFlappingCurrent() << "%.";
#endif /* I2_DEBUG */
OnNewCheckResult(this, cr, origin); OnNewCheckResult(this, cr, origin);
@ -371,7 +374,8 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
OnNotificationsRequested(this, NotificationFlappingStart, cr, "", "", MessageOrigin::Ptr()); OnNotificationsRequested(this, NotificationFlappingStart, cr, "", "", MessageOrigin::Ptr());
Log(LogNotice, "Checkable") Log(LogNotice, "Checkable")
<< "Flapping: Checkable '" << GetName() << "' started flapping (Current flapping value " << GetFlappingCurrent() << "% > threshold " << GetFlappingThresholdHigh() << "%)."; << "Flapping Start: Checkable '" << GetName() << "' started flapping (Current flapping value "
<< GetFlappingCurrent() << "% > high threshold " << GetFlappingThresholdHigh() << "%).";
NotifyFlapping(origin); NotifyFlapping(origin);
} else if (!in_downtime && was_flapping && !is_flapping) { } else if (!in_downtime && was_flapping && !is_flapping) {
@ -380,7 +384,8 @@ void Checkable::ProcessCheckResult(const CheckResult::Ptr& cr, const MessageOrig
OnNotificationsRequested(this, NotificationFlappingEnd, cr, "", "", MessageOrigin::Ptr()); OnNotificationsRequested(this, NotificationFlappingEnd, cr, "", "", MessageOrigin::Ptr());
Log(LogNotice, "Checkable") Log(LogNotice, "Checkable")
<< "Flapping: Checkable '" << GetName() << "' stopped flapping (Current flapping value " << GetFlappingCurrent() << "% < threshold " << GetFlappingThresholdLow() << "%)."; << "Flapping Stop: Checkable '" << GetName() << "' stopped flapping (Current flapping value "
<< GetFlappingCurrent() << "% < low threshold " << GetFlappingThresholdLow() << "%).";
NotifyFlapping(origin); NotifyFlapping(origin);
} }

View File

@ -27,13 +27,14 @@ using namespace icinga;
void Checkable::UpdateFlappingStatus(bool stateChange) void Checkable::UpdateFlappingStatus(bool stateChange)
{ {
std::bitset<20> stateChangeBuf = GetFlappingBuffer(); std::bitset<20> stateChangeBuf = GetFlappingBuffer();
int oldestIndex = (GetFlappingBuffer() & 0xFF00000) >> 20; int oldestIndex = GetFlappingIndex();
stateChangeBuf[oldestIndex] = stateChange; stateChangeBuf[oldestIndex] = stateChange;
oldestIndex = (oldestIndex + 1) % 20; oldestIndex = (oldestIndex + 1) % 20;
double stateChanges = 0; double stateChanges = 0;
/* Iterate over our state array and compute a weighted total */
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
if (stateChangeBuf[(oldestIndex + i) % 20]) if (stateChangeBuf[(oldestIndex + i) % 20])
stateChanges += 0.8 + (0.02 * i); stateChanges += 0.8 + (0.02 * i);
@ -48,12 +49,13 @@ void Checkable::UpdateFlappingStatus(bool stateChange)
else else
flapping = flappingValue > GetFlappingThresholdHigh(); flapping = flappingValue > GetFlappingThresholdHigh();
SetFlappingBuffer(stateChangeBuf.to_ulong());
SetFlappingIndex(oldestIndex);
SetFlappingCurrent(flappingValue);
SetFlapping(flapping, true);
if (flapping != GetFlapping()) if (flapping != GetFlapping())
SetFlappingLastChange(Utility::GetTime()); SetFlappingLastChange(Utility::GetTime());
SetFlappingBuffer((stateChangeBuf.to_ulong() | (oldestIndex << 20)));
SetFlappingCurrent(flappingValue);
SetFlapping(flapping);
} }
bool Checkable::IsFlapping(void) const bool Checkable::IsFlapping(void) const

View File

@ -181,7 +181,6 @@ public:
/* Flapping Detection */ /* Flapping Detection */
bool IsFlapping(void) const; bool IsFlapping(void) const;
void UpdateFlappingStatus(bool stateChange);
/* Dependencies */ /* Dependencies */
void AddDependency(const intrusive_ptr<Dependency>& dep); void AddDependency(const intrusive_ptr<Dependency>& dep);
@ -237,6 +236,9 @@ private:
std::set<intrusive_ptr<Dependency> > m_ReverseDependencies; std::set<intrusive_ptr<Dependency> > m_ReverseDependencies;
void GetAllChildrenInternal(std::set<Checkable::Ptr>& children, int level = 0) const; void GetAllChildrenInternal(std::set<Checkable::Ptr>& children, int level = 0) const;
/* Flapping */
void UpdateFlappingStatus(bool stateChange);
}; };
} }

View File

@ -158,7 +158,9 @@ abstract class Checkable : CustomVarObject
default {{{ return 0; }}} default {{{ return 0; }}}
}; };
[state] Timestamp flapping_last_change; [state] Timestamp flapping_last_change;
[state, no_user_view, no_user_modify] int flapping_buffer; [state, no_user_view, no_user_modify] int flapping_buffer;
[state, no_user_view, no_user_modify] int flapping_index;
[state, protected] bool flapping; [state, protected] bool flapping;
[config, navigation] name(Endpoint) command_endpoint (CommandEndpointRaw) { [config, navigation] name(Endpoint) command_endpoint (CommandEndpointRaw) {